diff options
author | spreis <spreis@yandex-team.com> | 2024-03-29 14:18:43 +0300 |
---|---|---|
committer | spreis <spreis@yandex-team.com> | 2024-03-29 14:31:49 +0300 |
commit | f39261a434c46274b5eaef0927ee3b2e0d95b41a (patch) | |
tree | e64c68742b1a7423d8b2809a5ca938f5ddbed2e2 /contrib | |
parent | 9334caaba1f032fa294d74e7a74157e3fb263a3e (diff) | |
download | ydb-f39261a434c46274b5eaef0927ee3b2e0d95b41a.tar.gz |
Re-enable separation of protobufs for Python 2 and Python 3
Это откат коммита https://a.yandex-team.ru/arcadia/commit/rXXXXXX
И соответственно возврат коммитов https://a.yandex-team.ru/arcadia/commit/rXXXXXX и https://a.yandex-team.ru/arcadia/commit/rXXXXXX
Починка причины отката влилась здесь: https://a.yandex-team.ru/arcadia/commit/rXXXXXX
ae529e54d3ef7992b0e9f152373bc300061c1293
Diffstat (limited to 'contrib')
225 files changed, 139981 insertions, 37 deletions
diff --git a/contrib/libs/protobuf_old/CHANGES.txt b/contrib/libs/protobuf_old/CHANGES.txt new file mode 100644 index 0000000000..db6194529d --- /dev/null +++ b/contrib/libs/protobuf_old/CHANGES.txt @@ -0,0 +1,3044 @@ +2021-10-15 version 3.19.0 (C++/Java/Python/PHP/Objective-C/C#/Ruby/JavaScript) + + C++ + * Make proto2::Message::DiscardUnknownFields() non-virtual + * Separate RepeatedPtrField into its own header file + * For default floating point values of 0, consider all bits significant + * cmake: support `MSVC_RUNTIME_LIBRARY` property (#8851) + * Fix shadowing warnings (#8926) + * Fix for issue #8484, constant initialization doesn't compile in msvc clang-cl environment (#8993) + * Fix build on AIX and SunOS (#8373) (#9065) + * Add Android stlport and default toolchains to BUILD. (#8290) + + Java + * For default floating point values of 0, consider all bits significant + * Annotate `//java/com/google/protobuf/util/...` with nullness annotations + * Use ArrayList copy constructor (#7853) + + Kotlin + * Switch Kotlin proto DSLs to be implemented with inline value classes + + Python + * Proto2 DecodeError now includes message name in error message + * Make MessageToDict convert map keys to strings (#8122) + * Add python-requires in setup.py (#8989) + * Add python 3.10 (#9034) + + JavaScript + * Skip exports if not available by CommonJS (#8856) + * JS: Comply with CSP no-unsafe-eval. (#8864) + + PHP + * Added "object" as a reserved name for PHP (#8962) + + Ruby + * Override Map.clone to use Map's dup method (#7938) + * Ruby: build extensions for arm64-darwin (#8232) + * Add class method Timestamp.from_time to ruby well known types (#8562) + * Adopt pure ruby DSL implementation for JRuby (#9047) + * Add size to Map class (#8068) + + C# + * Correctly set ExtensionRegistry when parsing with MessageParser, but using an already existing CodedInputStream (#7246) + * [C#] Make FieldDescriptor propertyName public (#7642) + +2021-10-04 version 3.18.1 (C++/Java/Python/PHP/Objective-C/C#/Ruby/JavaScript) + + Python + * Update setup.py to reflect that we now require at least Python 3.5 (#8989) + * Performance fix for DynamicMessage: force GetRaw() to be inlined (#9023) + + Ruby + * Update ruby_generator.cc to allow proto2 imports in proto3 (#9003) + +2021-09-13 version 3.18.0 (C++/Java/Python/PHP/Objective-C/C#/Ruby/JavaScript) + + Python + * Removed Python 2.x support. + * Pure python descriptor_pool.AddSerializedFile() will always build the + file and return FileDescriptor which is same with python c++ extension + * type errors thrown by MergeFrom now report fully qualified class names + * Protobuf python generated code are simplified. Some platforms that uses + "is"("is not") to compare the enum or descriptor's label/type may fail, + should use "=="("!=") instead. + + C++ + * Generated code now uses the c++11 standard integer types int{32,64}_t and + uint{32,64}_t + * Reduce memory usage of the DescriptorPool type. + * Moved the zero-argument New() method on messages to the base class (internal + optimization). + * Unused return values marked with `PROTOBUF_MUST_USE_RESULT` are now + correctly attributed. + * Demotes PrintPath log for maps in MessageDifferencer down from WARNING to + INFO. + * Make sure FullMessageName() is always private. + * Fix race condition in EnumDescriptor. + * Remove MessageLite::GetMaybeArenaPointer. + + Java + * Add @deprecated javadoc for set/get/has methods + * correctly decode \? escape sequence in text protos + * Avoid depending on Objects.requireNonNull() until we can verify that no + users are depending on older Android versions. + * disallow null string map values in put and putAll + * Add `@CheckReturnValue` to `ByteString` API. + * Make the `hasPresence` method public in `FieldDescriptor`. + * Report more detailed messages in Duration and Timestamp proto parsing + errors. + * New Timestamps.fromDate utility method that converts a java.util.Date to a + Timestamp proto object. + + Kotlin + * Generated Kotlin code is Explicit API mode compatible + +2021-09-13 version 3.18.0 (C++/Java/Python/PHP/Objective-C/C#/Ruby/JavaScript) + C++ + * Fix warnings raised by clang 11 (#8664) + * Make StringPiece constructible from std::string_view (#8707) + * Add missing capability attributes for LLVM 12 (#8714) + * Stop using std::iterator (deprecated in C++17). (#8741) + * Move field_access_listener from libprotobuf-lite to libprotobuf (#8775) + * Fix #7047 Safely handle setlocale (#8735) + * Remove deprecated version of SetTotalBytesLimit() (#8794) + * Support arena allocation of google::protobuf::AnyMetadata (#8758) + * Fix undefined symbol error around SharedCtor() (#8827) + * Fix default value of enum(int) in json_util with proto2 (#8835) + * Better Smaller ByteSizeLong + * Introduce event filters for inject_field_listener_events + * Reduce memory usage of DescriptorPool + * For lazy fields copy serialized form when allowed. + * Re-introduce the InlinedStringField class + * v2 access listener + * Reduce padding in the proto's ExtensionRegistry map. + * GetExtension performance optimizations + * Make tracker a static variable rather than call static functions + * Support extensions in field access listener + * Annotate MergeFrom for field access listener + * Fix incomplete types for field access listener + * Add map_entry/new_map_entry to SpecificField in MessageDifferencer. They + record the map items which are different in MessageDifferencer's reporter. + * Reduce binary size due to fieldless proto messages + * TextFormat: ParseInfoTree supports getting field end location in addition to + start. + * Fix repeated enum extension size in field listener + * Enable Any Text Expansion for Descriptors::DebugString() + * Switch from int{8,16,32,64} to int{8,16,32,64}_t + * Reduce memory usage of the DescriptorPool type. + + Java + * Fix errorprone conflict (#8723) + * Removing deprecated TimeUtil class. (#8749) + * Optimized FieldDescriptor.valueOf() to avoid array copying. + * Removing deprecated TimeUtil class. + * Add Durations.parseUnchecked(String) and Timestamps.parseUnchecked(String) + * FieldMaskUtil: Add convenience method to mask the fields out of a given proto. + + JavaScript + * Optimize binary parsing of repeated float64 + * Fix for optimization when reading doubles from binary wire format + * Replace toArray implementation with toJSON. + + Python + * Drops support for 2.7 and 3.5. + + PHP + * Migrate PHP & Ruby to ABSL wyhash (#8854) + * Added support for PHP 8.1 (currently in RC1) to the C extension (#8964) + * Fixed PHP SEGV when constructing messages from a destructor. (#8969) + + Ruby + * Move DSL implementation from C to pure Ruby (#8850) + * Fixed a memory bug with RepeatedField#+. (#8970) + + Other + * [csharp] ByteString.CreateCodedInput should use ArraySegment offset and count (#8740) + * [ObjC] Add support for using the proto package to prefix symbols. (#8760) + * field_presence.md: fix Go example (#8788) + + + Kotlin + * Suppress NOTHING_TO_INLINE in Kotlin generated inline functions. + +2021-06-04 version 3.17.3 (C++/Java/Python/PHP/Objective-C/C#/Ruby/JavaScript) + Python + * Note: This is the last release to support Python 2.7. Future releases will + require Python >= 3.5. + + C++ + * Introduce FieldAccessListener. + * Stop emitting boilerplate {Copy/Merge}From in each ProtoBuf class + * Fixed some uninitialized variable warnings in generated_message_reflection.cc. + + Kotlin + * Fix duplicate proto files error (#8699) + + Java + * Fixed parser to check that we are at a proper limit when a sub-message has + finished parsing. + +2021-05-25 version 3.17.2 (C++/Java/Python/PHP/Objective-C/C#/Ruby/JavaScript) + Kotlin + * Fix duplicate class error (#8653) + + PHP + * Fixed SEGV in sub-message getters for well-known types when message is unset + (#8670) + +2021-05-07 version 3.17.1 (C++/Java/Python/PHP/Objective-C/C#/Ruby/JavaScript) + PHP + * Fixed PHP memory leaks and arginfo errors. (#8614) + * Fixed JSON parser to allow multiple values from the same oneof as long as + all but one are null. + + Ruby + * Fixed memory bug: properly root repeated/map field when assigning. (#8639) + * Fixed JSON parser to allow multiple values from the same oneof as long as + all but one are null. + + +2021-05-07 version 3.17.0 (C++/Java/Python/PHP/Objective-C/C#/Ruby/JavaScript) + + Protocol Compiler + * Fix the generated source information for reserved values in Enums. + + C++ + * Fix -Wunused-parameter in map<string, int> fields (fixes #8494) (#8500) + * Use byteswap.h when building against musl libc (#8503) + * Fix -Wundefined-inline error when using SharedCtor() or SharedDtor() (#8532) + * Fix bug where `Descriptor::DebugString()` printed proto3 synthetic oneofs. + * Provide stable versions of `SortAndUnique()`. + * Make sure to cache proto3 optional message fields when they are cleared. + * Expose UnsafeArena methods to Reflection. + * Use std::string::empty() rather than std::string::size() > 0. + + Kotlin + * Restrict extension setter and getter operators to non-nullable T. + + Java + * updating GSON and Guava to more recent versions (#8524) + * Reduce the time spent evaluating isExtensionNumber by storing the extension + ranges in a TreeMap for faster queries. This is particularly relevant for + protos which define a large number of extension ranges, for example when + each tag is defined as an extension. + * Fix java bytecode estimation logic for optional fields. + * Optimize Descriptor.isExtensionNumber. + + Python + * Add MethodDescriptor.CopyToProto() (#8327) + * Remove unused python_protobuf.{cc,h} (#8513) + * Start publishing python aarch64 manylinux wheels normally (#8530) + * Fix constness issue detected by MSVC standard conforming mode (#8568) + * Make JSON parsing match C++ and Java when multiple fields from the same + oneof are present and all but one is null. + + Ruby + * Add support for proto3 json_name in compiler and field definitions (#8356) + * Fixed memory leak of Ruby arena objects. (#8461) + * Fix source gem compilation (#8471) + * Fix various exceptions in Ruby on 64-bit Windows (#8563) + * Fix crash when calculating Message hash values on 64-bit Windows (#8565) + + Conformance Tests + * Added a conformance test for the case of multiple fields from the same + oneof. + +2021-04-06 version 3.16.0 (C++/Java/Python/PHP/Objective-C/C#/Ruby/JavaScript) + Other + * Opensourcing kotlin protos (#8272) + * Use a newer version of rules_proto, with the new rule `proto_descriptor_set` (#8469) + + C++ + * Fix compiler warnings issue found in conformance_test_runner #8189 (#8190) + * Fix MinGW-w64 build issues. (#8286) + * [Protoc] C++ Resolved an issue where NO_DESTROY and CONSTINIT are in incorrect order (#8296) + * Fix PROTOBUF_CONSTINIT macro redefinition (#8323) + * Delete StringPiecePod (#8353) + * Fix gcc error: comparison of unsigned expression in '>= 0' is always … (#8309) + * Fix cmake install on iOS (#8301) + * Create a CMake option to control whether or not RTTI is enabled (#8347) + * Fix endian.h location on FreeBSD (#8351) + * Refactor util::Status (#8354) + * Make util::Status more similar to absl::Status (#8405) + * Fix -Wsuggest-destructor-override for generated C++ proto classes. (#8408) + * Refactor StatusOr and StringPiece (#8406) + * Refactor uint128 (#8416) + * The ::pb namespace is no longer exposed due to conflicts. + * Allow MessageDifferencer::TreatAsSet() (and friends) to override previous + calls instead of crashing. + * Reduce the size of generated proto headers for protos with `string` or + `bytes` fields. + * Move arena() operation on uncommon path to out-of-line routine + * For iterator-pair function parameter types, take both iterators by value. + * Code-space savings and perhaps some modest performance improvements in + RepeatedPtrField. + * Eliminate nullptr check from every tag parse. + * Remove unused _$name$_cached_byte_size_ fields. + * Serialize extension ranges together when not broken by a proto field in the + middle. + * Do out-of-line allocation and deallocation of string object in ArenaString. + * Streamline ParseContext::ParseMessage<T> to avoid code bloat and improve + performance. + * New member functions RepeatedField::Assign, RepeatedPtrField::{Add, Assign}. + * Fix undefined behavior warning due to innocuous uninitialization of value + on an error path. + * Avoid expensive inlined code space for encoding message length for messages + >= 128 bytes and instead do a procedure call to a shared out-of-line routine. + * util::DefaultFieldComparator will be final in a future version of protobuf. + Subclasses should inherit from SimpleFieldComparator instead. + + C# + * Add .NET 5 target and improve WriteString performance with SIMD (#8147) + + Java + * deps: update JUnit and Truth (#8319) + * Detect invalid overflow of byteLimit and return InvalidProtocolBufferException as documented. + * Exceptions thrown while reading from an InputStream in parseFrom are now + included as causes. + * Support potentially more efficient proto parsing from RopeByteStrings. + * Clarify runtime of ByteString.Output.toStringBuffer(). + * Added UnsafeByteOperations to protobuf-lite (#8426) + + JavaScript + * Make Any.pack() chainable. + + Python + * Fix some constness / char literal issues being found by MSVC standard conforming mode (#8344) + * Switch on "new" buffer API (#8339) + * Enable crosscompiling aarch64 python wheels under dockcross manylinux docker image (#8280) + * Fixed a bug in text format where a trailing colon was printed for repeated field. + * When TextFormat encounters a duplicate message map key, replace the current + one instead of merging. + + Objective-C + * Move the class map to a CFDictionary. (#8328) + + PHP + * read_property() handler is not supposed to return NULL (#8362) + * Changed parameter type from long to integer (#7613) + * fix: README supported PHP version for C extension (#8236) + + Ruby + * Fixed quadratic memory usage when appending to arrays. (#8364) + * Fixed memory leak of Ruby arena objects. (#8461) + * Add support for proto3 json_name in compiler and field definitions. (#8356) + + Other + * Some doc on AOT compilation and protobuf (#8294) + * [CMake] Ability to pass options to protoc executable from cmake (#8374) + * Add --fatal_warnings flag to treat warnings as errors (#8131) + * [bazel] Remove deprecated way to depend on googletest (#8396) + * add error returns missing from protoc to prevent it from exiting with… (#8409) + + +2021-04-07 version 3.15.8 (C++/Java/Python/PHP/Objective-C/C#/Ruby/JavaScript) + + Ruby + * Fixed memory leak of Ruby arena objects (#8461) + +2021-04-02 version 3.15.7 (C++/Java/Python/PHP/Objective-C/C#/Ruby/JavaScript) + + C++ + * Remove the ::pb namespace (alias) (#8423) + + Ruby + * Fix unbounded memory growth for Ruby <2.7 (#8429) + * Fixed message equality in cases where the message type is different (#8434) + +2021-03-10 version 3.15.6 (C++/Java/Python/PHP/Objective-C/C#/Ruby/JavaScript) + + Ruby + * Fixed bug in string comparison logic (#8386) + +2021-03-04 version 3.15.5 (C++/Java/Python/PHP/Objective-C/C#/Ruby/JavaScript) + + Ruby + * Fixed quadratic memory use in array append (#8379) + + PHP + * Fixed quadratic memory use in array append (#8379) + + C++ + * Do not disable RTTI by default in the CMake build (#8377) + +2021-03-02 version 3.15.4 (C++/Java/Python/PHP/Objective-C/C#/Ruby/JavaScript) + + Ruby + * Fixed SEGV when users pass nil messages (#8363) + * Fixed quadratic memory usage when appending to arrays (#8364) + + C++ + * Create a CMake option to control whether or not RTTI is enabled (#8361) + + PHP + * read_property() handler is not supposed to return NULL (#8362) + +2021-02-25 version 3.15.3 (C++/Java/Python/PHP/Objective-C/C#/Ruby/JavaScript) + + Ruby + * Ruby <2.7 now uses WeakMap too, which prevents memory leaks. (#8341) + +2021-02-23 version 3.15.2 (C++/Java/Python/PHP/Objective-C/C#/Ruby/JavaScript) + + Ruby + * Fix for FieldDescriptor.get(msg) (#8330) + + C++ + * Fix PROTOBUF_CONSTINIT macro redefinition (#8323) + +2021-02-05 version 3.15.1 (C++/Java/Python/PHP/Objective-C/C#/Ruby/JavaScript) + + Ruby + * Bugfix for Message.[] for repeated or map fields (#8313) + +2021-02-05 version 3.15.0 (C++/Java/Python/PHP/Objective-C/C#/Ruby/JavaScript) + + Protocol Compiler + * Optional fields for proto3 are enabled by default, and no longer require + the --experimental_allow_proto3_optional flag. + + C++ + * MessageDifferencer: fixed bug when using custom ignore with multiple + unknown fields + * Use init_seg in MSVC to push initialization to an earlier phase. + * Runtime no longer triggers -Wsign-compare warnings. + * Fixed -Wtautological-constant-out-of-range-compare warning. + * DynamicCastToGenerated works for nullptr input for even if RTTI is disabled + * Arena is refactored and optimized. + * Clarified/specified that the exact value of Arena::SpaceAllocated() is an + implementation detail users must not rely on. It should not be used in + unit tests. + * Change the signature of Any::PackFrom() to return false on error. + * Add fast reflection getter API for strings. + * Constant initialize the global message instances + * Avoid potential for missed wakeup in UnknownFieldSet + * Now Proto3 Oneof fields have "has" methods for checking their presence in + C++. + * Bugfix for NVCC + * Return early in _InternalSerialize for empty maps. + * Adding functionality for outputting map key values in proto path logging + output (does not affect comparison logic) and stop printing 'value' in the + path. The modified print functionality is in the + MessageDifferencer::StreamReporter. + * Fixed https://github.com/protocolbuffers/protobuf/issues/8129 + * Ensure that null char symbol, package and file names do not result in a + crash. + * Constant initialize the global message instances + * Pretty print 'max' instead of numeric values in reserved ranges. + * Removed remaining instances of std::is_pod, which is deprecated in C++20. + * Changes to reduce code size for unknown field handling by making uncommon + cases out of line. + * Fix std::is_pod deprecated in C++20 (#7180) + * Fix some -Wunused-parameter warnings (#8053) + * Fix detecting file as directory on zOS issue #8051 (#8052) + * Don't include sys/param.h for _BYTE_ORDER (#8106) + * remove CMAKE_THREAD_LIBS_INIT from pkgconfig CFLAGS (#8154) + * Fix TextFormatMapTest.DynamicMessage issue#5136 (#8159) + * Fix for compiler warning issue#8145 (#8160) + * fix: support deprecated enums for GCC < 6 (#8164) + * Fix some warning when compiling with Visual Studio 2019 on x64 target (#8125) + + Python + * Provided an override for the reverse() method that will reverse the internal + collection directly instead of using the other methods of the BaseContainer. + * MessageFactory.CreateProtoype can be overridden to customize class creation. + * Fix PyUnknownFields memory leak (#7928) + * Add macOS Big Sur compatibility (#8126) + + JavaScript + * Generate `getDescriptor` methods with `*` as their `this` type. + * Enforce `let/const` for generated messages. + * js/binary/utils.js: Fix jspb.utils.joinUnsignedDecimalString to work with negative bitsLow and low but non-zero bitsHigh parameter. (#8170) + + PHP + * Added support for PHP 8. (#8105) + * unregister INI entries and fix invalid read on shutdown (#8042) + * Fix PhpDoc comments for message accessors to include "|null". (#8136) + * fix: convert native PHP floats to single precision (#8187) + * Fixed PHP to support field numbers >=2**28. (#8235) + * feat: add support for deprecated fields to PHP compiler (#8223) + * Protect against stack overflow if the user derives from Message. (#8248) + * Fixed clone for Message, RepeatedField, and MapField. (#8245) + * Updated upb to allow nonzero offset minutes in JSON timestamps. (#8258) + + Ruby + * Added support for Ruby 3. (#8184) + * Rewrote the data storage layer to be based on upb_msg objects from the + upb library. This should lead to much better parsing performance, + particularly for large messages. (#8184). + * Fill out JRuby support (#7923) + * [Ruby] Fix: (SIGSEGV) gRPC-Ruby issue on Windows. memory alloc infinite + recursion/run out of memory (#8195) + * Fix jruby support to handle messages nested more than 1 level deep (#8194) + + Java + * Avoid possible UnsupportedOperationException when using CodedInputSteam + with a direct ByteBuffer. + * Make Durations.comparator() and Timestamps.comparator() Serializable. + * Add more detailed error information for dynamic message field type + validation failure + * Removed declarations of functions declared in java_names.h from + java_helpers.h. + * Now Proto3 Oneof fields have "has" methods for checking their presence in + Java. + * Annotates Java proto generated *_FIELD_NUMBER constants. + * Add -assumevalues to remove JvmMemoryAccessor on Android. + + C# + * Fix parsing negative Int32Value that crosses segment boundary (#8035) + * Change ByteString to use memory and support unsafe create without copy (#7645) + * Optimize MapField serialization by removing MessageAdapter (#8143) + * Allow FileDescriptors to be parsed with extension registries (#8220) + * Optimize writing small strings (#8149) + +2020-11-11 version 3.14.0 (C++/Java/Python/PHP/Objective-C/C#/Ruby/JavaScript) + + Protocol Compiler + * The proto compiler no longer requires a .proto filename when it is not + generating code. + * Added flag `--deterministic_output` to `protoc --encode=...`. + * Fixed deadlock when using google.protobuf.Any embedded in aggregate options. + + C++ + * Arenas are now unconditionally enabled. cc_enable_arenas no longer has + any effect. + * Removed inlined string support, which is incompatible with arenas. + * Fix a memory corruption bug in reflection when mixing optional and + non-optional fields. + * Make SpaceUsed() calculation more thorough for map fields. + * Add stack overflow protection for text format with unknown field values. + * FieldPath::FollowAll() now returns a bool to signal if an out-of-bounds + error was encountered. + * Performance improvements for Map. + * Minor formatting fix when dumping a descriptor to .proto format with + DebugString. + * UBSAN fix in RepeatedField (#2073). + * When running under ASAN, skip a test that makes huge allocations. + * Fixed a crash that could happen when creating more than 256 extensions in + a single message. + * Fix a crash in BuildFile when passing in invalid descriptor proto. + * Parser security fix when operating with CodedInputStream. + * Warn against the use of AllowUnknownExtension. + * Migrated to C++11 for-range loops instead of index-based loops where + possible. This fixes a lot of warnings when compiling with -Wsign-compare. + * Fix segment fault for proto3 optional (#7805) + * Adds a CMake option to build `libprotoc` separately (#7949) + + Java + * Bugfix in mergeFrom() when a oneof has multiple message fields. + * Fix RopeByteString.RopeInputStream.read() returning -1 when told to read + 0 bytes when not at EOF. + * Redefine remove(Object) on primitive repeated field Lists to avoid + autoboxing. + * Support "\u" escapes in textformat string literals. + * Trailing empty spaces are no longer ignored for FieldMask. + * Fix FieldMaskUtil.subtract to recursively remove mask. + * Mark enums with `@java.lang.Deprecated` if the proto enum has option + `deprecated = true;`. + * Adding forgotten duration.proto to the lite library (#7738) + + Python + * Print google.protobuf.NullValue as null instead of "NULL_VALUE" when it is + used outside WKT Value/Struct. + * Fix bug occurring when attempting to deep copy an enum type in python 3. + * Add a setuptools extension for generating Python protobufs (#7783) + * Remove uses of pkg_resources in non-namespace packages. (#7902) + * [bazel/py] Omit google/__init__.py from the Protobuf runtime. (#7908) + * Removed the unnecessary setuptools package dependency for Python package (#7511) + * Fix PyUnknownFields memory leak (#7928) + + PHP + * Added support for "==" to the PHP C extension (#7883) + * Added `==` operators for Map and Array. (#7900) + * Native C well-known types (#7944) + * Optimized away hex2bin() call in generated code (#8006) + * New version of upb, and a new hash function wyhash in third_party. (#8000) + * add missing hasOneof method to check presence of oneof fields (#8003) + + Go: + * Update go_package options to reference google.golang.org/protobuf module. + + C#: + * annotate ByteString.CopyFrom(ReadOnlySpan<byte>) as SecuritySafeCritical (#7701) + * Fix C# optional field reflection when there are regular fields too (#7705) + * Fix parsing negative Int32Value that crosses segment boundary (#8035) + + Javascript: + * JS: parse (un)packed fields conditionally (#7379) + +2020-07-14 version 3.13.0 (C++/Java/Python/PHP/Objective-C/C#/Ruby/JavaScript) + + PHP: + * The C extension is completely rewritten. The new C extension has significantly + better parsing performance and fixes a handful of conformance issues. It will + also make it easier to add support for more features like proto2 and proto3 presence. + * The new C extension does not support PHP 5.x. PHP 5.x users can still use pure-PHP. + + C++: + * Removed deprecated unsafe arena string accessors + * Enabled heterogeneous lookup for std::string keys in maps. + * Removed implicit conversion from StringPiece to std::string + * Fix use-after-destroy bug when the Map is allocated in the arena. + * Improved the randomness of map ordering + * Added stack overflow protection for text format with unknown fields + * Use std::hash for proto maps to help with portability. + * Added more Windows macros to proto whitelist. + * Arena constructors for map entry messages are now marked "explicit" + (for regular messages they were already explicit). + * Fix subtle aliasing bug in RepeatedField::Add + * Fix mismatch between MapEntry ByteSize and Serialize with respect to unset + fields. + + Python: + * JSON format conformance fixes: + * Reject lowercase t for Timestamp json format. + * Print full_name directly for extensions (no camelCase). + * Reject boolean values for integer fields. + * Reject NaN, Infinity, -Infinity that is not quoted. + * Base64 fixes for bytes fields: accept URL-safe base64 and missing padding. + * Bugfix for fields/files named "async" or "await". + * Improved the error message when AttributeError is returned from __getattr__ + in EnumTypeWrapper. + + Java: + * Fixed a bug where setting optional proto3 enums with setFooValue() would + not mark the value as present. + * Add Subtract function to FieldMaskUtil. + + C#: + * Dropped support for netstandard1.0 (replaced by support for netstandard1.1). + This was required to modernize the parsing stack to use the `Span<byte>` + type internally. (#7351) + * Add `ParseFrom(ReadOnlySequence<byte>)` method to enable GC friendly + parsing with reduced allocations and buffer copies. (#7351) + * Add support for serialization directly to a `IBufferWriter<byte>` or + to a `Span<byte>` to enable GC friendly serialization. + The new API is available as extension methods on the `IMessage` type. (#7576) + * Add `GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE` define to make + generated code compatible with old C# compilers (pre-roslyn compilers + from .NET framework and old versions of mono) that do not support + ref structs. Users that are still on a legacy stack that does + not support C# 7.2 compiler might need to use the new define + in their projects to be able to build the newly generated code. (#7490) + * Due to the major overhaul of parsing and serialization internals (#7351 and #7576), + it is recommended to regenerate your generated code to achieve the best + performance (the legacy generated code will still work, but might incur + a slight performance penalty). + +2020-07-28 version 3.12.4 (C++/Java/Python/PHP/Objective-C/C#/Ruby/JavaScript) + +This release contains no significant changes, but exists because 3.12.3 was +mistakenly tagged at the wrong commit. + +2020-06-01 version 3.12.3 (C++/Java/Python/PHP/Objective-C/C#/Ruby/JavaScript) + + Objective-C + * Tweak the union used for Extensions to support old generated code. #7573 + +2020-05-26 version 3.12.2 (C++/Java/Python/PHP/Objective-C/C#/Ruby/JavaScript) + + C++ + * Simplified the template export macros to fix the build for mingw32. (#7539) + + Objective-C + * Fix for the :protobuf_objc target in the Bazel BUILD file. (#7538) + +2020-05-20 version 3.12.1 (C++/Java/Python/PHP/Objective-C/C#/Ruby/JavaScript) + + Ruby + * Re-add binary gems for Ruby 2.3 and 2.4. These are EOL upstream, however + many people still use them and dropping support will require more + coordination. + +2020-05-12 version 3.12.0 (C++/Java/Python/PHP/Objective-C/C#/Ruby/JavaScript) + + Protocol Compiler + * [experimental] Singular, non-message typed fields in proto3 now support + presence tracking. This is enabled by adding the "optional" field label and + passing the --experimental_allow_proto3_optional flag to protoc. + * For usage info, see docs/field_presence.md. + * During this experimental phase, code generators should update to support + proto3 presence, see docs/implementing_proto3_presence.md for instructions. + * Allow duplicate symbol names when multiple descriptor sets are passed on + the command-line, to match the behavior when multiple .proto files are passed. + * Deterministic `protoc --descriptor_set_out` (#7175) + + C++ + * [experimental] Added proto3 presence support. + * New descriptor APIs to support proto3 presence. + * Enable Arenas by default on all .proto files. + * Documented that users are not allowed to subclass Message or MessageLite. + * Mark generated classes as final; inheriting from protos is strongly discouraged. + * Add stack overflow protection for text format with unknown fields. + * Add accessors for map key and value FieldDescriptors. + * Add FieldMaskUtil::FromFieldNumbers(). + * MessageDifferencer: use ParsePartial() on Any fields so the diff does not + fail when there are missing required fields. + * ReflectionOps::Merge(): lookup messages in the right factory, if it can. + * Added Descriptor::WellKnownTypes enum and Descriptor::well_known_type() + accessor as an easier way of determining if a message is a Well-Known Type. + * Optimized RepeatedField::Add() when it is used in a loop. + * Made proto move/swap more efficient. + * De-virtualize the GetArena() method in MessageLite. + * Improves performance of json_stream_parser.cc by factor 1000 (#7230) + * bug: #7076 undefine Windows OUT and OPTIONAL macros (#7087) + * Fixed a bug in FieldDescriptor::DebugString() that would erroneously print + an "optional" label for a field in a oneof. + * Fix bug in parsing bool extensions that assumed they are always 1 byte. + * Fix off-by-one error in FieldOptions::ByteSize() when extensions are present. + * Clarified the comments to show an example of the difference between + Descriptor::extension and DescriptorPool::FindAllExtensions. + * Add a compiler option 'code_size' to force optimize_for=code_size on all + protos where this is possible. + + Java + * [experimental] Added proto3 presence support. + * Mark java enum _VALUE constants as @Deprecated if the enum field is deprecated + * reduce <clinit> size for enums with allow_alias set to true. + * Sort map fields alphabetically by the field's key when printing textproto. + * Fixed a bug in map sorting that appeared in -rc1 and -rc2 (#7508). + * TextFormat.merge() handles Any as top level type. + * Throw a descriptive IllegalArgumentException when calling + getValueDescriptor() on enum special value UNRECOGNIZED instead of + ArrayIndexOutOfBoundsException. + * Fixed an issue with JsonFormat.printer() where setting printingEnumsAsInts() + would override the configuration passed into includingDefaultValueFields(). + * Implement overrides of indexOf() and contains() on primitive lists returned + for repeated fields to avoid autoboxing the list contents. + * Add overload to FieldMaskUtil.fromStringList that accepts a descriptor. + * [bazel] Move Java runtime/toolchains into //java (#7190) + + Python + * [experimental] Added proto3 presence support. + * [experimental] fast import protobuf module, only works with cpp generated code linked in. + * Truncate 'float' fields to 4 bytes of precision in setters for pure-Python + implementation (C++ extension was already doing this). + * Fixed a memory leak in C++ bindings. + * Added a deprecation warning when code tries to create Descriptor objects + directly. + * Fix unintended comparison between bytes and string in descriptor.py. + * Avoid printing excess digits for float fields in TextFormat. + * Remove Python 2.5 syntax compatibility from the proto compiler generated _pb2.py module code. + * Drop 3.3, 3.4 and use single version docker images for all python tests (#7396) + + JavaScript + * Fix js message pivot selection (#6813) + + PHP + * Persistent Descriptor Pool (#6899) + * Implement lazy loading of php class for proto messages (#6911) + * Correct @return in Any.unpack docblock (#7089) + * Ignore unknown enum value when ignore_unknown specified (#7455) + + Ruby + * [experimental] Implemented proto3 presence for Ruby. (#7406) + * Stop building binary gems for ruby <2.5 (#7453) + * Fix for wrappers with a zero value (#7195) + * Fix for JSON serialization of 0/empty-valued wrapper types (#7198) + * Call "Class#new" over rb_class_new_instance in decoding (#7352) + * Build extensions for Ruby 2.7 (#7027) + * assigning 'nil' to submessage should clear the field. (#7397) + + C# + * [experimental] Add support for proto3 presence fields in C# (#7382) + * Mark GetOption API as obsolete and expose the "GetOptions()" method on descriptors instead (#7491) + * Remove Has/Clear members for C# message fields in proto2 (#7429) + * Enforce recursion depth checking for unknown fields (#7132) + * Fix conformance test failures for Google.Protobuf (#6910) + * Cleanup various bits of Google.Protobuf (#6674) + * Fix latest ArgumentException for C# extensions (#6938) + * Remove unnecessary branch from ReadTag (#7289) + + Objective-C + * [experimental] ObjC Proto3 optional support (#7421) + * Block subclassing of generated classes (#7124) + * Use references to Obj C classes instead of names in descriptors. (#7026) + * Revisit how the WKTs are bundled with ObjC. (#7173) + + Other + * Add a proto_lang_toolchain for javalite (#6882) + * [bazel] Update gtest and deprecate //external:{gtest,gtest_main} (#7237) + * Add application note for explicit presence tracking. (#7390) + * Howto doc for implementing proto3 presence in a code generator. (#7407) + + +2020-02-14 version 3.11.4 (C++/Java/Python/PHP/Objective-C/C#/Ruby/JavaScript) + + C# + * Fix latest ArgumentException for C# extensions (#7188) + * Enforce recursion depth checking for unknown fields (#7210) + + Ruby + * Fix wrappers with a zero value (#7195) + * Fix JSON serialization of 0/empty-valued wrapper types (#7198) + +2020-01-31 version 3.11.3 (C++/Java/Python/PHP/Objective-C/C#/Ruby/JavaScript) + + C++ + * Add OUT and OPTIONAL to windows portability files (#7087) + + PHP + * Refactored ulong to zend_ulong for php7.4 compatibility (#7147) + * Call register_class before getClass from desc to fix segfault (#7077) + + +2019-12-10 version 3.11.2 (C++/Java/Python/PHP/Objective-C/C#/Ruby/JavaScript) + + PHP + * Make c extension portable for php 7.4 (#6968) + + +2019-12-02 version 3.11.1 (C++/Java/Python/PHP/Objective-C/C#/Ruby/JavaScript) + + PHP + * Extern declare protobuf_globals (#6946) + + +2019-11-19 version 3.11.0 (C++/Java/Python/PHP/Objective-C/C#/Ruby/JavaScript) + + C++ + * Make serialization method naming consistent + * Make proto runtime + generated code free of deprecation warnings + * Moved ShutdownProtobufLibrary() to message_lite.h. For backward compatibility a declaration is still available in stubs/common.h, but users should prefer message_lite.h + * Removed non-namespace macro EXPECT_OK() + * Removed mathlimits.h from stubs in favor of using std::numeric_limits from C++11 + * Fixed bug in parser when ending on a group tag + * Add a helper function to UnknownFieldSet to deal with the changing return value of message::unknown_fields() + * Fix incorrect use of string_view iterators + * Support direct pickling of nested messages + * Skip extension tag validation for MessageSet if unknown dependencies are allowed + * Updated deprecation macros to annotate deprecated code (#6612) + * Remove conversion warning in MapEntryFuncs::ByteSizeLong (#6766) + * Revert "Make shared libraries be able to link to MSVC static runtime libraries, so that VC runtime is not required." (#6914) + + Java + * Remove the usage of MethodHandle, so that Android users prior to API version 26 can use protobuf-java + * Publish ProGuard config for javalite + * Fix for StrictMode disk read violation in ExtensionRegistryLite + * Include part of the ByteString's content in its toString(). + * Include unknown fields when merging proto3 messages in Java lite builders + + Python + * Add float_precision option in json format printer + * Optionally print bytes fields as messages in unknown fields, if possible + * FieldPath: fix testing IsSet on root path '' + * Experimental code gen (fast import protobuf module) which only work with cpp generated code linked in + + JavaScript + * Remove guard for Symbol iterator for jspb.Map + + PHP + * Avoid too much overhead in layout_init (#6716) + * Lazily Create Singular Wrapper Message (#6833) + * Implement lazy loading of php class for proto messages (#6911) + + Ruby + * Ruby lazy wrappers optimization (#6797) + + C# + * (RepeatedField): Capacity property to resize the internal array (#6530) + * Experimental proto2 support is now officially available (#4642, #5183, #5350, #5936) + * Getting started doc: https://github.com/protocolbuffers/protobuf/blob/master/docs/csharp/proto2.md + * Add length checks to ExtensionCollection (#6759) + * Optimize parsing of some primitive and wrapper types (#6843) + * Use 3 parameter Encoding.GetString for default string values (#6828) + * Change _Extensions property to normal body rather than expression (#6856) + + Objective C + * Fixed unaligned reads for 32bit arm with newer Xcode versions (#6678) + + +2019-09-03 version 3.10.0 (C++/Java/Python/PHP/Objective-C/C#/Ruby/JavaScript) + + C++ + * Switch the proto parser to the faster MOMI parser. + * Properly escape Struct keys in the proto3 JSON serializer. + * Fix crash on uninitialized map entries. + * Informed the compiler of has-bit invariant to produce better code + * Unused imports of files defining descriptor extensions will now be reported + * Add proto2::util::RemoveSubranges to remove multiple subranges in linear time. + * Added BaseTextGenerator::GetCurrentIndentationSize() + * Made implicit weak fields compatible with the Apple linker + * Support 32 bit values for ProtoStreamObjectWriter to Struct. + * Removed the internal-only header coded_stream_inl.h and the internal-only methods defined there. + * Enforced no SWIG wrapping of descriptor_database.h (other headers already had this restriction). + * Implementation of the equivalent of the MOMI parser for serialization. This removes one of the two serialization routines, by making the fast array serialization routine completely general. SerializeToCodedStream can now be implemented in terms of the much much faster array serialization. The array serialization regresses slightly, but when array serialization is not possible this wins big. + * Do not convert unknown field name to snake case to accurately report error. + * Fix a UBSAN warnings. (#6333) + * Add podspec for C++ (#6404) + * protoc: fix source code info location for missing label (#6436) + * C++ Add move constructor for Reflection's SetString (#6477) + + Java + * Call loadDescriptor outside of synchronized block to remove one possible source of deadlock. + * Have oneof enums implement a separate interface (other than EnumLite) for clarity. + * Opensource Android Memory Accessors + * Update TextFormat to make use of the new TypeRegistry. + * Support getFieldBuilder and getRepeatedFieldBuilder in ExtendableBuilder + * Update JsonFormat to make use of the new TypeRegistry. + * Add proguard config generator for GmmBenchmarkSuiteLite. + * Change ProtobufArrayList to use Object[] instead of ArrayList for 5-10% faster parsing + * Implement ProtobufArrayList.add(E) for 20% (5%-40%) faster overall protolite2 parsing + * Make a copy of JsonFormat.TypeRegistry at the protobuf top level package. This will eventually replace JsonFormat.TypeRegistry. + * Fix javadoc warnings in generated files (#6231) + * Java: Add Automatic-Module-Name entries to the Manifest (#6568) + + Python + * Add descriptor methods in descriptor_pool are deprecated. + * Uses explicit imports to prevent multithread test failures in py3. + * Added __delitem__ for Python extension dict + * Update six version to 1.12.0 and fix legacy_create_init issue (#6391) + + JavaScript + * Remove deprecated boolean option to getResultBase64String(). + * Fix sint64 zig-zag encoding. + * Simplify hash64 string conversion to avoid DIGIT array. Should reduce overhead if these functions aren't used, and be more efficient by avoiding linear array searches. + * Change the parameter types of binaryReaderFn in ExtensionFieldBinaryInfo to (number, ?, ?). + * Create dates.ts and time_of_days.ts to mirror Java versions. This is a near-identical conversion of c.g.type.util.{Dates,TimeOfDays} respectively. + * Migrate moneys to TypeScript. + + PHP + * Fix incorrect leap day for Timestamp (#6696) + * Initialize well known type values (#6713) + + Ruby + * Fix scope resolution for Google namespace (#5878) + * Support hashes for struct initializers (#5716) + * Optimized away the creation of empty string objects. (#6502) + * Roll forward Ruby upb changes now that protobuf Ruby build is fixed (#5866) + * Optimized layout_mark() for Ruby (#6521) + * Optimization for layout_init() (#6547) + * Fix for GC of Ruby map frames. (#6533) + * Fixed leap year handling by reworking upb_mktime() -> upb_timegm(). (#6695) + + Objective C + * Remove OSReadLittle* due to alignment requirements (#6678) + * Don't use unions and instead use memcpy for the type swaps. (#6672) + + Other + * Override CocoaPods module to lowercase (#6464) + + +2019-06-28 version 3.9.0 (C++/Java/Python/PHP/Objective-C/C#/Ruby/JavaScript) + + C++ + * Optimize and simplify implementation of RepeatedPtrFieldBase + * Don't create unnecessary unknown field sets. + * Remove branch from accessors to repeated field element array. + * Added delimited parse and serialize util. + * Reduce size by not emitting constants for fieldnumbers + * Fix a bug when comparing finite and infinite field values with explicit tolerances. + * TextFormat::Parser should use a custom Finder to look up extensions by number if one is provided. + * Add MessageLite::Utf8DebugString() to make MessageLite more compatible with Message. + * Fail fast for better performance in DescriptorPool::FindExtensionByNumber() if descriptor has no defined extensions. + * Adding the file name to help debug colliding extensions + * Added FieldDescriptor::PrintableNameForExtension() and DescriptorPool::FindExtensionByPrintableName(). + The latter will replace Reflection::FindKnownExtensionByName(). + * Replace NULL with nullptr + * Created a new Add method in repeated field that allows adding a range of elements all at once. + * Enabled enum name-to-value mapping functions for C++ lite + * Avoid dynamic initialization in descriptor.proto generated code + * Move stream functions to MessageLite from Message. + * Move all zero_copy_stream functionality to io_lite. + * Do not create array of matched fields for simple repeated fields + * Enabling silent mode by default to reduce make compilation noise. (#6237) + + Java + * Expose TextFormat.Printer and make it configurable. Deprecate the static methods. + * Library for constructing google.protobuf.Struct and google.protobuf.Value + * Make OneofDescriptor extend GenericDescriptor. + * Expose streamingness of service methods from MethodDescriptor. + * Fix a bug where TextFormat fails to parse Any filed with > 1 embedded message sub-fields. + * Establish consistent JsonFormat behavior for nulls in oneofs, regardless of order. + * Update GSON version to 3.8.5. (#6268) + * Add `protobuf_java_lite` Bazel target. (#6177) + + Python + * Change implementation of Name() for enums that allow aliases in proto2 in Python + to be in line with claims in C++ implementation (to return first value). + * Explicitly say what field cannot be set when the new value fails a type check. + * Duplicate register in descriptor pool will raise errors + * Add __slots__ to all well_known_types classes, custom attributes are not allowed anymore. + * text_format only present 8 valid digits for float fields by default + + JavaScript + * Add Oneof enum to the list of goog.provide + + PHP + * Make php message class final to avoid mocking. (#6277) + * Rename get/setXXXValue to get/setXXXWrapper. (#6295) + + Ruby + * Remove to_hash methods. (#6166) + + +2019-04-29 version 3.8.0 (C++/Java/Python/PHP/Objective-C/C#/Ruby/JavaScript) + + C++ + * Use std::atomic<int32> in case of myriad2 platform + * Always declare enums to be int-sized + * Added DebugString() and ShortDebugString() methods on MessageLite + * Specialized different parse loop control flows + * Make hasbits potentially in register. The or's start forming an obstacle because it's a read modify store on the same mem address on each iteration. + * Move to an internal MACRO for parser validity checks. + * Improve map parsing performance. + * Make MergePartialFromCodedStream non virtual. This allows direct calls, potential inlining and is also a code health improvement + * Add an overall limit to parse_context to prevent reading past it. This allows to remove a annoying level of indirection. + * Fix a mistake, we shouldn't verify map key/value strings for utf8 in opt mode for proto2. + * Further improvements to cut binary size. + * Prepare to make MergePartialFromCodedStream non-virtual. + * A report on some interesting behavior change in python (caused by b/27494216) made me realize there is a check that needs to be done in case the parse ended on a end group tag. + * Add a note of caution to the comments around skip in CodedOutputStream. + * Simplify end check. + * Add overload for ParseMessage for MessageLite/Message types. If the explicit type is not known inlining won't help de-virtualizing the virtual call. + * Reduce linker input. It turns out that ParseMessage is not inlined, producing template instantiations that are used only once and save nothing but cost more. + * Improve the parser. + * [c++17] Changed proto2::RepeatedPtrField iterators to no longer derive from the deprecated std::iterator class. + * Change the default value of case_insensitive_enum_parsing to false for JsonStringToMessage. + * Add a warning if a field name doesn't match the style guide. + * Fix TextFormat not round-trip correctly when float value is max float. + * Added locationed info for some errors at compiler + * Python reserved keywords are now working with getattr()/setattr() for most descriptors. + * Added AllowUnknownField() in text_format + * Append '_' to C++ reserved keywords for message, enum, extension + * Fix MSVC warning C4244 in protobuf's parse_context.h. + * Updating Iterators to be compatible with C++17 in MSVC. + * Use capability annotation in mutex.h + * Fix "UndefinedBehaviorSanitizer: cfi-bad-type" + * CriticalSectionLock class as a lightweight replacement for std::mutex on Windows platforms. + * Removed vestigial wire_format_lite_inl.h + + C# + * Added System.Memory dependency. + + Java + * Make Java protoc code generator ignore optimize_for LITE_RUNTIME. Users should instead use the Java lite protoc plugin. + * Change Extension getMessageDefaultInstance() to return Message instead of MessageLite. + * Prevent malicious input streams from leaking buffers for ByteString or ByteBuffer parsing. + * Release new Javalite runtime. + * Show warning in case potential file name conflict. + * Allow Java reserved keywords to be used in extensions. + * Added setAllowUnknownFields() in text format + * Add memoization to ExtensionRegistryLite.getEmptyRegistry() + * Improve performance of CodedOutputStream.writeUInt32NoTag + * Add an optimized mismatch-finding algorithm to UnsafeUtil. + * When serializing uint32 varints, check that we have MAX_VARINT32_SIZE bytes left, not just MAX_VARINT_SIZE. + * Minor optimization to RopeByteString.PieceIterator + + JavaScript + * Simplify generated toObject code when the default value is used. + + Python + * Changes implementation of Name() for enums that allow aliases in proto2 in Python to be in line with claims in C++ implementation (to return first value). + * Added double_format option in text format printer. + * Added iter and __contains__ to extension dict + * Added allow_unknown_field option in python text format parser + * Fixed Timestamp.ToDatetime() loses precision issue + * Support unknown field in text format printer. + * Float field will be convert to inf if bigger than struct.unpack('f', b'\xff\xff\x7f\x7f')[0] which is about 3.4028234664e+38, + convert to -inf if smaller than -3.4028234664e+38 + * Allowed casting str->bytes in Message.__setstate__ + + Ruby + * Helper methods to get enum name for Ruby. + + +2019-01-24 version 3.7.0 (C++/Java/Python/PHP/Objective-C/C#/Ruby/JavaScript) + + C++ + * Introduced new MOMI (maybe-outside-memory-interval) parser. + * Add an option to json_util to parse enum as case-insensitive. In the future, enum parsing in json_util will become case-sensitive. + * Added conformance test for enum aliases + * Added support for --cpp_out=speed:... + * Added use of C++ override keyword where appropriate + * Many other cleanups and fixes. + + Java + * Fix illegal reflective access warning in JDK 9+ + * Add BOM + + Python + * Added Python 3.7 compatibility. + * Modified ParseFromString to return bytes parsed . + * Introduce Proto C API. + * FindFileContainingSymbol in descriptor pool is now able to find field and enum values. + * reflection.MakeClass() and reflection.ParseMessage() are deprecated. + * Added DescriptorPool.FindMethodByName() method in pure python (c extension already has it) + * Flipped proto3 to preserve unknown fields by default. + * Added support for memoryview in python3 proto message parsing. + * Added MergeFrom for repeated scalar fields in c extension (pure python already has it) + * Surrogates are now rejected at setters in python3. + * Added public unknown field API. + * RecursionLimit is also set to max if allow_oversize_protos is enabled. + * Disallow duplicate scalars in proto3 text_format parse. + * Fix some segment faults for c extension map field. + + PHP + * Most issues for json encoding/decoding in the c extension have been fixed. There are still some edge cases not fixed. For more details, check conformance/failure_list_php_c.txt. + * Supports php 7.3 + * Added helper methods to convert between enum values and names. + * Allow setting/getting wrapper message fields using primitive values. + * Various bug fixes. + + Ruby + * Ruby 2.6 support. + * Drops support for ruby < 2.3. + * Most issues for json encoding/decoding in the c extension have been fixed. There are still some edge cases not fixed. For more details, check conformance/failure_list_ruby.txt. + * Json parsing can specify an option to ignore unknown fields: msg.decode_json(data, {ignore_unknown_fields: true}). + * Added support for proto2 syntax (partially). + * Various bug fixes. + + Csharp + * More support for FieldMask include merge, intersect and more. + * Increasing the default recursion limit to 100. + * Support loading FileDescriptors dynamically. + * Provide access to comments from descriptors. + * Added Any.Is method. + * Compatible with C# 6 + * Added IComparable and comparison operators on Timestamp. + + Objective C + * Add ability to introspect list of enum values (#4678) + * Copy the value when setting message/data fields (#5215) + * Support suppressing the objc package prefix checks on a list of files (#5309) + * More complete keyword and NSObject method (via categories) checks for field names, can result in more fields being rename, but avoids the collisions at runtime (#5289) + * Small fixes to TextFormat generation for extensions (#5362) + * Provide more details/context in deprecation messages (#5412) + * Array/Dictionary enumeration blocks NS_NOESCAPE annotation for Swift (#5421) + * Properly annotate extensions for ARC when their names imply behaviors (#5427) + * Enum alias name collision improvements (#5480) + + +2018-07-27 version 3.6.1 (C++/Java/Python/PHP/Objective-C/C#/Ruby/JavaScript) + + C++ + * Introduced workaround for Windows issue with std::atomic and std::once_flag + initialization (#4777, #4773). + + PHP + * Added compatibility with PHP 7.3 (#4898). + + Ruby + * Fixed Ruby crash involving Any encoding (#4718). + +2018-06-01 version 3.6.0 (C++/Java/Python/PHP/Objective-C/C#/Ruby/JavaScript) + + C++ + * Starting from this release, we now require C++11. For those we cannot yet + upgrade to C++11, we will try to keep the 3.5.x branch updated with + critical bug fixes only. If you have any concerns about this, please + comment on issue #2780. + * Moved to C++11 types like std::atomic and std::unique_ptr and away from our + old custom-built equivalents. + * Added support for repeated message fields in lite protos using implicit + weak fields. This is an experimental feature that allows the linker to + strip out more unused messages than previously was possible. + * Fixed SourceCodeInfo for interpreted options and extension range options. + * Fixed always_print_enums_as_ints option for JSON serialization. + * Added support for ignoring unknown enum values when parsing JSON. + * Create std::string in Arena memory. + * Fixed ValidateDateTime to correctly check the day. + * Fixed bug in ZeroCopyStreamByteSink. + * Various other cleanups and fixes. + + Java + * Dropped support for Java 6. + * Added a UTF-8 decoder that uses Unsafe to directly decode a byte buffer. + * Added deprecation annotations to generated code for deprecated oneof + fields. + * Fixed map field serialization in DynamicMessage. + * Cleanup and documentation for Java Lite runtime. + * Various other fixes and cleanups + * Fixed unboxed arraylists to handle an edge case + * Improved performance for copying between unboxed arraylists + * Fixed lite protobuf to avoid Java compiler warnings + * Improved test coverage for lite runtime + * Performance improvements for lite runtime + + Python + * Fixed bytes/string map key incompatibility between C++ and pure-Python + implementations (issue #4029) + * Added __init__.py files to compiler and util subpackages + * Use /MT for all Windows versions + * Fixed an issue affecting the Python-C++ implementation when used with + Cython (issue #2896) + * Various text format fixes + * Various fixes to resolve behavior differences between the pure-Python and + Python-C++ implementations + + PHP + * Added php_metadata_namespace to control the file path of generated metadata + file. + * Changed generated classes of nested message/enum. E.g., Foo.Bar, which + previously generates Foo_Bar, now generates Foo/Bar + * Added array constructor. When creating a message, users can pass a php + array whose content is field name to value pairs into constructor. The + created message will be initialized according to the array. Note that + message field should use a message value instead of a sub-array. + * Various bug fixes. + + Objective-C + * We removed some helper class methods from GPBDictionary to shrink the size + of the library, the functionary is still there, but you may need to do some + specific +alloc / -init… methods instead. + * Minor improvements in the performance of object field getters/setters by + avoiding some memory management overhead. + * Fix a memory leak during the raising of some errors. + * Make header importing completely order independent. + * Small code improvements for things the undefined behaviors compiler option + was flagging. + + Ruby + * Added ruby_package file option to control the module of generated class. + * Various bug fixes. + + Javascript + * Allow setting string to int64 field. + + Csharp + * Unknown fields are now parsed and then sent back on the wire. They can be + discarded at parse time via a CodedInputStream option. + * Movement towards working with .NET 3.5 and Unity + * Expression trees are no longer used + * AOT generics issues in Unity/il2cpp have a workaround (see this commit for + details) + * Floating point values are now compared bitwise (affects NaN value + comparisons) + * The default size limit when parsing is now 2GB rather than 64MB + * MessageParser now supports parsing from a slice of a byte array + * JSON list parsing now accepts null values where the underlying proto + representation does + +2017-12-20 version 3.5.1 (C++/Java/Python/PHP/Objective-C/C#/Ruby/JavaScript) + Planned Future Changes + * Make C++ implementation C++11 only: we plan to require C++11 to build + protobuf code starting from 3.6.0 release. Please join this github issue: + https://github.com/protocolbuffers/protobuf/issues/2780 to provide your feedback. + + protoc + * Fixed a bug introduced in 3.5.0 and protoc in Windows now accepts non-ascii + characters in paths again. + + C++ + * Removed several usages of C++11 features in the code base. + * Fixed some compiler warnings. + + PHP + * Fixed memory leak in C-extension implementation. + * Added discardUnknokwnFields API. + * Removed duplicated typedef in C-extension headers. + * Avoided calling private php methods (timelib_update_ts). + * Fixed Any.php to use fully-qualified name for DescriptorPool. + + Ruby + * Added Google_Protobuf_discard_unknown for discarding unknown fields in + messages. + + C# + * Unknown fields are now preserved by default. + * Floating point values are now bitwise compared, affecting message equality + check and Contains() API in map and repeated fields. + + +2017-11-13 version 3.5.0 (C++/Java/Python/PHP/Objective-C/C#/Ruby/JavaScript) + Planned Future Changes + * Make C++ implementation C++11 only: we plan to require C++11 to build + protobuf code starting from 3.6.0 release. Please join this github issue: + https://github.com/protocolbuffers/protobuf/issues/2780 to provide your feedback. + + General + * Unknown fields are now preserved in proto3 for most of the language + implementations for proto3 by default. See the per-language section for + details. + * reserve keyword are now supported in enums + + C++ + * Proto3 messages are now preserving unknown fields by default. If you rely on + unknowns fields being dropped. Please use DiscardUnknownFields() explicitly. + * Deprecated the unsafe_arena_release_* and unsafe_arena_add_allocated_* + methods for string fields. + * Added move constructor and move assignment to RepeatedField, + RepeatedPtrField and google::protobuf::Any. + * Added perfect forwarding in Arena::CreateMessage + * In-progress experimental support for implicit weak fields with lite protos. + This feature allows the linker to strip out more unused messages and reduce + binary size. + * Various performance optimizations. + + Java + * Proto3 messages are now preserving unknown fields by default. If you’d like + to drop unknown fields, please use the DiscardUnknownFieldsParser API. For + example: + Parser<Foo> parser = DiscardUnknownFieldsParser.wrap(Foo.parser()); + Foo foo = parser.parseFrom(input); + * Added a new CodedInputStream decoder for Iterable<ByteBuffer> with direct + ByteBuffers. + * TextFormat now prints unknown length-delimited fields as messages if + possible. + * FieldMaskUtil.merge() no longer creates unnecessary empty messages when a + message field is unset in both source message and destination message. + * Various performance optimizations. + + Python + * Proto3 messages are now preserving unknown fields by default. Use + message.DiscardUnknownFields() to drop unknown fields. + * Add FieldDescriptor.file in generated code. + * Add descriptor pool FindOneofByName in pure python. + * Change unknown enum values into unknown field set . + * Add more Python dict/list compatibility for Struct/ListValue. + * Add utf-8 support for text_format.Merge()/Parse(). + * Support numeric unknown enum values for proto3 JSON format. + * Add warning for Unexpected end-group tag in cpp extension. + + PHP + * Proto3 messages are now preserving unknown fields. + * Provide well known type messages in runtime. + * Add prefix ‘PB’ to generated class of reserved names. + * Fixed all conformance tests for encode/decode json in php runtime. C + extension needs more work. + + Objective-C + * Fixed some issues around copying of messages with unknown fields and then + mutating the unknown fields in the copy. + + C# + * Added unknown field support in JsonParser. + * Fixed oneof message field merge. + * Simplify parsing messages from array slices. + + Ruby + * Unknown fields are now preserved by default. + * Fixed several bugs for segment fault. + + Javascript + * Decoder can handle both paced and unpacked data no matter how the proto is + defined. + * Decoder now accept long varint for 32 bit integers. + + +2017-08-14 version 3.4.0 (C++/Java/Python/PHP/Objective-C/C#/Ruby/JavaScript) + Planned Future Changes + * There are some changes that are not included in this release but are planned + for the near future + - Preserve unknown fields in proto3: We are going to bring unknown fields + back into proto3. In this release, some languages start to support + preserving unknown fields in proto3, controlled by flags/options. Some + languages also introduce explicit APIs to drop unknown fields for + migration. Please read the change log sections by languages for details. + For general timeline and plan: + + https://docs.google.com/document/d/1KMRX-G91Aa-Y2FkEaHeeviLRRNblgIahbsk4wA14gRk/view + + For issues and discussions: + + https://github.com/protocolbuffers/protobuf/issues/272 + + - Make C++ implementation C++11 only: we plan to require C++11 to build + protobuf code starting from 3.5.0 or 3.6.0 release, after unknown fields + semantic changes are finished. Please join this + github issue: + + https://github.com/protocolbuffers/protobuf/issues/2780 + + to provide your feedback. + + General + * Extension ranges now accept options and are customizable. + * "reserve" keyword now supports “max” in field number ranges, + e.g. reserve 1000 to max; + + C++ + * Proto3 messages are now able to preserve unknown fields. The default + behavior is still to drop unknowns, which will be flipped in a future + release. If you rely on unknowns fields being dropped. Please use + Message::DiscardUnknownFields() explicitly. + * Packable proto3 fields are now packed by default in serialization. + * Following C++11 features are introduced when C++11 is available: + - move-constructor and move-assignment are introduced to messages + - Repeated fields constructor now takes std::initializer_list + - rvalue setters are introduced for string fields + * Experimental Table-Driven parsing and serialization available to test. To + enable it, pass in table_driven_parsing table_driven_serialization protoc + generator flags for C++ + + $ protoc --cpp_out=table_driven_parsing,table_driven_serialization:./ \ + test.proto + + * lite generator parameter supported by the generator. Once set, all generated + files, use lite runtime regardless of the optimizer_for setting in the + .proto file. + * Various optimizations to make C++ code more performant on PowerPC platform + * Fixed maps data corruption when the maps are modified by both reflection API + and generated API. + * Deterministic serialization on maps reflection now uses stable sort. + * file() accessors are introduced to various *Descriptor classes to make + writing template function easier. + * ByteSize() and SpaceUsed() are deprecated.Use ByteSizeLong() and + SpaceUsedLong() instead + * Consistent hash function is used for maps in DEBUG and NDEBUG build. + * "using namespace std" is removed from stubs/common.h + * Various performance optimizations and bug fixes + + Java + * Introduced new parser API DiscardUnknownFieldsParser in preparation of + proto3 unknown fields preservation change. Users who want to drop unknown + fields should migrate to use this new parser API. For example: + + Parser<Foo> parser = DiscardUnknownFieldsParser.wrap(Foo.parser()); + Foo foo = parser.parseFrom(input); + + * Introduced new TextFormat API printUnicodeFieldValue() that prints field + value without escaping unicode characters. + * Added Durations.compare(Duration, Duration) and + Timestamps.compare(Timestamp, Timestamp). + * JsonFormat now accepts base64url encoded bytes fields. + * Optimized CodedInputStream to do less copies when parsing large bytes + fields. + * Optimized TextFormat to allocate less memory when printing. + + Python + * SerializeToString API is changed to SerializeToString(self, **kwargs), + deterministic parameter is accepted for deterministic serialization. + * Added sort_keys parameter in json format to make the output deterministic. + * Added indent parameter in json format. + * Added extension support in json format. + * Added __repr__ support for repeated field in cpp implementation. + * Added file in FieldDescriptor. + * Added pretty-print filter to text format. + * Services and method descriptors are always printed even if generic_service + option is turned off. + * Note: AppEngine 2.5 is deprecated on June 2017 that AppEngine 2.5 will + never update protobuf runtime. Users who depend on AppEngine 2.5 should use + old protoc. + + PHP + * Support PHP generic services. Specify file option php_generic_service=true + to enable generating service interface. + * Message, repeated and map fields setters take value instead of reference. + * Added map iterator in c extension. + * Support json encode/decode. + * Added more type info in getter/setter phpdoc + * Fixed the problem that c extension and php implementation cannot be used + together. + * Added file option php_namespace to use custom php namespace instead of + package. + * Added fluent setter. + * Added descriptor API in runtime for custom encode/decode. + * Various bug fixes. + + Objective-C + * Fix for GPBExtensionRegistry copying and add tests. + * Optimize GPBDictionary.m codegen to reduce size of overall library by 46K + per architecture. + * Fix some cases of reading of 64bit map values. + * Properly error on a tag with field number zero. + * Preserve unknown fields in proto3 syntax files. + * Document the exceptions on some of the writing apis. + + C# + * Implemented IReadOnlyDictionary<K,V> in MapField<K,V> + * Added TryUnpack method for Any message in addition to Unpack. + * Converted C# projects to MSBuild (csproj) format. + + Ruby + * Several bug fixes. + + Javascript + * Added support of field option js_type. Now one can specify the JS type of a + 64-bit integer field to be string in the generated code by adding option + [jstype = JS_STRING] on the field. + +2017-04-05 version 3.3.0 (C++/Java/Python/PHP/Objective-C/C#/Ruby/JavaScript) + Planned Future Changes + * There are some changes that are not included in this release but are + planned for the near future: + - Preserve unknown fields in proto3: please read this doc: + + https://docs.google.com/document/d/1KMRX-G91Aa-Y2FkEaHeeviLRRNblgIahbsk4wA14gRk/view + + for the timeline and follow up this github issue: + + https://github.com/protocolbuffers/protobuf/issues/272 + + for discussion. + - Make C++ implementation C++11 only: we plan to require C++11 to build + protobuf code starting from 3.4.0 or 3.5.0 release. Please join this + github issue: + + https://github.com/protocolbuffers/protobuf/issues/2780 + + to provide your feedback. + + C++ + * Fixed map fields serialization of DynamicMessage to correctly serialize + both key and value regardless of their presence. + * Parser now rejects field number 0 correctly. + * New API Message::SpaceUsedLong() that’s equivalent to + Message::SpaceUsed() but returns the value in size_t. + * JSON support + - New flag always_print_enums_as_ints in JsonPrintOptions. + - New flag preserve_proto_field_names in JsonPrintOptions. It will instruct + the JSON printer to use the original field name declared in the .proto + file instead of converting them to lowerCamelCase when printing JSON. + - JsonPrintOptions.always_print_primtive_fields now works for oneof message + fields. + - Fixed a bug that doesn’t allow different fields to set the same json_name + value. + - Fixed a performance bug that causes excessive memory copy when printing + large messages. + * Various performance optimizations. + + Java + * Map field setters eagerly validate inputs and throw NullPointerExceptions + as appropriate. + * Added ByteBuffer overloads to the generated parsing methods and the Parser + interface. + * proto3 enum's getNumber() method now throws on UNRECOGNIZED values. + * Output of JsonFormat is now locale independent. + + Python + * Added FindServiceByName() in the pure-Python DescriptorPool. This works only + for descriptors added with DescriptorPool.Add(). Generated descriptor_pool + does not support this yet. + * Added a descriptor_pool parameter for parsing Any in text_format.Parse(). + * descriptor_pool.FindFileContainingSymbol() now is able to find nested + extensions. + * Extending empty [] to repeated field now sets parent message presence. + + PHP + * Added file option php_class_prefix. The prefix will be prepended to all + generated classes defined in the file. + * When encoding, negative int32 values are sign-extended to int64. + * Repeated/Map field setter accepts a regular PHP array. Type checking is + done on the array elements. + * encode/decode are renamed to serializeToString/mergeFromString. + * Added mergeFrom, clear method on Message. + * Fixed a bug that oneof accessor didn’t return the field name that is + actually set. + * C extension now works with php7. + * This is the first GA release of PHP. We guarantee that old generated code + can always work with new runtime and new generated code. + + Objective-C + * Fixed help for GPBTimestamp for dates before the epoch that contain + fractional seconds. + * Added GPBMessageDropUnknownFieldsRecursively() to remove unknowns from a + message and any sub messages. + * Addressed a threading race in extension registration/lookup. + * Increased the max message parsing depth to 100 to match the other languages. + * Removed some use of dispatch_once in favor of atomic compare/set since it + needs to be heap based. + * Fixes for new Xcode 8.3 warnings. + + C# + * Fixed MapField.Values.CopyTo, which would throw an exception unnecessarily + if provided exactly the right size of array to copy to. + * Fixed enum JSON formatting when multiple names mapped to the same numeric + value. + * Added JSON formatting option to format enums as integers. + * Modified RepeatedField<T> to implement IReadOnlyList<T>. + * Introduced the start of custom option handling; it's not as pleasant as it + might be, but the information is at least present. We expect to extend code + generation to improve this in the future. + * Introduced ByteString.FromStream and ByteString.FromStreamAsync to + efficiently create a ByteString from a stream. + * Added whole-message deprecation, which decorates the class with [Obsolete]. + + Ruby + * Fixed Message#to_h for messages with map fields. + * Fixed memcpy() in binary gems to work for old glibc, without breaking the + build for non-glibc libc’s like musl. + + Javascript + * Added compatibility tests for version 3.0.0. + * Added conformance tests. + * Fixed serialization of extensions: we need to emit a value even if it is + falsy (like the number 0). + * Use closurebuilder.py in favor of calcdeps.py for compiling JavaScript. + +2017-01-23 version 3.2.0 (C++/Java/Python/PHP/Ruby/Objective-C/C#/JavaScript/Lite) + General + * Added protoc version number to protoc plugin protocol. It can be used by + protoc plugin to detect which version of protoc is used with the plugin and + mitigate known problems in certain version of protoc. + + C++ + * The default parsing byte size limit has been raised from 64MB to 2GB. + * Added rvalue setters for non-arena string fields. + * Enabled debug logging for Android. + * Fixed a double-free problem when using Reflection::SetAllocatedMessage() + with extension fields. + * Fixed several deterministic serialization bugs: + * MessageLite::SerializeAsString() now respects the global deterministic + serialization flag. + * Extension fields are serialized deterministically as well. Fixed protocol + compiler to correctly report importing-self as an error. + * Fixed FileDescriptor::DebugString() to print custom options correctly. + * Various performance/codesize optimizations and cleanups. + + Java + * The default parsing byte size limit has been raised from 64MB to 2GB. + * Added recursion limit when parsing JSON. + * Fixed a bug that enumType.getDescriptor().getOptions() doesn't have custom + options. + * Fixed generated code to support field numbers up to 2^29-1. + + Python + * You can now assign NumPy scalars/arrays (np.int32, np.int64) to protobuf + fields, and assigning other numeric types has been optimized for + performance. + * Pure-Python: message types are now garbage-collectable. + * Python/C++: a lot of internal cleanup/refactoring. + + PHP (Alpha) + * For 64-bit integers type (int64/uint64/sfixed64/fixed64/sint64), use PHP + integer on 64-bit environment and PHP string on 32-bit environment. + * PHP generated code also conforms to PSR-4 now. + * Fixed ZTS build for c extension. + * Fixed c extension build on Mac. + * Fixed c extension build on 32-bit linux. + * Fixed the bug that message without namespace is not found in the descriptor + pool. (#2240) + * Fixed the bug that repeated field is not iterable in c extension. + * Message names Empty will be converted to GPBEmpty in generated code. + * Added phpdoc in generated files. + * The released API is almost stable. Unless there is large problem, we won't + change it. See + https://developers.google.com/protocol-buffers/docs/reference/php-generated + for more details. + + Objective-C + * Added support for push/pop of the stream limit on CodedInputStream for + anyone doing manual parsing. + + C# + * No changes. + + Ruby + * Message objects now support #respond_to? for field getters/setters. + * You can now compare “message == non_message_object” and it will return false + instead of throwing an exception. + * JRuby: fixed #hashCode to properly reflect the values in the message. + + Javascript + * Deserialization of repeated fields no longer has quadratic performance + behavior. + * UTF-8 encoding/decoding now properly supports high codepoints. + * Added convenience methods for some well-known types: Any, Struct, and + Timestamp. These make it easier to convert data between native JavaScript + types and the well-known protobuf types. + +2016-09-23 version 3.1.0 (C++/Java/Python/PHP/Ruby/Objective-C/C#/JavaScript/Lite) + General + * Proto3 support in PHP (alpha). + * Various bug fixes. + + C++ + * Added MessageLite::ByteSizeLong() that’s equivalent to + MessageLite::ByteSize() but returns the value in size_t. Useful to check + whether a message is over the 2G size limit that protobuf can support. + * Moved default_instances to global variables. This allows default_instance + addresses to be known at compile time. + * Adding missing generic gcc 64-bit atomicops. + * Restore New*Callback into google::protobuf namespace since these are used + by the service stubs code + * JSON support. + * Fixed some conformance issues. + * Fixed a JSON serialization bug for bytes fields. + + Java + * Fixed a bug in TextFormat that doesn’t accept empty repeated fields (i.e., + “field: [ ]”). + * JSON support + * Fixed JsonFormat to do correct snake_case-to-camelCase conversion for + non-style-conforming field names. + * Fixed JsonFormat to parse empty Any message correctly. + * Added an option to JsonFormat.Parser to ignore unknown fields. + * Experimental API + * Added UnsafeByteOperations.unsafeWrap(byte[]) to wrap a byte array into + ByteString without copy. + + Python + * JSON support + * Fixed some conformance issues. + + PHP (Alpha) + * We have added the proto3 support for PHP via both a pure PHP package and a + native c extension. The pure PHP package is intended to provide usability + to wider range of PHP platforms, while the c extension is intended to + provide higher performance. Both implementations provide the same runtime + APIs and share the same generated code. Users don’t need to re-generate + code for the same proto definition when they want to switch the + implementation later. The pure PHP package is included in the php/src + directory, and the c extension is included in the php/ext directory. + + Both implementations provide idiomatic PHP APIs: + * All messages and enums are defined as PHP classes. + * All message fields can only be accessed via getter/setter. + * Both repeated field elements and map elements are stored in containers + that act like a normal PHP array. + + Unlike several existing third-party PHP implementations for protobuf, our + implementations are built on a "strongly-typed" philosophy: message fields + and array/map containers will throw exceptions eagerly when values of the + incorrect type (not including those that can be type converted, e.g., + double <-> integer <-> numeric string) are inserted. + + Currently, pure PHP runtime supports php5.5, 5.6 and 7 on linux. C + extension runtime supports php5.5 and 5.6 on linux. + + See php/README.md for more details about installment. See + https://developers.google.com/protocol-buffers/docs/phptutorial for more + details about APIs. + + Objective-C + * Helpers are now provided for working the Any well known type (see + GPBWellKnownTypes.h for the api additions). + * Some improvements in startup code (especially when extensions aren’t used). + + Javascript + * Fixed missing import of jspb.Map + * Fixed valueWriterFn variable name + + Ruby + * Fixed hash computation for JRuby's RubyMessage + * Make sure map parsing frames are GC-rooted. + * Added API support for well-known types. + + C# + * Removed check on dependency in the C# reflection API. + +2016-09-06 version 3.0.2 (C++/Java/Python/Ruby/Objective-C/C#/JavaScript/Lite) + General + * Various bug fixes. + + Objective C + * Fix for oneofs in proto3 syntax files where fields were set to the zero + value. + * Fix for embedded null character in strings. + * CocoaDocs support + + Ruby + * Fixed memory corruption bug in parsing that could occur under GC pressure. + + Javascript + * jspb.Map is now properly exported to CommonJS modules. + + C# + * Removed legacy_enum_values flag. + + +2016-07-27 version 3.0.0 (C++/Java/Python/Ruby/Objective-C/C#/JavaScript/Lite) + General + * This log only contains changes since the beta-4 release. Summarized change + log since the last stable release (v2.6.1) can be found in the github + release page. + + Compatibility Notice + * v3.0.0 is the first API stable release of the v3.x series. We do not expect + any future API breaking changes. + * For C++, Java Lite and Objective-C, source level compatibility is + guaranteed. Upgrading from v3.0.0 to newer minor version releases will be + source compatible. For example, if your code compiles against protobuf + v3.0.0, it will continue to compile after you upgrade protobuf library to + v3.1.0. + * For other languages, both source level compatibility and binary level + compatibility are guaranteed. For example, if you have a Java binary built + against protobuf v3.0.0. After switching the protobuf runtime binary to + v3.1.0, your built binary should continue to work. + * Compatibility is only guaranteed for documented API and documented + behaviors. If you are using undocumented API (e.g., use anything in the C++ + internal namespace), it can be broken by minor version releases in an + undetermined manner. + + Ruby + * When you assign a string field `a.string_field = "X"`, we now call + #encode(UTF-8) on the string and freeze the copy. This saves you from + needing to ensure the string is already encoded as UTF-8. It also prevents + you from mutating the string after it has been assigned (this is how we + ensure it stays valid UTF-8). + * The generated file for `foo.proto` is now `foo_pb.rb` instead of just + `foo.rb`. This makes it easier to see which imports/requires are from + protobuf generated code, and also prevents conflicts with any `foo.rb` file + you might have written directly in Ruby. It is a backward-incompatible + change: you will need to update all of your `require` statements. + * For package names like `foo_bar`, we now translate this to the Ruby module + `FooBar`. This is more idiomatic Ruby than what we used to do (`Foo_bar`). + + JavaScript + * Scalar fields like numbers and boolean now return defaults instead of + `undefined` or `null` when they are unset. You can test for presence + explicitly by calling `hasFoo()`, which we now generate for scalar fields. + + Java Lite + * Java Lite is now implemented as a separate plugin, maintained in the + `javalite` branch. Both lite runtime and protoc artifacts will be available + in Maven. + + C# + * Target platforms now .NET 4.5, selected portable subsets and .NET Core. + * legacy_enum_values option is no longer supported. + +2016-07-15 version 3.0.0-beta-4 (C++/Java/Python/Ruby/Objective-C/C#/JavaScript) + General + * Added a deterministic serialization API for C++. The deterministic + serialization guarantees that given a binary, equal messages will be + serialized to the same bytes. This allows applications like MapReduce to + group equal messages based on the serialized bytes. The deterministic + serialization is, however, NOT canonical across languages; it is also + unstable across different builds with schema changes due to unknown fields. + Users who need canonical serialization, e.g. persistent storage in a + canonical form, fingerprinting, etc, should define their own + canonicalization specification and implement the serializer using reflection + APIs rather than relying on this API. + * Added OneofOptions. You can now define custom options for oneof groups. + import "google/protobuf/descriptor.proto"; + extend google.protobuf.OneofOptions { + optional int32 my_oneof_extension = 12345; + } + message Foo { + oneof oneof_group { + (my_oneof_extension) = 54321; + ... + } + } + + C++ (beta) + * Introduced a deterministic serialization API in + CodedOutputStream::SetSerializationDeterministic(bool). See the notes about + deterministic serialization in the General section. + * Added google::protobuf::Map::swap() to swap two map fields. + * Fixed a memory leak when calling Reflection::ReleaseMessage() on a message + allocated on arena. + * Improved error reporting when parsing text format protos. + * JSON + - Added a new parser option to ignore unknown fields when parsing JSON. + - Added convenient methods for message to/from JSON conversion. + * Various performance optimizations. + + Java (beta) + * File option "java_generate_equals_and_hash" is now deprecated. equals() and + hashCode() methods are generated by default. + * Added a new JSON printer option "omittingInsignificantWhitespace" to produce + a more compact JSON output. The printer will pretty-print by default. + * Updated Java runtime to be compatible with 2.5.0/2.6.1 generated protos. + + Python (beta) + * Added support to pretty print Any messages in text format. + * Added a flag to ignore unknown fields when parsing JSON. + * Bugfix: "@type" field of a JSON Any message is now correctly put before + other fields. + + Objective-C (beta) + * Updated the code to support compiling with more compiler warnings + enabled. (Issue 1616) + * Exposing more detailed errors for parsing failures. (PR 1623) + * Small (breaking) change to the naming of some methods on the support classes + for map<>. There were collisions with the system provided KVO support, so + the names were changed to avoid those issues. (PR 1699) + * Fixed for proper Swift bridging of error handling during parsing. (PR 1712) + * Complete support for generating sources that will go into a Framework and + depend on generated sources from other Frameworks. (Issue 1457) + + C# (beta) + * RepeatedField optimizations. + * Support for .NET Core. + * Minor bug fixes. + * Ability to format a single value in JsonFormatter (advanced usage only). + * Modifications to attributes applied to generated code. + + Javascript (alpha) + * Maps now have a real map API instead of being treated as repeated fields. + * Well-known types are now provided in the google-protobuf package, and the + code generator knows to require() them from that package. + * Bugfix: non-canonical varints are correctly decoded. + + Ruby (alpha) + * Accessors for oneof fields now return default values instead of nil. + + Java Lite + * Java lite support is removed from protocol compiler. It will be supported + as a protocol compiler plugin in a separate code branch. + +2016-05-16 version 3.0.0-beta-3 (C++/Java/Python/Ruby/Nano/Objective-C/C#/JavaScript) + General + * Supported Proto3 lite-runtime in C++/Java for mobile platforms. + * Any type now supports APIs to specify prefixes other than + type.googleapis.com + * Removed javanano_use_deprecated_package option; Nano will always has its own + ".nano" package. + + C++ (Beta) + * Improved hash maps. + - Improved hash maps comments. In particular, please note that equal hash + maps will not necessarily have the same iteration order and + serialization. + - Added a new hash maps implementation that will become the default in a + later release. + * Arenas + - Several inlined methods in Arena were moved to out-of-line to improve + build performance and code size. + - Added SpaceAllocatedAndUsed() to report both space used and allocated + - Added convenient class UnsafeArenaAllocatedRepeatedPtrFieldBackInserter + * Any + - Allow custom type URL prefixes in Any packing. + - TextFormat now expand the Any type rather than printing bytes. + * Performance optimizations and various bug fixes. + + Java (Beta) + * Introduced an ExperimentalApi annotation. Annotated APIs are experimental + and are subject to change in a backward incompatible way in future releases. + * Introduced zero-copy serialization as an ExperimentalApi + - Introduction of the `ByteOutput` interface. This is similar to + `OutputStream` but provides semantics for lazy writing (i.e. no + immediate copy required) of fields that are considered to be immutable. + - `ByteString` now supports writing to a `ByteOutput`, which will directly + expose the internals of the `ByteString` (i.e. `byte[]` or `ByteBuffer`) + to the `ByteOutput` without copying. + - `CodedOutputStream` now supports writing to a `ByteOutput`. `ByteString` + instances that are too large to fit in the internal buffer will be + (lazily) written to the `ByteOutput` directly. + - This allows applications using large `ByteString` fields to avoid + duplication of these fields entirely. Such an application can supply a + `ByteOutput` that chains together the chunks received from + `CodedOutputStream` before forwarding them onto the IO system. + * Other related changes to `CodedOutputStream` + - Additional use of `sun.misc.Unsafe` where possible to perform fast + access to `byte[]` and `ByteBuffer` values and avoiding unnecessary + range checking. + - `ByteBuffer`-backed `CodedOutputStream` now writes directly to the + `ByteBuffer` rather than to an intermediate array. + * Improved lite-runtime. + - Lite protos now implement deep equals/hashCode/toString + - Significantly improved the performance of Builder#mergeFrom() and + Builder#mergeDelimitedFrom() + * Various bug fixes and small feature enhancement. + - Fixed stack overflow when in hashCode() for infinite recursive oneofs. + - Fixed the lazy field parsing in lite to merge rather than overwrite. + - TextFormat now supports reporting line/column numbers on errors. + - Updated to add appropriate @Override for better compiler errors. + + Python (Beta) + * Added JSON format for Any, Struct, Value and ListValue + * [ ] is now accepted for both repeated scalar fields and repeated message + fields in text format parser. + * Numerical field name is now supported in text format. + * Added DiscardUnknownFields API for python protobuf message. + + Objective-C (Beta) + * Proto comments now come over as HeaderDoc comments in the generated sources + so Xcode can pick them up and display them. + * The library headers have been updated to use HeaderDoc comments so Xcode can + pick them up and display them. + * The per message and per field overhead in both generated code and runtime + object sizes was reduced. + * Generated code now include deprecated annotations when the proto file + included them. + + C# (Beta) + In general: some changes are breaking, which require regenerating messages. + Most user-written code will not be impacted *except* for the renaming of enum + values. + + * Allow custom type URL prefixes in `Any` packing, and ignore them when + unpacking + * `protoc` is now in a separate NuGet package (Google.Protobuf.Tools) + * New option: `internal_access` to generate internal classes + * Enum values are now PascalCased, and if there's a prefix which matches the + name of the enum, that is removed (so an enum `COLOR` with a value + `COLOR_BLUE` would generate a value of just `Blue`). An option + (`legacy_enum_values`) is temporarily available to disable this, but the + option will be removed for GA. + * `json_name` option is now honored + * If group tags are encountered when parsing, they are validated more + thoroughly (although we don't support actual groups) + * NuGet dependencies are better specified + * Breaking: `Preconditions` is renamed to `ProtoPreconditions` + * Breaking: `GeneratedCodeInfo` is renamed to `GeneratedClrTypeInfo` + * `JsonFormatter` now allows writing to a `TextWriter` + * New interface, `ICustomDiagnosticMessage` to allow more compact + representations from `ToString` + * `CodedInputStream` and `CodedOutputStream` now implement `IDisposable`, + which simply disposes of the streams they were constructed with + * Map fields no longer support null values (in line with other languages) + * Improvements in JSON formatting and parsing + + Javascript (Alpha) + * Better support for "bytes" fields: bytes fields can be read as either a + base64 string or UInt8Array (in environments where TypedArray is supported). + * New support for CommonJS imports. This should make it easier to use the + JavaScript support in Node.js and tools like WebPack. See js/README.md for + more information. + * Some significant internal refactoring to simplify and modularize the code. + + Ruby (Alpha) + * JSON serialization now properly uses camelCased names, with a runtime option + that will preserve original names from .proto files instead. + * Well-known types are now included in the distribution. + * Release now includes binary gems for Windows, Mac, and Linux instead of just + source gems. + * Bugfix for serializing oneofs. + + C++/Java Lite (Alpha) + A new "lite" generator parameter was introduced in the protoc for C++ and + Java for Proto3 syntax messages. Example usage: + + ./protoc --cpp_out=lite:$OUTPUT_PATH foo.proto + + The protoc will treat the current input and all the transitive dependencies + as LITE. The same generator parameter must be used to generate the + dependencies. + + In Proto3 syntax files, "optimized_for=LITE_RUNTIME" is no longer supported. + + +2015-12-30 version 3.0.0-beta-2 (C++/Java/Python/Ruby/Nano/Objective-C/C#/JavaScript) + General + * Introduced a new language implementation: JavaScript. + * Added a new field option "json_name". By default proto field names are + converted to "lowerCamelCase" in proto3 JSON format. This option can be + used to override this behavior and specify a different JSON name for the + field. + * Added conformance tests to ensure implementations are following proto3 JSON + specification. + + C++ (Beta) + * Various bug fixes and improvements to the JSON support utility: + - Duplicate map keys in JSON are now rejected (i.e., translation will + fail). + - Fixed wire-format for google.protobuf.Value/ListValue. + - Fixed precision loss when converting google.protobuf.Timestamp. + - Fixed a bug when parsing invalid UTF-8 code points. + - Fixed a memory leak. + - Reduced call stack usage. + + Java (Beta) + * Cleaned up some unused methods on CodedOutputStream. + * Presized lists for packed fields during parsing in the lite runtime to + reduce allocations and improve performance. + * Improved the performance of unknown fields in the lite runtime. + * Introduced UnsafeByteStrings to support zero-copy ByteString creation. + * Various bug fixes and improvements to the JSON support utility: + - Fixed a thread-safety bug. + - Added a new option “preservingProtoFieldNames” to JsonFormat. + - Added a new option “includingDefaultValueFields” to JsonFormat. + - Updated the JSON utility to comply with proto3 JSON specification. + + Python (Beta) + * Added proto3 JSON format utility. It includes support for all field types + and a few well-known types except for Any and Struct. + * Added runtime support for Any, Timestamp, Duration and FieldMask. + * [ ] is now accepted for repeated scalar fields in text format parser. + * Map fields now have proper O(1) performance for lookup/insert/delete + when using the Python/C++ implementation. They were previously using O(n) + search-based algorithms because the C++ reflection interface didn't + support true map operations. + + Objective-C (Beta) + * Various bug-fixes and code tweaks to pass more strict compiler warnings. + * Now has conformance test coverage and is passing all tests. + + C# (Beta) + * Various bug-fixes. + * Code generation: Files generated in directories based on namespace. + * Code generation: Include comments from .proto files in XML doc + comments (naively) + * Code generation: Change organization/naming of "reflection class" (access + to file descriptor) + * Code generation and library: Add Parser property to MessageDescriptor, + and introduce a non-generic parser type. + * Library: Added TypeRegistry to support JSON parsing/formatting of Any. + * Library: Added Any.Pack/Unpack support. + * Library: Implemented JSON parsing. + + Javascript (Alpha) + * Added proto3 support for JavaScript. The runtime is written in pure + JavaScript and works in browsers and in Node.js. To generate JavaScript + code for your proto, invoke protoc with "--js_out". See js/README.md + for more build instructions. + +2015-08-26 version 3.0.0-beta-1 (C++/Java/Python/Ruby/Nano/Objective-C/C#) + About Beta + * This is the first beta release of protobuf v3.0.0. Not all languages + have reached beta stage. Languages not marked as beta are still in + alpha (i.e., be prepared for API breaking changes). + + General + * Proto3 JSON is supported in several languages (fully supported in C++ + and Java, partially supported in Ruby/C#). The JSON spec is defined in + the proto3 language guide: + + https://developers.google.com/protocol-buffers/docs/proto3#json + + We will publish a more detailed spec to define the exact behavior of + proto3-conformant JSON serializers and parsers. Until then, do not rely + on specific behaviors of the implementation if it’s not documented in + the above spec. More specifically, the behavior is not yet finalized for + the following: + - Parsing invalid JSON input (e.g., input with trailing commas). + - Non-camelCase names in JSON input. + - The same field appears multiple times in JSON input. + - JSON arrays contain “null” values. + - The message has unknown fields. + + * Proto3 now enforces strict UTF-8 checking. Parsing will fail if a string + field contains non UTF-8 data. + + C++ (Beta) + * Introduced new utility functions/classes in the google/protobuf/util + directory: + - MessageDifferencer: compare two proto messages and report their + differences. + - JsonUtil: support converting protobuf binary format to/from JSON. + - TimeUtil: utility functions to work with well-known types Timestamp + and Duration. + - FieldMaskUtil: utility functions to work with FieldMask. + + * Performance optimization of arena construction and destruction. + * Bug fixes for arena and maps support. + * Changed to use cmake for Windows Visual Studio builds. + * Added Bazel support. + + Java (Beta) + * Introduced a new util package that will be distributed as a separate + artifact in maven. It contains: + - JsonFormat: convert proto messages to/from JSON. + - TimeUtil: utility functions to work with Timestamp and Duration. + - FieldMaskUtil: utility functions to work with FieldMask. + + * The static PARSER in each generated message is deprecated, and it will + be removed in a future release. A static parser() getter is generated + for each message type instead. + * Performance optimizations for String fields serialization. + * Performance optimizations for Lite runtime on Android: + - Reduced allocations + - Reduced method overhead after ProGuarding + - Reduced code size after ProGuarding + + Python (Alpha) + * Removed legacy Python 2.5 support. + * Moved to a single Python 2.x/3.x-compatible codebase, instead of using 2to3. + * Fixed build/tests on Python 2.6, 2.7, 3.3, and 3.4. + - Pure-Python works on all four. + - Python/C++ implementation works on all but 3.4, due to changes in the + Python/C++ API in 3.4. + * Some preliminary work has been done to allow for multiple DescriptorPools + with Python/C++. + + Ruby (Alpha) + * Many bugfixes: + - fixed parsing/serialization of bytes, sint, sfixed types + - other parser bugfixes + - fixed memory leak affecting Ruby 2.2 + + JavaNano (Alpha) + * JavaNano generated code now will be put in a nano package by default to + avoid conflicts with Java generated code. + + Objective-C (Alpha) + * Added non-null markup to ObjC library. Requires SDK 8.4+ to build. + * Many bugfixes: + - Removed the class/enum filter. + - Renamed some internal types to avoid conflicts with the well-known types + protos. + - Added missing support for parsing repeated primitive fields in packed or + unpacked forms. + - Added *Count for repeated and map<> fields to avoid auto-create when + checking for them being set. + + C# (Alpha) + * Namespace changed to Google.Protobuf (and NuGet package will be named + correspondingly). + * Target platforms now .NET 4.5 and selected portable subsets only. + * Removed lite runtime. + * Reimplementation to use mutable message types. + * Null references used to represent "no value" for message type fields. + * Proto3 semantics supported; proto2 files are prohibited for C# codegen. + Most proto3 features supported: + - JSON formatting (a.k.a. serialization to JSON), including well-known + types (except for Any). + - Wrapper types mapped to nullable value types (or string/ByteString + allowing nullability). JSON parsing is not supported yet. + - maps + - oneof + - enum unknown value preservation + +2015-05-25 version 3.0.0-alpha-3 (Objective-C/C#): + General + * Introduced two new language implementations (Objective-C, C#) to proto3. + * Explicit "optional" keyword are disallowed in proto3 syntax, as fields are + optional by default. + * Group fields are no longer supported in proto3 syntax. + * Changed repeated primitive fields to use packed serialization by default in + proto3 (implemented for C++, Java, Python in this release). The user can + still disable packed serialization by setting packed to false for now. + * Added well-known type protos (any.proto, empty.proto, timestamp.proto, + duration.proto, etc.). Users can import and use these protos just like + regular proto files. Additional runtime support will be added for them in + future releases (in the form of utility helper functions, or having them + replaced by language specific types in generated code). + * Added a "reserved" keyword in both proto2 and proto3 syntax. User can use + this keyword to declare reserved field numbers and names to prevent them + from being reused by other fields in the same message. + + To reserve field numbers, add a reserved declaration in your message: + + message TestMessage { + reserved 2, 15, 9 to 11, 3; + } + + This reserves field numbers 2, 3, 9, 10, 11 and 15. If a user uses any of + these as field numbers, the protocol buffer compiler will report an error. + + Field names can also be reserved: + + message TestMessage { + reserved "foo", "bar"; + } + + * Various bug fixes since 3.0.0-alpha-2 + + Objective-C + Objective-C includes a code generator and a native objective-c runtime + library. By adding “--objc_out” to protoc, the code generator will generate + a header(*.pbobjc.h) and an implementation file(*.pbobjc.m) for each proto + file. + + In this first release, the generated interface provides: enums, messages, + field support(single, repeated, map, oneof), proto2 and proto3 syntax + support, parsing and serialization. It’s compatible with ARC and non-ARC + usage. Besides, user can also access it via the swift bridging header. + + See objectivec/README.md for details. + + C# + * C# protobufs are based on project + https://github.com/jskeet/protobuf-csharp-port. The original project was + frozen and all the new development will happen here. + * Codegen plugin for C# was completely rewritten to C++ and is now an + integral part of protoc. + * Some refactorings and cleanup has been applied to the C# runtime library. + * Only proto2 is supported in C# at the moment, proto3 support is in + progress and will likely bring significant breaking changes to the API. + + See csharp/README.md for details. + + C++ + * Added runtime support for Any type. To use Any in your proto file, first + import the definition of Any: + + // foo.proto + import "google/protobuf/any.proto"; + message Foo { + google.protobuf.Any any_field = 1; + } + message Bar { + int32 value = 1; + } + + Then in C++ you can access the Any field using PackFrom()/UnpackTo() + methods: + + Foo foo; + Bar bar = ...; + foo.mutable_any_field()->PackFrom(bar); + ... + if (foo.any_field().IsType<Bar>()) { + foo.any_field().UnpackTo(&bar); + ... + } + * In text format, entries of a map field will be sorted by key. + + Java + * Continued optimizations on the lite runtime to improve performance for + Android. + + Python + * Added map support. + - maps now have a dict-like interface (msg.map_field[key] = value) + - existing code that modifies maps via the repeated field interface + will need to be updated. + + Ruby + * Improvements to RepeatedField's emulation of the Ruby Array API. + * Various speedups and internal cleanups. + +2015-02-26 version 3.0.0-alpha-2 (Python/Ruby/JavaNano): + General + * Introduced three new language implementations (Ruby, JavaNano, and + Python) to proto3. + * Various bug fixes since 3.0.0-alpha-1 + + Python: + Python has received several updates, most notably support for proto3 + semantics in any .proto file that declares syntax="proto3". + Messages declared in proto3 files no longer represent field presence + for scalar fields (number, enums, booleans, or strings). You can + no longer call HasField() for such fields, and they are serialized + based on whether they have a non-zero/empty/false value. + + One other notable change is in the C++-accelerated implementation. + Descriptor objects (which describe the protobuf schema and allow + reflection over it) are no longer duplicated between the Python + and C++ layers. The Python descriptors are now simple wrappers + around the C++ descriptors. This change should significantly + reduce the memory usage of programs that use a lot of message + types. + + Ruby: + We have added proto3 support for Ruby via a native C extension. + + The Ruby extension itself is included in the ruby/ directory, and details on + building and installing the extension are in ruby/README.md. The extension + will also be published as a Ruby gem. Code generator support is included as + part of `protoc` with the `--ruby_out` flag. + + The Ruby extension implements a user-friendly DSL to define message types + (also generated by the code generator from `.proto` files). Once a message + type is defined, the user may create instances of the message that behave in + ways idiomatic to Ruby. For example: + + - Message fields are present as ordinary Ruby properties (getter method + `foo` and setter method `foo=`). + - Repeated field elements are stored in a container that acts like a native + Ruby array, and map elements are stored in a container that acts like a + native Ruby hashmap. + - The usual well-known methods, such as `#to_s`, `#dup`, and the like, are + present. + + Unlike several existing third-party Ruby extensions for protobuf, this + extension is built on a "strongly-typed" philosophy: message fields and + array/map containers will throw exceptions eagerly when values of the + incorrect type are inserted. + + See ruby/README.md for details. + + JavaNano: + JavaNano is a special code generator and runtime library designed especially + for resource-restricted systems, like Android. It is very resource-friendly + in both the amount of code and the runtime overhead. Here is an an overview + of JavaNano features compared with the official Java protobuf: + + - No descriptors or message builders. + - All messages are mutable; fields are public Java fields. + - For optional fields only, encapsulation behind setter/getter/hazzer/ + clearer functions is opt-in, which provide proper 'has' state support. + - For proto2, if not opted in, has state (field presence) is not available. + Serialization outputs all fields not equal to their defaults. + The behavior is consistent with proto3 semantics. + - Required fields (proto2 only) are always serialized. + - Enum constants are integers; protection against invalid values only + when parsing from the wire. + - Enum constants can be generated into container interfaces bearing + the enum's name (so the referencing code is in Java style). + - CodedInputByteBufferNano can only take byte[] (not InputStream). + - Similarly CodedOutputByteBufferNano can only write to byte[]. + - Repeated fields are in arrays, not ArrayList or Vector. Null array + elements are allowed and silently ignored. + - Full support for serializing/deserializing repeated packed fields. + - Support extensions (in proto2). + - Unset messages/groups are null, not an immutable empty default + instance. + - toByteArray(...) and mergeFrom(...) are now static functions of + MessageNano. + - The 'bytes' type translates to the Java type byte[]. + + See javanano/README.txt for details. + +2014-12-01 version 3.0.0-alpha-1 (C++/Java): + + General + * Introduced Protocol Buffers language version 3 (aka proto3). + + When protobuf was initially opensourced it implemented Protocol Buffers + language version 2 (aka proto2), which is why the version number + started from v2.0.0. From v3.0.0, a new language version (proto3) is + introduced while the old version (proto2) will continue to be supported. + + The main intent of introducing proto3 is to clean up protobuf before + pushing the language as the foundation of Google's new API platform. + In proto3, the language is simplified, both for ease of use and to + make it available in a wider range of programming languages. At the + same time a few features are added to better support common idioms + found in APIs. + + The following are the main new features in language version 3: + + 1. Removal of field presence logic for primitive value fields, removal + of required fields, and removal of default values. This makes proto3 + significantly easier to implement with open struct representations, + as in languages like Android Java, Objective C, or Go. + 2. Removal of unknown fields. + 3. Removal of extensions, which are instead replaced by a new standard + type called Any. + 4. Fix semantics for unknown enum values. + 5. Addition of maps. + 6. Addition of a small set of standard types for representation of time, + dynamic data, etc. + 7. A well-defined encoding in JSON as an alternative to binary proto + encoding. + + This release (v3.0.0-alpha-1) includes partial proto3 support for C++ and + Java. Items 6 (well-known types) and 7 (JSON format) in the above feature + list are not implemented. + + A new notion "syntax" is introduced to specify whether a .proto file + uses proto2 or proto3: + + // foo.proto + syntax = "proto3"; + message Bar {...} + + If omitted, the protocol compiler will generate a warning and "proto2" will + be used as the default. This warning will be turned into an error in a + future release. + + We recommend that new Protocol Buffers users use proto3. However, we do not + generally recommend that existing users migrate from proto2 from proto3 due + to API incompatibility, and we will continue to support proto2 for a long + time. + + * Added support for map fields (implemented in C++/Java for both proto2 and + proto3). + + Map fields can be declared using the following syntax: + + message Foo { + map<string, string> values = 1; + } + + Data of a map field will be stored in memory as an unordered map and it + can be accessed through generated accessors. + + C++ + * Added arena allocation support (for both proto2 and proto3). + + Profiling shows memory allocation and deallocation constitutes a significant + fraction of CPU-time spent in protobuf code and arena allocation is a + technique introduced to reduce this cost. With arena allocation, new + objects will be allocated from a large piece of preallocated memory and + deallocation of these objects is almost free. Early adoption shows 20% to + 50% improvement in some Google binaries. + + To enable arena support, add the following option to your .proto file: + + option cc_enable_arenas = true; + + Protocol compiler will generate additional code to make the generated + message classes work with arenas. This does not change the existing API + of protobuf messages and does not affect wire format. Your existing code + should continue to work after adding this option. In the future we will + make this option enabled by default. + + To actually take advantage of arena allocation, you need to use the arena + APIs when creating messages. A quick example of using the arena API: + + { + google::protobuf::Arena arena; + // Allocate a protobuf message in the arena. + MyMessage* message = Arena::CreateMessage<MyMessage>(&arena); + // All submessages will be allocated in the same arena. + if (!message->ParseFromString(data)) { + // Deal with malformed input data. + } + // Must not delete the message here. It will be deleted automatically + // when the arena is destroyed. + } + + Currently arena does not work with map fields. Enabling arena in a .proto + file containing map fields will result in compile errors in the generated + code. This will be addressed in a future release. + +2014-10-20 version 2.6.1: + + C++ + * Added atomicops support for Solaris. + * Released memory allocated by InitializeDefaultRepeatedFields() and + GetEmptyString(). Some memory sanitizers reported them as memory leaks. + + Java + * Updated DynamicMessage.setField() to handle repeated enum values + correctly. + * Fixed a bug that caused NullPointerException to be thrown when + converting manually constructed FileDescriptorProto to + FileDescriptor. + + Python + * Fixed WhichOneof() to work with de-serialized protobuf messages. + * Fixed a missing file problem of Python C++ implementation. + +2014-08-15 version 2.6.0: + + General + * Added oneofs(unions) feature. Fields in the same oneof will share + memory and at most one field can be set at the same time. Use the + oneof keyword to define a oneof like: + message SampleMessage { + oneof test_oneof { + string name = 4; + YourMessage sub_message = 9; + } + } + * Files, services, enums, messages, methods and enum values can be marked + as deprecated now. + * Added Support for list values, including lists of messages, when + parsing text-formatted protos in C++ and Java. + For example: foo: [1, 2, 3] + + C++ + * Enhanced customization on TestFormat printing. + * Added SwapFields() in reflection API to swap a subset of fields. + Added SetAllocatedMessage() in reflection API. + * Repeated primitive extensions are now packable. The + [packed=true] option only affects serializers. Therefore, it is + possible to switch a repeated extension field to packed format + without breaking backwards-compatibility. + * Various speed optimizations. + + Java + * writeTo() method in ByteString can now write a substring to an + output stream. Added endWith() method for ByteString. + * ByteString and ByteBuffer are now supported in CodedInputStream + and CodedOutputStream. + * java_generate_equals_and_hash can now be used with the LITE_RUNTIME. + + Python + * A new C++-backed extension module (aka "cpp api v2") that replaces the + old ("cpp api v1") one. Much faster than the pure Python code. This one + resolves many bugs and is recommended for general use over the + pure Python when possible. + * Descriptors now have enum_types_by_name and extension_types_by_name dict + attributes. + * Support for Python 3. + +2013-02-27 version 2.5.0: + + General + * New notion "import public" that allows a proto file to forward the content + it imports to its importers. For example, + // foo.proto + import public "bar.proto"; + import "baz.proto"; + + // qux.proto + import "foo.proto"; + // Stuff defined in bar.proto may be used in this file, but stuff from + // baz.proto may NOT be used without importing it explicitly. + This is useful for moving proto files. To move a proto file, just leave + a single "import public" in the old proto file. + * New enum option "allow_alias" that specifies whether different symbols can + be assigned the same numeric value. Default value is "true". Setting it to + false causes the compiler to reject enum definitions where multiple symbols + have the same numeric value. + Note: We plan to flip the default value to "false" in a future release. + Projects using enum aliases should set the option to "true" in their .proto + files. + + C++ + * New generated method set_allocated_foo(Type* foo) for message and string + fields. This method allows you to set the field to a pre-allocated object + and the containing message takes the ownership of that object. + * Added SetAllocatedExtension() and ReleaseExtension() to extensions API. + * Custom options are now formatted correctly when descriptors are printed in + text format. + * Various speed optimizations. + + Java + * Comments in proto files are now collected and put into generated code as + comments for corresponding classes and data members. + * Added Parser to parse directly into messages without a Builder. For + example, + Foo foo = Foo.PARSER.ParseFrom(input); + Using Parser is ~25% faster than using Builder to parse messages. + * Added getters/setters to access the underlying ByteString of a string field + directly. + * ByteString now supports more operations: substring(), prepend(), and + append(). The implementation of ByteString uses a binary tree structure + to support these operations efficiently. + * New method findInitializationErrors() that lists all missing required + fields. + * Various code size and speed optimizations. + + Python + * Added support for dynamic message creation. DescriptorDatabase, + DescriptorPool, and MessageFactory work like their C++ counterparts to + simplify Descriptor construction from *DescriptorProtos, and MessageFactory + provides a message instance from a Descriptor. + * Added pickle support for protobuf messages. + * Unknown fields are now preserved after parsing. + * Fixed bug where custom options were not correctly populated. Custom + options can be accessed now. + * Added EnumTypeWrapper that provides better accessibility to enum types. + * Added ParseMessage(descriptor, bytes) to generate a new Message instance + from a descriptor and a byte string. + +2011-05-01 version 2.4.1: + + C++ + * Fixed the friendship problem for old compilers to make the library now gcc 3 + compatible again. + * Fixed vcprojects/extract_includes.bat to extract compiler/plugin.h. + + Java + * Removed usages of JDK 1.6 only features to make the library now JDK 1.5 + compatible again. + * Fixed a bug about negative enum values. + * serialVersionUID is now defined in generated messages for java serializing. + * Fixed protoc to use java.lang.Object, which makes "Object" now a valid + message name again. + + Python + * Experimental C++ implementation now requires C++ protobuf library installed. + See the README.txt in the python directory for details. + +2011-02-02 version 2.4.0: + + General + * The RPC (cc|java|py)_generic_services default value is now false instead of + true. + * Custom options can have aggregate types. For example, + message MyOption { + optional string comment = 1; + optional string author = 2; + } + extend google.protobuf.FieldOptions { + optional MyOption myoption = 12345; + } + This option can now be set as follows: + message SomeType { + optional int32 field = 1 [(myoption) = { comment:'x' author:'y' }]; + } + + C++ + * Various speed and code size optimizations. + * Added a release_foo() method on string and message fields. + * Fixed gzip_output_stream sub-stream handling. + + Java + * Builders now maintain sub-builders for sub-messages. Use getFooBuilder() to + get the builder for the sub-message "foo". This allows you to repeatedly + modify deeply-nested sub-messages without rebuilding them. + * Builder.build() no longer invalidates the Builder for generated messages + (You may continue to modify it and then build another message). + * Code generator will generate efficient equals() and hashCode() + implementations if new option java_generate_equals_and_hash is enabled. + (Otherwise, reflection-based implementations are used.) + * Generated messages now implement Serializable. + * Fields with [deprecated=true] will be marked with @Deprecated in Java. + * Added lazy conversion of UTF-8 encoded strings to String objects to improve + performance. + * Various optimizations. + * Enum value can be accessed directly, instead of calling getNumber() on the + enum member. + * For each enum value, an integer constant is also generated with the suffix + _VALUE. + + Python + * Added an experimental C++ implementation for Python messages via a Python + extension. Implementation type is controlled by an environment variable + PROTOCOL_BUFFERS_PYTHON_IMPLEMENTATION (valid values: "cpp" and "python") + The default value is currently "python" but will be changed to "cpp" in + future release. + * Improved performance on message instantiation significantly. + Most of the work on message instantiation is done just once per message + class, instead of once per message instance. + * Improved performance on text message parsing. + * Allow add() to forward keyword arguments to the concrete class. + E.g. instead of + item = repeated_field.add() + item.foo = bar + item.baz = quux + You can do: + repeated_field.add(foo=bar, baz=quux) + * Added a sort() interface to the BaseContainer. + * Added an extend() method to repeated composite fields. + * Added UTF8 debug string support. + +2010-01-08 version 2.3.0: + + General + * Parsers for repeated numeric fields now always accept both packed and + unpacked input. The [packed=true] option only affects serializers. + Therefore, it is possible to switch a field to packed format without + breaking backwards-compatibility -- as long as all parties are using + protobuf 2.3.0 or above, at least. + * The generic RPC service code generated by the C++, Java, and Python + generators can be disabled via file options: + option cc_generic_services = false; + option java_generic_services = false; + option py_generic_services = false; + This allows plugins to generate alternative code, possibly specific to some + particular RPC implementation. + + protoc + * Now supports a plugin system for code generators. Plugins can generate + code for new languages or inject additional code into the output of other + code generators. Plugins are just binaries which accept a protocol buffer + on stdin and write a protocol buffer to stdout, so they may be written in + any language. See src/google/protobuf/compiler/plugin.proto. + **WARNING**: Plugins are experimental. The interface may change in a + future version. + * If the output location ends in .zip or .jar, protoc will write its output + to a zip/jar archive instead of a directory. For example: + protoc --java_out=myproto_srcs.jar --python_out=myproto.zip myproto.proto + Currently the archive contents are not compressed, though this could change + in the future. + * inf, -inf, and nan can now be used as default values for float and double + fields. + + C++ + * Various speed and code size optimizations. + * DynamicMessageFactory is now fully thread-safe. + * Message::Utf8DebugString() method is like DebugString() but avoids escaping + UTF-8 bytes. + * Compiled-in message types can now contain dynamic extensions, through use + of CodedInputStream::SetExtensionRegistry(). + * Now compiles shared libraries (DLLs) by default on Cygwin and MinGW, to + match other platforms. Use --disable-shared to avoid this. + + Java + * parseDelimitedFrom() and mergeDelimitedFrom() now detect EOF and return + false/null instead of throwing an exception. + * Fixed some initialization ordering bugs. + * Fixes for OpenJDK 7. + + Python + * 10-25 times faster than 2.2.0, still pure-Python. + * Calling a mutating method on a sub-message always instantiates the message + in its parent even if the mutating method doesn't actually mutate anything + (e.g. parsing from an empty string). + * Expanded descriptors a bit. + +2009-08-11 version 2.2.0: + + C++ + * Lite mode: The "optimize_for = LITE_RUNTIME" option causes the compiler + to generate code which only depends libprotobuf-lite, which is much smaller + than libprotobuf but lacks descriptors, reflection, and some other features. + * Fixed bug where Message.Swap(Message) was only implemented for + optimize_for_speed. Swap now properly implemented in both modes + (Issue 91). + * Added RemoveLast and SwapElements(index1, index2) to Reflection + interface for repeated elements. + * Added Swap(Message) to Reflection interface. + * Floating-point literals in generated code that are intended to be + single-precision now explicitly have 'f' suffix to avoid pedantic warnings + produced by some compilers. + * The [deprecated=true] option now causes the C++ code generator to generate + a GCC-style deprecation annotation (no-op on other compilers). + * google::protobuf::GetEnumDescriptor<SomeGeneratedEnumType>() returns the + EnumDescriptor for that type -- useful for templates which cannot call + SomeGeneratedEnumType_descriptor(). + * Various optimizations and obscure bug fixes. + + Java + * Lite mode: The "optimize_for = LITE_RUNTIME" option causes the compiler + to generate code which only depends libprotobuf-lite, which is much smaller + than libprotobuf but lacks descriptors, reflection, and some other features. + * Lots of style cleanups. + + Python + * Fixed endianness bug with floats and doubles. + * Text format parsing support. + * Fix bug with parsing packed repeated fields in embedded messages. + * Ability to initialize fields by passing keyword args to constructor. + * Support iterators in extend and __setslice__ for containers. + +2009-05-13 version 2.1.0: + + General + * Repeated fields of primitive types (types other that string, group, and + nested messages) may now use the option [packed = true] to get a more + efficient encoding. In the new encoding, the entire list is written + as a single byte blob using the "length-delimited" wire type. Within + this blob, the individual values are encoded the same way they would + be normally except without a tag before each value (thus, they are + tightly "packed"). + * For each field, the generated code contains an integer constant assigned + to the field number. For example, the .proto file: + message Foo { optional int bar_baz = 123; } + would generate the following constants, all with the integer value 123: + C++: Foo::kBarBazFieldNumber + Java: Foo.BAR_BAZ_FIELD_NUMBER + Python: Foo.BAR_BAZ_FIELD_NUMBER + Constants are also generated for extensions, with the same naming scheme. + These constants may be used as switch cases. + * Updated bundled Google Test to version 1.3.0. Google Test is now bundled + in its verbatim form as a nested autoconf package, so you can drop in any + other version of Google Test if needed. + * optimize_for = SPEED is now the default, by popular demand. Use + optimize_for = CODE_SIZE if code size is more important in your app. + * It is now an error to define a default value for a repeated field. + Previously, this was silently ignored (it had no effect on the generated + code). + * Fields can now be marked deprecated like: + optional int32 foo = 1 [deprecated = true]; + Currently this does not have any actual effect, but in the future the code + generators may generate deprecation annotations in each language. + * Cross-compiling should now be possible using the --with-protoc option to + configure. See README.txt for more info. + + protoc + * --error_format=msvs option causes errors to be printed in Visual Studio + format, which should allow them to be clicked on in the build log to go + directly to the error location. + * The type name resolver will no longer resolve type names to fields. For + example, this now works: + message Foo {} + message Bar { + optional int32 Foo = 1; + optional Foo baz = 2; + } + Previously, the type of "baz" would resolve to "Bar.Foo", and you'd get + an error because Bar.Foo is a field, not a type. Now the type of "baz" + resolves to the message type Foo. This change is unlikely to make a + difference to anyone who follows the Protocol Buffers style guide. + + C++ + * Several optimizations, including but not limited to: + - Serialization, especially to flat arrays, is 10%-50% faster, possibly + more for small objects. + - Several descriptor operations which previously required locking no longer + do. + - Descriptors are now constructed lazily on first use, rather than at + process startup time. This should save memory in programs which do not + use descriptors or reflection. + - UnknownFieldSet completely redesigned to be more efficient (especially in + terms of memory usage). + - Various optimizations to reduce code size (though the serialization speed + optimizations increased code size). + * Message interface has method ParseFromBoundedZeroCopyStream() which parses + a limited number of bytes from an input stream rather than parsing until + EOF. + * GzipInputStream and GzipOutputStream support reading/writing gzip- or + zlib-compressed streams if zlib is available. + (google/protobuf/io/gzip_stream.h) + * DescriptorPool::FindAllExtensions() and corresponding + DescriptorDatabase::FindAllExtensions() can be used to enumerate all + extensions of a given type. + * For each enum type Foo, protoc will generate functions: + const string& Foo_Name(Foo value); + bool Foo_Parse(const string& name, Foo* result); + The former returns the name of the enum constant corresponding to the given + value while the latter finds the value corresponding to a name. + * RepeatedField and RepeatedPtrField now have back-insertion iterators. + * String fields now have setters that take a char* and a size, in addition + to the existing ones that took char* or const string&. + * DescriptorPool::AllowUnknownDependencies() may be used to tell + DescriptorPool to create placeholder descriptors for unknown entities + referenced in a FileDescriptorProto. This can allow you to parse a .proto + file without having access to other .proto files that it imports, for + example. + * Updated gtest to latest version. The gtest package is now included as a + nested autoconf package, so it should be able to drop new versions into the + "gtest" subdirectory without modification. + + Java + * Fixed bug where Message.mergeFrom(Message) failed to merge extensions. + * Message interface has new method toBuilder() which is equivalent to + newBuilderForType().mergeFrom(this). + * All enums now implement the ProtocolMessageEnum interface. + * Setting a field to null now throws NullPointerException. + * Fixed tendency for TextFormat's parsing to overflow the stack when + parsing large string values. The underlying problem is with Java's + regex implementation (which unfortunately uses recursive backtracking + rather than building an NFA). Worked around by making use of possessive + quantifiers. + * Generated service classes now also generate pure interfaces. For a service + Foo, Foo.Interface is a pure interface containing all of the service's + defined methods. Foo.newReflectiveService() can be called to wrap an + instance of this interface in a class that implements the generic + RpcService interface, which provides reflection support that is usually + needed by RPC server implementations. + * RPC interfaces now support blocking operation in addition to non-blocking. + The protocol compiler generates separate blocking and non-blocking stubs + which operate against separate blocking and non-blocking RPC interfaces. + RPC implementations will have to implement the new interfaces in order to + support blocking mode. + * New I/O methods parseDelimitedFrom(), mergeDelimitedFrom(), and + writeDelimitedTo() read and write "delimited" messages from/to a stream, + meaning that the message size precedes the data. This way, you can write + multiple messages to a stream without having to worry about delimiting + them yourself. + * Throw a more descriptive exception when build() is double-called. + * Add a method to query whether CodedInputStream is at the end of the input + stream. + * Add a method to reset a CodedInputStream's size counter; useful when + reading many messages with the same stream. + * equals() and hashCode() now account for unknown fields. + + Python + * Added slicing support for repeated scalar fields. Added slice retrieval and + removal of repeated composite fields. + * Updated RPC interfaces to allow for blocking operation. A client may + now pass None for a callback when making an RPC, in which case the + call will block until the response is received, and the response + object will be returned directly to the caller. This interface change + cannot be used in practice until RPC implementations are updated to + implement it. + * Changes to input_stream.py should make protobuf compatible with appengine. + +2008-11-25 version 2.0.3: + + protoc + * Enum values may now have custom options, using syntax similar to field + options. + * Fixed bug where .proto files which use custom options but don't actually + define them (i.e. they import another .proto file defining the options) + had to explicitly import descriptor.proto. + * Adjacent string literals in .proto files will now be concatenated, like in + C. + * If an input file is a Windows absolute path (e.g. "C:\foo\bar.proto") and + the import path only contains "." (or contains "." but does not contain + the file), protoc incorrectly thought that the file was under ".", because + it thought that the path was relative (since it didn't start with a slash). + This has been fixed. + + C++ + * Generated message classes now have a Swap() method which efficiently swaps + the contents of two objects. + * All message classes now have a SpaceUsed() method which returns an estimate + of the number of bytes of allocated memory currently owned by the object. + This is particularly useful when you are reusing a single message object + to improve performance but want to make sure it doesn't bloat up too large. + * New method Message::SerializeAsString() returns a string containing the + serialized data. May be more convenient than calling + SerializeToString(string*). + * In debug mode, log error messages when string-type fields are found to + contain bytes that are not valid UTF-8. + * Fixed bug where a message with multiple extension ranges couldn't parse + extensions. + * Fixed bug where MergeFrom(const Message&) didn't do anything if invoked on + a message that contained no fields (but possibly contained extensions). + * Fixed ShortDebugString() to not be O(n^2). Durr. + * Fixed crash in TextFormat parsing if the first token in the input caused a + tokenization error. + * Fixed obscure bugs in zero_copy_stream_impl.cc. + * Added support for HP C++ on Tru64. + * Only build tests on "make check", not "make". + * Fixed alignment issue that caused crashes when using DynamicMessage on + 64-bit Sparc machines. + * Simplify template usage to work with MSVC 2003. + * Work around GCC 4.3.x x86_64 compiler bug that caused crashes on startup. + (This affected Fedora 9 in particular.) + * Now works on "Solaris 10 using recent Sun Studio". + + Java + * New overload of mergeFrom() which parses a slice of a byte array instead + of the whole thing. + * New method ByteString.asReadOnlyByteBuffer() does what it sounds like. + * Improved performance of isInitialized() when optimizing for code size. + + Python + * Corrected ListFields() signature in Message base class to match what + subclasses actually implement. + * Some minor refactoring. + * Don't pass self as first argument to superclass constructor (no longer + allowed in Python 2.6). + +2008-09-29 version 2.0.2: + + General + * License changed from Apache 2.0 to 3-Clause BSD. + * It is now possible to define custom "options", which are basically + annotations which may be placed on definitions in a .proto file. + For example, you might define a field option called "foo" like so: + import "google/protobuf/descriptor.proto" + extend google.protobuf.FieldOptions { + optional string foo = 12345; + } + Then you annotate a field using the "foo" option: + message MyMessage { + optional int32 some_field = 1 [(foo) = "bar"] + } + The value of this option is then visible via the message's + Descriptor: + const FieldDescriptor* field = + MyMessage::descriptor()->FindFieldByName("some_field"); + assert(field->options().GetExtension(foo) == "bar"); + This feature has been implemented and tested in C++ and Java. + Other languages may or may not need to do extra work to support + custom options, depending on how they construct descriptors. + + C++ + * Fixed some GCC warnings that only occur when using -pedantic. + * Improved static initialization code, making ordering more + predictable among other things. + * TextFormat will no longer accept messages which contain multiple + instances of a singular field. Previously, the latter instance + would overwrite the former. + * Now works on systems that don't have hash_map. + + Java + * Print @Override annotation in generated code where appropriate. + + Python + * Strings now use the "unicode" type rather than the "str" type. + String fields may still be assigned ASCII "str" values; they will + automatically be converted. + * Adding a property to an object representing a repeated field now + raises an exception. For example: + # No longer works (and never should have). + message.some_repeated_field.foo = 1 + + Windows + * We now build static libraries rather than DLLs by default on MSVC. + See vsprojects/readme.txt for more information. + +2008-08-15 version 2.0.1: + + protoc + * New flags --encode and --decode can be used to convert between protobuf text + format and binary format from the command-line. + * New flag --descriptor_set_out can be used to write FileDescriptorProtos for + all parsed files directly into a single output file. This is particularly + useful if you wish to parse .proto files from programs written in languages + other than C++: just run protoc as a background process and have it output + a FileDescriptorList, then parse that natively. + * Improved error message when an enum value's name conflicts with another + symbol defined in the enum type's scope, e.g. if two enum types declared + in the same scope have values with the same name. This is disallowed for + compatibility with C++, but this wasn't clear from the error. + * Fixed absolute output paths on Windows. + * Allow trailing slashes in --proto_path mappings. + + C++ + * Reflection objects are now per-class rather than per-instance. To make this + possible, the Reflection interface had to be changed such that all methods + take the Message instance as a parameter. This change improves performance + significantly in memory-bandwidth-limited use cases, since it makes the + message objects smaller. Note that source-incompatible interface changes + like this will not be made again after the library leaves beta. + * Heuristically detect sub-messages when printing unknown fields. + * Fix static initialization ordering bug that caused crashes at startup when + compiling on Mac with static linking. + * Fixed TokenizerTest when compiling with -DNDEBUG on Linux. + * Fixed incorrect definition of kint32min. + * Fix bytes type setter to work with byte sequences with embedded NULLs. + * Other irrelevant tweaks. + + Java + * Fixed UnknownFieldSet's parsing of varints larger than 32 bits. + * Fixed TextFormat's parsing of "inf" and "nan". + * Fixed TextFormat's parsing of comments. + * Added info to Java POM that will be required when we upload the + package to a Maven repo. + + Python + * MergeFrom(message) and CopyFrom(message) are now implemented. + * SerializeToString() raises an exception if the message is missing required + fields. + * Code organization improvements. + * Fixed doc comments for RpcController and RpcChannel, which had somehow been + swapped. + * Fixed text_format_test on Windows where floating-point exponents sometimes + contain extra zeros. + * Fix Python service CallMethod() implementation. + + Other + * Improved readmes. + * VIM syntax highlighting improvements. + +2008-07-07 version 2.0.0: + + * First public release. diff --git a/contrib/libs/protobuf_old/CONTRIBUTING.md b/contrib/libs/protobuf_old/CONTRIBUTING.md new file mode 100644 index 0000000000..8ef5dd29c8 --- /dev/null +++ b/contrib/libs/protobuf_old/CONTRIBUTING.md @@ -0,0 +1,120 @@ +# Contributing to Protocol Buffers + +We welcome some types of contributions to protocol buffers. This doc describes the +process to contribute patches to protobuf and the general guidelines we +expect contributors to follow. + +## What We Accept + +* Bug fixes with unit tests demonstrating the problem are very welcome. + We also appreciate bug reports, even when they don't come with a patch. + Bug fixes without tests are usually not accepted. +* New APIs and features with adequate test coverage and documentation + may be accepted if they do not compromise backwards + compatibility. However there's a fairly high bar of usefulness a new public + method must clear before it will be accepted. Features that are fine in + isolation are often rejected because they don't have enough impact to justify the + conceptual burden and ongoing maintenance cost. It's best to file an issue + and get agreement from maintainers on the value of a new feature before + working on a PR. +* Performance optimizations may be accepted if they have convincing benchmarks that demonstrate + an improvement and they do not significantly increase complexity. +* Changes to existing APIs are almost never accepted. Stability and + backwards compatibility are paramount. In the unlikely event a breaking change + is required, it must usually be implemented in google3 first. +* Changes to the wire and text formats are never accepted. Any breaking change + to these formats would have to be implemented as a completely new format. + We cannot begin generating protos that cannot be parsed by existing code. + +## Before You Start + +We accept patches in the form of github pull requests. If you are new to +github, please read [How to create github pull requests](https://help.github.com/articles/about-pull-requests/) +first. + +### Contributor License Agreements + +Contributions to this project must be accompanied by a Contributor License +Agreement. You (or your employer) retain the copyright to your contribution, +this simply gives us permission to use and redistribute your contributions +as part of the project. + +* If you are an individual writing original source code and you're sure you + own the intellectual property, then you'll need to sign an [individual CLA](https://cla.developers.google.com/about/google-individual?csw=1). +* If you work for a company that wants to allow you to contribute your work, + then you'll need to sign a [corporate CLA](https://cla.developers.google.com/about/google-corporate?csw=1). + +### Coding Style + +This project follows [Google’s Coding Style Guides](https://github.com/google/styleguide). +Before sending out your pull request, please familiarize yourself with the +corresponding style guides and make sure the proposed code change is style +conforming. + +## Contributing Process + +Most pull requests should go to the master branch and the change will be +included in the next major/minor version release (e.g., 3.6.0 release). If you +need to include a bug fix in a patch release (e.g., 3.5.2), make sure it’s +already merged to master, and then create a pull request cherry-picking the +commits from master branch to the release branch (e.g., branch 3.5.x). + +For each pull request, a protobuf team member will be assigned to review the +pull request. For minor cleanups, the pull request may be merged right away +after an initial review. For larger changes, you will likely receive multiple +rounds of comments and it may take some time to complete. We will try to keep +our response time within 7-days but if you don’t get any response in a few +days, feel free to comment on the threads to get our attention. We also expect +you to respond to our comments within a reasonable amount of time. If we don’t +hear from you for 2 weeks or longer, we may close the pull request. You can +still send the pull request again once you have time to work on it. + +Once a pull request is merged, we will take care of the rest and get it into +the final release. + +## Pull Request Guidelines + +* If you are a Googler, it is preferable to first create an internal CL and + have it reviewed and submitted. The code propagation process will deliver the + change to GitHub. +* Create small PRs that are narrowly focused on addressing a single concern. + We often receive PRs that are trying to fix several things at a time, but if + only one fix is considered acceptable, nothing gets merged and both author's + & reviewer's time is wasted. Create more PRs to address different concerns and + everyone will be happy. +* For speculative changes, consider opening an issue and discussing it first. + If you are suggesting a behavioral or API change, make sure you get explicit + support from a protobuf team member before sending us the pull request. +* Provide a good PR description as a record of what change is being made and + why it was made. Link to a GitHub issue if it exists. +* Don't fix code style and formatting unless you are already changing that + line to address an issue. PRs with irrelevant changes won't be merged. If + you do want to fix formatting or style, do that in a separate PR. +* Unless your PR is trivial, you should expect there will be reviewer comments + that you'll need to address before merging. We expect you to be reasonably + responsive to those comments, otherwise the PR will be closed after 2-3 weeks + of inactivity. +* Maintain clean commit history and use meaningful commit messages. PRs with + messy commit history are difficult to review and won't be merged. Use rebase + -i upstream/master to curate your commit history and/or to bring in latest + changes from master (but avoid rebasing in the middle of a code review). +* Keep your PR up to date with upstream/master (if there are merge conflicts, + we can't really merge your change). +* All tests need to be passing before your change can be merged. We recommend + you run tests locally before creating your PR to catch breakages early on. + Ultimately, the green signal will be provided by our testing infrastructure. + The reviewer will help you if there are test failures that seem not related + to the change you are making. + +## Reviewer Guidelines + +* Make sure that all tests are passing before approval. +* Apply the "release notes: yes" label if the pull request's description should + be included in the next release (e.g., any new feature / bug fix). + Apply the "release notes: no" label if the pull request's description should + not be included in the next release (e.g., refactoring changes that does not + change behavior, integration from Google internal, updating tests, etc.). +* Apply the appropriate language label (e.g., C++, Java, Python, etc.) to the + pull request. This will make it easier to identify which languages the pull + request affects, allowing us to better identify appropriate reviewer, create + a better release note, and make it easier to identify issues in the future. diff --git a/contrib/libs/protobuf_old/CONTRIBUTORS.txt b/contrib/libs/protobuf_old/CONTRIBUTORS.txt new file mode 100644 index 0000000000..b8d97fc23d --- /dev/null +++ b/contrib/libs/protobuf_old/CONTRIBUTORS.txt @@ -0,0 +1,102 @@ +This file contains a list of people who have made large contributions +to the public version of Protocol Buffers. + +Original Protocol Buffers design and implementation: + Sanjay Ghemawat <sanjay@google.com> + Jeff Dean <jeff@google.com> + Daniel Dulitz <daniel@google.com> + Craig Silverstein + Paul Haahr <haahr@google.com> + Corey Anderson <corin@google.com> + (and many others) + +Proto2 C++ and Java primary author: + Kenton Varda <kenton@google.com> + +Proto2 Python primary authors: + Will Robinson <robinson@google.com> + Petar Petrov <petar@google.com> + +Java Nano primary authors: + Brian Duff <bduff@google.com> + Tom Chao <chaot@google.com> + Max Cai <maxtroy@google.com> + Ulas Kirazci <ulas@google.com> + +Large code contributions: + Jason Hsueh <jasonh@google.com> + Joseph Schorr <jschorr@google.com> + Wenbo Zhu <wenboz@google.com> + +Large quantity of code reviews: + Scott Bruce <sbruce@google.com> + Frank Yellin + Neal Norwitz <nnorwitz@google.com> + Jeffrey Yasskin <jyasskin@google.com> + Ambrose Feinstein <ambrose@google.com> + +Documentation: + Lisa Carey <lcarey@google.com> + +Maven packaging: + Gregory Kick <gak@google.com> + +Patch contributors: + Kevin Ko <kevin.s.ko@gmail.com> + * Small patch to handle trailing slashes in --proto_path flag. + Johan Euphrosine <proppy@aminche.com> + * Small patch to fix Python CallMethod(). + Ulrich Kunitz <kune@deine-taler.de> + * Small optimizations to Python serialization. + Leandro Lucarella <llucax@gmail.com> + * VI syntax highlighting tweaks. + * Fix compiler to not make output executable. + Dilip Joseph <dilip.antony.joseph@gmail.com> + * Heuristic detection of sub-messages when printing unknown fields in + text format. + Brian Atkinson <nairb774@gmail.com> + * Added @Override annotation to generated Java code where appropriate. + Vincent Choinière <Choiniere.Vincent@hydro.qc.ca> + * Tru64 support. + Monty Taylor <monty.taylor@gmail.com> + * Solaris 10 + Sun Studio fixes. + Alek Storm <alek.storm@gmail.com> + * Slicing support for repeated scalar fields for the Python API. + Oleg Smolsky <oleg.smolsky@gmail.com> + * MS Visual Studio error format option. + * Detect unordered_map in stl_hash.m4. + Brian Olson <brianolson@google.com> + * gzip/zlib I/O support. + Michael Poole <mdpoole@troilus.org> + * Fixed warnings about generated constructors not explicitly initializing + all fields (only present with certain compiler settings). + * Added generation of field number constants. + Wink Saville <wink@google.com> + * Fixed initialization ordering problem in logging code. + Will Pierce <willp@nuclei.com> + * Small patch improving performance of in Python serialization. + Alexandre Vassalotti <alexandre@peadrop.com> + * Emacs mode for Protocol Buffers (editors/protobuf-mode.el). + Scott Stafford <scott.stafford@gmail.com> + * Added Swap(), SwapElements(), and RemoveLast() to Reflection interface. + Alexander Melnikov <alm@sibmail.ru> + * HPUX support. + Oliver Jowett <oliver.jowett@gmail.com> + * Detect whether zlib is new enough in configure script. + * Fixes for Solaris 10 32/64-bit confusion. + Evan Jones <evanj@mit.edu> + * Optimize Java serialization code when writing a small message to a stream. + * Optimize Java serialization of strings so that UTF-8 encoding happens only + once per string per serialization call. + * Clean up some Java warnings. + * Fix bug with permanent callbacks that delete themselves when run. + Michael Kucharski <m.kucharski@gmail.com> + * Added CodedInputStream.getTotalBytesRead(). + Kacper Kowalik <xarthisius.kk@gmail.com> + * Fixed m4/acx_pthread.m4 problem for some Linux distributions. + William Orr <will@worrbase.com> + * Fixed detection of sched_yield on Solaris. + * Added atomicops for Solaris + Andrew Paprocki <andrew@ishiboo.com> + * Fixed minor IBM xlC compiler build issues + * Added atomicops for AIX (POWER) diff --git a/contrib/libs/protobuf_old/LICENSE b/contrib/libs/protobuf_old/LICENSE new file mode 100644 index 0000000000..19b305b000 --- /dev/null +++ b/contrib/libs/protobuf_old/LICENSE @@ -0,0 +1,32 @@ +Copyright 2008 Google Inc. All rights reserved. + +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. + +Code generated by the Protocol Buffer compiler is owned by the owner +of the input file used when generating it. This code is not +standalone and requires a support library to be linked with it. This +support library is itself covered by the above license. diff --git a/contrib/libs/protobuf_old/README.md b/contrib/libs/protobuf_old/README.md new file mode 100644 index 0000000000..618dc2a775 --- /dev/null +++ b/contrib/libs/protobuf_old/README.md @@ -0,0 +1,85 @@ +Protocol Buffers - Google's data interchange format +=================================================== + +Copyright 2008 Google Inc. + +https://developers.google.com/protocol-buffers/ + +Overview +-------- + +Protocol Buffers (a.k.a., protobuf) are Google's language-neutral, +platform-neutral, extensible mechanism for serializing structured data. You +can find [protobuf's documentation on the Google Developers site](https://developers.google.com/protocol-buffers/). + +This README file contains protobuf installation instructions. To install +protobuf, you need to install the protocol compiler (used to compile .proto +files) and the protobuf runtime for your chosen programming language. + +Protocol Compiler Installation +------------------------------ + +The protocol compiler is written in C++. If you are using C++, please follow +the [C++ Installation Instructions](src/README.md) to install protoc along +with the C++ runtime. + +For non-C++ users, the simplest way to install the protocol compiler is to +download a pre-built binary from our release page: + + [https://github.com/protocolbuffers/protobuf/releases](https://github.com/protocolbuffers/protobuf/releases) + +In the downloads section of each release, you can find pre-built binaries in +zip packages: protoc-$VERSION-$PLATFORM.zip. It contains the protoc binary +as well as a set of standard .proto files distributed along with protobuf. + +If you are looking for an old version that is not available in the release +page, check out the maven repo here: + + [https://repo1.maven.org/maven2/com/google/protobuf/protoc/](https://repo1.maven.org/maven2/com/google/protobuf/protoc/) + +These pre-built binaries are only provided for released versions. If you want +to use the github master version at HEAD, or you need to modify protobuf code, +or you are using C++, it's recommended to build your own protoc binary from +source. + +If you would like to build protoc binary from source, see the [C++ Installation +Instructions](src/README.md). + +Protobuf Runtime Installation +----------------------------- + +Protobuf supports several different programming languages. For each programming +language, you can find instructions in the corresponding source directory about +how to install protobuf runtime for that specific language: + +| Language | Source | +|--------------------------------------|-------------------------------------------------------------| +| C++ (include C++ runtime and protoc) | [src](src) | +| Java | [java](java) | +| Python | [python](python) | +| Objective-C | [objectivec](objectivec) | +| C# | [csharp](csharp) | +| JavaScript | [js](js) | +| Ruby | [ruby](ruby) | +| Go | [protocolbuffers/protobuf-go](https://github.com/protocolbuffers/protobuf-go)| +| PHP | [php](php) | +| Dart | [dart-lang/protobuf](https://github.com/dart-lang/protobuf) | + +Quick Start +----------- + +The best way to learn how to use protobuf is to follow the tutorials in our +developer guide: + +https://developers.google.com/protocol-buffers/docs/tutorials + +If you want to learn from code examples, take a look at the examples in the +[examples](examples) directory. + +Documentation +------------- + +The complete documentation for Protocol Buffers is available via the +web at: + +https://developers.google.com/protocol-buffers/ diff --git a/contrib/libs/protobuf_old/SECURITY.md b/contrib/libs/protobuf_old/SECURITY.md new file mode 100644 index 0000000000..76a40ee066 --- /dev/null +++ b/contrib/libs/protobuf_old/SECURITY.md @@ -0,0 +1,4 @@ +To report security concerns or vulnerabilities within protobuf, please use +Google's official channel for reporting these. + +https://www.google.com/appserve/security-bugs/m2/new diff --git a/contrib/libs/protobuf_old/builtin_proto/protos_from_protobuf/ya.make b/contrib/libs/protobuf_old/builtin_proto/protos_from_protobuf/ya.make new file mode 100644 index 0000000000..81678689ed --- /dev/null +++ b/contrib/libs/protobuf_old/builtin_proto/protos_from_protobuf/ya.make @@ -0,0 +1,41 @@ +PROTO_LIBRARY() + +WITHOUT_LICENSE_TEXTS() + +LICENSE(BSD-3-Clause) + +EXCLUDE_TAGS( + CPP_PROTO + GO_PROTO +) + +NO_MYPY() + +NO_OPTIMIZE_PY_PROTOS() + +DISABLE(NEED_GOOGLE_PROTO_PEERDIRS) + +PY_NAMESPACE(.) + +PROTO_NAMESPACE( + GLOBAL + contrib/libs/protobuf_old/src +) + +SRCDIR(contrib/libs/protobuf_old/src) + +SRCS( + google/protobuf/any.proto + google/protobuf/api.proto + google/protobuf/descriptor.proto + google/protobuf/duration.proto + google/protobuf/empty.proto + google/protobuf/field_mask.proto + google/protobuf/source_context.proto + google/protobuf/struct.proto + google/protobuf/timestamp.proto + google/protobuf/type.proto + google/protobuf/wrappers.proto +) + +END() diff --git a/contrib/libs/protobuf_old/src/README.md b/contrib/libs/protobuf_old/src/README.md new file mode 100644 index 0000000000..9db40fdde4 --- /dev/null +++ b/contrib/libs/protobuf_old/src/README.md @@ -0,0 +1,230 @@ +Protocol Buffers - Google's data interchange format +=================================================== + +Copyright 2008 Google Inc. + +https://developers.google.com/protocol-buffers/ + +C++ Installation - Unix +----------------------- + +To build protobuf from source, the following tools are needed: + + * autoconf + * automake + * libtool + * make + * g++ + * unzip + +On Ubuntu/Debian, you can install them with: + + sudo apt-get install autoconf automake libtool curl make g++ unzip + +On other platforms, please use the corresponding package managing tool to +install them before proceeding. + +To get the source, download one of the release .tar.gz or .zip packages in the +release page: + + https://github.com/protocolbuffers/protobuf/releases/latest + +For example: if you only need C++, download `protobuf-cpp-[VERSION].tar.gz`; if +you need C++ and Java, download `protobuf-java-[VERSION].tar.gz` (every package +contains C++ source already); if you need C++ and multiple other languages, +download `protobuf-all-[VERSION].tar.gz`. + +You can also get the source by "git clone" our git repository. Make sure you +have also cloned the submodules and generated the configure script (skip this +if you are using a release .tar.gz or .zip package): + + git clone https://github.com/protocolbuffers/protobuf.git + cd protobuf + git submodule update --init --recursive + ./autogen.sh + +To build and install the C++ Protocol Buffer runtime and the Protocol +Buffer compiler (protoc) execute the following: + + + ./configure + make + make check + sudo make install + sudo ldconfig # refresh shared library cache. + +If "make check" fails, you can still install, but it is likely that +some features of this library will not work correctly on your system. +Proceed at your own risk. + +For advanced usage information on configure and make, please refer to the +autoconf documentation: + + http://www.gnu.org/software/autoconf/manual/autoconf.html#Running-configure-Scripts + +**Hint on install location** + +By default, the package will be installed to /usr/local. However, +on many platforms, /usr/local/lib is not part of LD_LIBRARY_PATH. +You can add it, but it may be easier to just install to /usr +instead. To do this, invoke configure as follows: + + ./configure --prefix=/usr + +If you already built the package with a different prefix, make sure +to run "make clean" before building again. + +**Compiling dependent packages** + +To compile a package that uses Protocol Buffers, you need to pass +various flags to your compiler and linker. As of version 2.2.0, +Protocol Buffers integrates with pkg-config to manage this. If you +have pkg-config installed, then you can invoke it to get a list of +flags like so: + + + pkg-config --cflags protobuf # print compiler flags + pkg-config --libs protobuf # print linker flags + pkg-config --cflags --libs protobuf # print both + + +For example: + + c++ my_program.cc my_proto.pb.cc `pkg-config --cflags --libs protobuf` + +Note that packages written prior to the 2.2.0 release of Protocol +Buffers may not yet integrate with pkg-config to get flags, and may +not pass the correct set of flags to correctly link against +libprotobuf. If the package in question uses autoconf, you can +often fix the problem by invoking its configure script like: + + + configure CXXFLAGS="$(pkg-config --cflags protobuf)" \ + LIBS="$(pkg-config --libs protobuf)" + +This will force it to use the correct flags. + +If you are writing an autoconf-based package that uses Protocol +Buffers, you should probably use the PKG_CHECK_MODULES macro in your +configure script like: + + PKG_CHECK_MODULES([protobuf], [protobuf]) + +See the pkg-config man page for more info. + +If you only want protobuf-lite, substitute "protobuf-lite" in place +of "protobuf" in these examples. + +**Note for Mac users** + +For a Mac system, Unix tools are not available by default. You will first need +to install Xcode from the Mac AppStore and then run the following command from +a terminal: + + sudo xcode-select --install + +To install Unix tools, you can install "port" following the instructions at +https://www.macports.org . This will reside in /opt/local/bin/port for most +Mac installations. + + sudo /opt/local/bin/port install autoconf automake libtool + +Then follow the Unix instructions above. + +**Note for cross-compiling** + +The makefiles normally invoke the protoc executable that they just +built in order to build tests. When cross-compiling, the protoc +executable may not be executable on the host machine. In this case, +you must build a copy of protoc for the host machine first, then use +the --with-protoc option to tell configure to use it instead. For +example: + + ./configure --with-protoc=protoc + +This will use the installed protoc (found in your $PATH) instead of +trying to execute the one built during the build process. You can +also use an executable that hasn't been installed. For example, if +you built the protobuf package for your host machine in ../host, +you might do: + + ./configure --with-protoc=../host/src/protoc + +Either way, you must make sure that the protoc executable you use +has the same version as the protobuf source code you are trying to +use it with. + +**Note for Solaris users** + +Solaris 10 x86 has a bug that will make linking fail, complaining +about libstdc++.la being invalid. We have included a work-around +in this package. To use the work-around, run configure as follows: + + ./configure LDFLAGS=-L$PWD/src/solaris + +See src/solaris/libstdc++.la for more info on this bug. + +**Note for HP C++ Tru64 users** + +To compile invoke configure as follows: + + ./configure CXXFLAGS="-O -std ansi -ieee -D__USE_STD_IOSTREAM" + +Also, you will need to use gmake instead of make. + +**Note for AIX users** + +Compile using the IBM xlC C++ compiler as follows: + + ./configure CXX=xlC + +Also, you will need to use GNU `make` (`gmake`) instead of AIX `make`. + +C++ Installation - Windows +-------------------------- + +If you only need the protoc binary, you can download it from the release +page: + + https://github.com/protocolbuffers/protobuf/releases/latest + +In the downloads section, download the zip file protoc-$VERSION-win32.zip. +It contains the protoc binary as well as public proto files of protobuf +library. + +Protobuf and its dependencies can be installed directly by using `vcpkg`: + + >vcpkg install protobuf protobuf:x64-windows + +If zlib support is desired, you'll also need to install the zlib feature: + + >vcpkg install protobuf[zlib] protobuf[zlib]:x64-windows + +See https://github.com/Microsoft/vcpkg for more information. + +To build from source using Microsoft Visual C++, see [cmake/README.md](../cmake/README.md). + +To build from source using Cygwin or MinGW, follow the Unix installation +instructions, above. + +Binary Compatibility Warning +---------------------------- + +Due to the nature of C++, it is unlikely that any two versions of the +Protocol Buffers C++ runtime libraries will have compatible ABIs. +That is, if you linked an executable against an older version of +libprotobuf, it is unlikely to work with a newer version without +re-compiling. This problem, when it occurs, will normally be detected +immediately on startup of your app. Still, you may want to consider +using static linkage. You can configure this package to install +static libraries only using: + + ./configure --disable-shared + +Usage +----- + +The complete documentation for Protocol Buffers is available via the +web at: + +https://developers.google.com/protocol-buffers/ diff --git a/contrib/libs/protobuf_old/src/google/protobuf/any.cc b/contrib/libs/protobuf_old/src/google/protobuf/any.cc new file mode 100644 index 0000000000..73c002f604 --- /dev/null +++ b/contrib/libs/protobuf_old/src/google/protobuf/any.cc @@ -0,0 +1,83 @@ +// 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 <google/protobuf/any.h> + +#include <google/protobuf/arenastring.h> +#include <google/protobuf/descriptor.h> +#include <google/protobuf/generated_message_util.h> +#include <google/protobuf/message.h> + +#include <google/protobuf/port_def.inc> + +namespace google { +namespace protobuf { +namespace internal { + +bool AnyMetadata::PackFrom(Arena* arena, const Message& message) { + return PackFrom(arena, message, kTypeGoogleApisComPrefix); +} + +bool AnyMetadata::PackFrom(Arena* arena, const Message& message, + StringPiece type_url_prefix) { + type_url_->Set( + &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyString(), + GetTypeUrl(message.GetDescriptor()->full_name(), type_url_prefix), arena); + return message.SerializeToString( + value_->Mutable(ArenaStringPtr::EmptyDefault{}, arena)); +} + +bool AnyMetadata::UnpackTo(Message* message) const { + if (!InternalIs(message->GetDescriptor()->full_name())) { + return false; + } + return message->ParseFromString(value_->Get()); +} + +bool GetAnyFieldDescriptors(const Message& message, + const FieldDescriptor** type_url_field, + const FieldDescriptor** value_field) { + const Descriptor* descriptor = message.GetDescriptor(); + if (descriptor->full_name() != kAnyFullTypeName) { + return false; + } + *type_url_field = descriptor->FindFieldByNumber(1); + *value_field = descriptor->FindFieldByNumber(2); + return (*type_url_field != nullptr && + (*type_url_field)->type() == FieldDescriptor::TYPE_STRING && + *value_field != nullptr && + (*value_field)->type() == FieldDescriptor::TYPE_BYTES); +} + +} // namespace internal +} // namespace protobuf +} // namespace google + +#include <google/protobuf/port_undef.inc> diff --git a/contrib/libs/protobuf_old/src/google/protobuf/any.h b/contrib/libs/protobuf_old/src/google/protobuf/any.h new file mode 100644 index 0000000000..3b9e81d2ff --- /dev/null +++ b/contrib/libs/protobuf_old/src/google/protobuf/any.h @@ -0,0 +1,156 @@ +// 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_ANY_H__ +#define GOOGLE_PROTOBUF_ANY_H__ + +#include <string> + +#include <google/protobuf/stubs/common.h> +#include <google/protobuf/arenastring.h> +#include <google/protobuf/message_lite.h> + +#include <google/protobuf/port_def.inc> + +namespace google { +namespace protobuf { + +class FieldDescriptor; +class Message; + +namespace internal { + +extern const char kAnyFullTypeName[]; // "google.protobuf.Any". +extern const char kTypeGoogleApisComPrefix[]; // "type.googleapis.com/". +extern const char kTypeGoogleProdComPrefix[]; // "type.googleprod.com/". + +TProtoStringType GetTypeUrl(StringPiece message_name, + StringPiece type_url_prefix); + +// Helper class used to implement google::protobuf::Any. +class PROTOBUF_EXPORT AnyMetadata { + typedef ArenaStringPtr UrlType; + typedef ArenaStringPtr ValueType; + public: + // AnyMetadata does not take ownership of "type_url" and "value". + constexpr AnyMetadata(UrlType* type_url, ValueType* value) + : type_url_(type_url), value_(value) {} + + // Packs a message using the default type URL prefix: "type.googleapis.com". + // The resulted type URL will be "type.googleapis.com/<message_full_name>". + // Returns false if serializing the message failed. + template <typename T> + bool PackFrom(Arena* arena, const T& message) { + return InternalPackFrom(arena, message, kTypeGoogleApisComPrefix, + T::FullMessageName()); + } + + bool PackFrom(Arena* arena, const Message& message); + + // Packs a message using the given type URL prefix. The type URL will be + // constructed by concatenating the message type's full name to the prefix + // with an optional "/" separator if the prefix doesn't already end with "/". + // For example, both PackFrom(message, "type.googleapis.com") and + // PackFrom(message, "type.googleapis.com/") yield the same result type + // URL: "type.googleapis.com/<message_full_name>". + // Returns false if serializing the message failed. + template <typename T> + bool PackFrom(Arena* arena, const T& message, + StringPiece type_url_prefix) { + return InternalPackFrom(arena, message, type_url_prefix, + T::FullMessageName()); + } + + bool PackFrom(Arena* arena, const Message& message, + StringPiece type_url_prefix); + + // Unpacks the payload into the given message. Returns false if the message's + // type doesn't match the type specified in the type URL (i.e., the full + // name after the last "/" of the type URL doesn't match the message's actual + // full name) or parsing the payload has failed. + template <typename T> + bool UnpackTo(T* message) const { + return InternalUnpackTo(T::FullMessageName(), message); + } + + bool UnpackTo(Message* message) const; + + // Checks whether the type specified in the type URL matches the given type. + // A type is considered matching if its full name matches the full name after + // the last "/" in the type URL. + template <typename T> + bool Is() const { + return InternalIs(T::FullMessageName()); + } + + private: + bool InternalPackFrom(Arena* arena, const MessageLite& message, + StringPiece type_url_prefix, + StringPiece type_name); + bool InternalUnpackTo(StringPiece type_name, + MessageLite* message) const; + bool InternalIs(StringPiece type_name) const; + + UrlType* type_url_; + ValueType* value_; + + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(AnyMetadata); +}; + +// Get the proto type name from Any::type_url value. For example, passing +// "type.googleapis.com/rpc.QueryOrigin" will return "rpc.QueryOrigin" in +// *full_type_name. Returns false if the type_url does not have a "/" +// in the type url separating the full type name. +// +// NOTE: this function is available publicly as: +// google::protobuf::Any() // static method on the generated message type. +bool ParseAnyTypeUrl(StringPiece type_url, TProtoStringType* full_type_name); + +// Get the proto type name and prefix from Any::type_url value. For example, +// passing "type.googleapis.com/rpc.QueryOrigin" will return +// "type.googleapis.com/" in *url_prefix and "rpc.QueryOrigin" in +// *full_type_name. Returns false if the type_url does not have a "/" in the +// type url separating the full type name. +bool ParseAnyTypeUrl(StringPiece type_url, TProtoStringType* url_prefix, + TProtoStringType* full_type_name); + +// See if message is of type google.protobuf.Any, if so, return the descriptors +// for "type_url" and "value" fields. +bool GetAnyFieldDescriptors(const Message& message, + const FieldDescriptor** type_url_field, + const FieldDescriptor** value_field); + +} // namespace internal +} // namespace protobuf +} // namespace google + +#include <google/protobuf/port_undef.inc> + +#endif // GOOGLE_PROTOBUF_ANY_H__ diff --git a/contrib/libs/protobuf_old/src/google/protobuf/any.pb.cc b/contrib/libs/protobuf_old/src/google/protobuf/any.pb.cc new file mode 100644 index 0000000000..eb5dac86cc --- /dev/null +++ b/contrib/libs/protobuf_old/src/google/protobuf/any.pb.cc @@ -0,0 +1,352 @@ +// Generated by the protocol buffer compiler. DO NOT EDIT! +// source: google/protobuf/any.proto + +#include <google/protobuf/any.pb.h> + +#include <algorithm> + +#include <google/protobuf/io/coded_stream.h> +#include <google/protobuf/extension_set.h> +#include <google/protobuf/wire_format_lite.h> +#include <google/protobuf/descriptor.h> +#include <google/protobuf/generated_message_reflection.h> +#include <google/protobuf/reflection_ops.h> +#include <google/protobuf/wire_format.h> +// @@protoc_insertion_point(includes) +#include <google/protobuf/port_def.inc> + +PROTOBUF_PRAGMA_INIT_SEG +PROTOBUF_NAMESPACE_OPEN +constexpr Any::Any( + ::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized) + : type_url_(&::PROTOBUF_NAMESPACE_ID::internal::fixed_address_empty_string) + , value_(&::PROTOBUF_NAMESPACE_ID::internal::fixed_address_empty_string) + , _any_metadata_(&type_url_, &value_){} +struct AnyDefaultTypeInternal { + constexpr AnyDefaultTypeInternal() + : _instance(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized{}) {} + ~AnyDefaultTypeInternal() {} + union { + Any _instance; + }; +}; +PROTOBUF_ATTRIBUTE_NO_DESTROY PROTOBUF_CONSTINIT AnyDefaultTypeInternal _Any_default_instance_; +PROTOBUF_NAMESPACE_CLOSE +static ::PROTOBUF_NAMESPACE_ID::Metadata file_level_metadata_google_2fprotobuf_2fany_2eproto[1]; +static constexpr ::PROTOBUF_NAMESPACE_ID::EnumDescriptor const** file_level_enum_descriptors_google_2fprotobuf_2fany_2eproto = nullptr; +static constexpr ::PROTOBUF_NAMESPACE_ID::ServiceDescriptor const** file_level_service_descriptors_google_2fprotobuf_2fany_2eproto = nullptr; + +const arc_ui32 TableStruct_google_2fprotobuf_2fany_2eproto::offsets[] PROTOBUF_SECTION_VARIABLE(protodesc_cold) = { + ~0u, // no _has_bits_ + PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::Any, _internal_metadata_), + ~0u, // no _extensions_ + ~0u, // no _oneof_case_ + ~0u, // no _weak_field_map_ + ~0u, // no _inlined_string_donated_ + PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::Any, type_url_), + PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::Any, value_), +}; +static const ::PROTOBUF_NAMESPACE_ID::internal::MigrationSchema schemas[] PROTOBUF_SECTION_VARIABLE(protodesc_cold) = { + { 0, -1, -1, sizeof(::PROTOBUF_NAMESPACE_ID::Any)}, +}; + +static ::PROTOBUF_NAMESPACE_ID::Message const * const file_default_instances[] = { + reinterpret_cast<const ::PROTOBUF_NAMESPACE_ID::Message*>(&::PROTOBUF_NAMESPACE_ID::_Any_default_instance_), +}; + +const char descriptor_table_protodef_google_2fprotobuf_2fany_2eproto[] PROTOBUF_SECTION_VARIABLE(protodesc_cold) = + "\n\031google/protobuf/any.proto\022\017google.prot" + "obuf\"&\n\003Any\022\020\n\010type_url\030\001 \001(\t\022\r\n\005value\030\002" + " \001(\014Bv\n\023com.google.protobufB\010AnyProtoP\001Z" + ",google.golang.org/protobuf/types/known/" + "anypb\242\002\003GPB\252\002\036Google.Protobuf.WellKnownT" + "ypesb\006proto3" + ; +static ::PROTOBUF_NAMESPACE_ID::internal::once_flag descriptor_table_google_2fprotobuf_2fany_2eproto_once; +const ::PROTOBUF_NAMESPACE_ID::internal::DescriptorTable descriptor_table_google_2fprotobuf_2fany_2eproto = { + false, false, 212, descriptor_table_protodef_google_2fprotobuf_2fany_2eproto, "google/protobuf/any.proto", + &descriptor_table_google_2fprotobuf_2fany_2eproto_once, nullptr, 0, 1, + schemas, file_default_instances, TableStruct_google_2fprotobuf_2fany_2eproto::offsets, + file_level_metadata_google_2fprotobuf_2fany_2eproto, file_level_enum_descriptors_google_2fprotobuf_2fany_2eproto, file_level_service_descriptors_google_2fprotobuf_2fany_2eproto, +}; +PROTOBUF_ATTRIBUTE_WEAK const ::PROTOBUF_NAMESPACE_ID::internal::DescriptorTable* descriptor_table_google_2fprotobuf_2fany_2eproto_getter() { + return &descriptor_table_google_2fprotobuf_2fany_2eproto; +} + +// Force running AddDescriptors() at dynamic initialization time. +PROTOBUF_ATTRIBUTE_INIT_PRIORITY static ::PROTOBUF_NAMESPACE_ID::internal::AddDescriptorsRunner dynamic_init_dummy_google_2fprotobuf_2fany_2eproto(&descriptor_table_google_2fprotobuf_2fany_2eproto); +PROTOBUF_NAMESPACE_OPEN + +// =================================================================== + +bool Any::GetAnyFieldDescriptors( + const ::PROTOBUF_NAMESPACE_ID::Message& message, + const ::PROTOBUF_NAMESPACE_ID::FieldDescriptor** type_url_field, + const ::PROTOBUF_NAMESPACE_ID::FieldDescriptor** value_field) { + return ::PROTOBUF_NAMESPACE_ID::internal::GetAnyFieldDescriptors( + message, type_url_field, value_field); +} +bool Any::ParseAnyTypeUrl( + ::PROTOBUF_NAMESPACE_ID::ConstStringParam type_url, + TProtoStringType* full_type_name) { + return ::PROTOBUF_NAMESPACE_ID::internal::ParseAnyTypeUrl(type_url, + full_type_name); +} + +class Any::_Internal { + public: +}; + +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(); + if (!is_message_owned) { + RegisterArenaDtor(arena); + } + // @@protoc_insertion_point(arena_constructor:google.protobuf.Any) +} +Any::Any(const Any& from) + : ::PROTOBUF_NAMESPACE_ID::Message(), + _any_metadata_(&type_url_, &value_) { + _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_); + type_url_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); + #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING + type_url_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation()); + #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING + if (!from._internal_type_url().empty()) { + type_url_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, from._internal_type_url(), + GetArenaForAllocation()); + } + value_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); + #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING + value_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation()); + #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING + if (!from._internal_value().empty()) { + value_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, from._internal_value(), + GetArenaForAllocation()); + } + // @@protoc_insertion_point(copy_constructor:google.protobuf.Any) +} + +inline void Any::SharedCtor() { +type_url_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); +#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING + type_url_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation()); +#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING +value_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); +#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING + value_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation()); +#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING +} + +Any::~Any() { + // @@protoc_insertion_point(destructor:google.protobuf.Any) + if (GetArenaForAllocation() != nullptr) return; + SharedDtor(); + _internal_metadata_.Delete<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(); +} + +inline void Any::SharedDtor() { + GOOGLE_DCHECK(GetArenaForAllocation() == nullptr); + type_url_.DestroyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); + value_.DestroyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); +} + +void Any::ArenaDtor(void* object) { + Any* _this = reinterpret_cast< Any* >(object); + (void)_this; +} +void Any::RegisterArenaDtor(::PROTOBUF_NAMESPACE_ID::Arena*) { +} +void Any::SetCachedSize(int size) const { + _cached_size_.Set(size); +} + +void Any::Clear() { +// @@protoc_insertion_point(message_clear_start:google.protobuf.Any) + arc_ui32 cached_has_bits = 0; + // Prevent compiler warnings about cached_has_bits being unused + (void) cached_has_bits; + + type_url_.ClearToEmpty(); + value_.ClearToEmpty(); + _internal_metadata_.Clear<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(); +} + +const char* Any::_InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) { +#define CHK_(x) if (PROTOBUF_PREDICT_FALSE(!(x))) goto failure + while (!ctx->Done(&ptr)) { + arc_ui32 tag; + ptr = ::PROTOBUF_NAMESPACE_ID::internal::ReadTag(ptr, &tag); + switch (tag >> 3) { + // string type_url = 1; + case 1: + if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 10)) { + auto str = _internal_mutable_type_url(); + ptr = ::PROTOBUF_NAMESPACE_ID::internal::InlineGreedyStringParser(str, ptr, ctx); + CHK_(::PROTOBUF_NAMESPACE_ID::internal::VerifyUTF8(str, "google.protobuf.Any.type_url")); + CHK_(ptr); + } else + goto handle_unusual; + continue; + // bytes value = 2; + case 2: + if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 18)) { + auto str = _internal_mutable_value(); + ptr = ::PROTOBUF_NAMESPACE_ID::internal::InlineGreedyStringParser(str, ptr, ctx); + CHK_(ptr); + } else + goto handle_unusual; + continue; + default: + goto handle_unusual; + } // switch + handle_unusual: + if ((tag == 0) || ((tag & 7) == 4)) { + CHK_(ptr); + ctx->SetLastTag(tag); + goto message_done; + } + ptr = UnknownFieldParse( + tag, + _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(), + ptr, ctx); + CHK_(ptr != nullptr); + } // while +message_done: + return ptr; +failure: + ptr = nullptr; + goto message_done; +#undef CHK_ +} + +uint8_t* Any::_InternalSerialize( + uint8_t* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const { + // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.Any) + arc_ui32 cached_has_bits = 0; + (void) cached_has_bits; + + // string type_url = 1; + if (!this->_internal_type_url().empty()) { + ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::VerifyUtf8String( + this->_internal_type_url().data(), static_cast<int>(this->_internal_type_url().length()), + ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::SERIALIZE, + "google.protobuf.Any.type_url"); + target = stream->WriteStringMaybeAliased( + 1, this->_internal_type_url(), target); + } + + // bytes value = 2; + if (!this->_internal_value().empty()) { + target = stream->WriteBytesMaybeAliased( + 2, this->_internal_value(), target); + } + + if (PROTOBUF_PREDICT_FALSE(_internal_metadata_.have_unknown_fields())) { + target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::InternalSerializeUnknownFieldsToArray( + _internal_metadata_.unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(::PROTOBUF_NAMESPACE_ID::UnknownFieldSet::default_instance), target, stream); + } + // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.Any) + return target; +} + +size_t Any::ByteSizeLong() const { +// @@protoc_insertion_point(message_byte_size_start:google.protobuf.Any) + size_t total_size = 0; + + arc_ui32 cached_has_bits = 0; + // Prevent compiler warnings about cached_has_bits being unused + (void) cached_has_bits; + + // string type_url = 1; + if (!this->_internal_type_url().empty()) { + total_size += 1 + + ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::StringSize( + this->_internal_type_url()); + } + + // bytes value = 2; + if (!this->_internal_value().empty()) { + total_size += 1 + + ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::BytesSize( + this->_internal_value()); + } + + return MaybeComputeUnknownFieldsSize(total_size, &_cached_size_); +} + +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); + arc_ui32 cached_has_bits = 0; + (void) cached_has_bits; + + if (!from._internal_type_url().empty()) { + _internal_set_type_url(from._internal_type_url()); + } + if (!from._internal_value().empty()) { + _internal_set_value(from._internal_value()); + } + _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_); +} + +void Any::CopyFrom(const Any& from) { +// @@protoc_insertion_point(class_specific_copy_from_start:google.protobuf.Any) + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool Any::IsInitialized() const { + return true; +} + +void Any::InternalSwap(Any* other) { + using std::swap; + auto* lhs_arena = GetArenaForAllocation(); + auto* rhs_arena = other->GetArenaForAllocation(); + _internal_metadata_.InternalSwap(&other->_internal_metadata_); + ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::InternalSwap( + &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), + &type_url_, lhs_arena, + &other->type_url_, rhs_arena + ); + ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::InternalSwap( + &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), + &value_, lhs_arena, + &other->value_, rhs_arena + ); +} + +::PROTOBUF_NAMESPACE_ID::Metadata Any::GetMetadata() const { + return ::PROTOBUF_NAMESPACE_ID::internal::AssignDescriptors( + &descriptor_table_google_2fprotobuf_2fany_2eproto_getter, &descriptor_table_google_2fprotobuf_2fany_2eproto_once, + file_level_metadata_google_2fprotobuf_2fany_2eproto[0]); +} + +// @@protoc_insertion_point(namespace_scope) +PROTOBUF_NAMESPACE_CLOSE +PROTOBUF_NAMESPACE_OPEN +template<> PROTOBUF_NOINLINE ::PROTOBUF_NAMESPACE_ID::Any* Arena::CreateMaybeMessage< ::PROTOBUF_NAMESPACE_ID::Any >(Arena* arena) { + return Arena::CreateMessageInternal< ::PROTOBUF_NAMESPACE_ID::Any >(arena); +} +PROTOBUF_NAMESPACE_CLOSE + +// @@protoc_insertion_point(global_scope) +#include <google/protobuf/port_undef.inc> diff --git a/contrib/libs/protobuf_old/src/google/protobuf/any.pb.h b/contrib/libs/protobuf_old/src/google/protobuf/any.pb.h new file mode 100644 index 0000000000..833596f47e --- /dev/null +++ b/contrib/libs/protobuf_old/src/google/protobuf/any.pb.h @@ -0,0 +1,391 @@ +// Generated by the protocol buffer compiler. DO NOT EDIT! +// source: google/protobuf/any.proto + +#ifndef GOOGLE_PROTOBUF_INCLUDED_google_2fprotobuf_2fany_2eproto +#define GOOGLE_PROTOBUF_INCLUDED_google_2fprotobuf_2fany_2eproto + +#include <limits> +#include <string> + +#include <google/protobuf/port_def.inc> +#if PROTOBUF_VERSION < 3019000 +#error This file was generated by a newer version of protoc which is +#error incompatible with your Protocol Buffer headers. Please update +#error your headers. +#endif +#if 3019000 < PROTOBUF_MIN_PROTOC_VERSION +#error This file was generated by an older version of protoc which is +#error incompatible with your Protocol Buffer headers. Please +#error regenerate this file with a newer version of protoc. +#endif + +#include <google/protobuf/port_undef.inc> +#include <google/protobuf/io/coded_stream.h> +#include <google/protobuf/arena.h> +#include <google/protobuf/arenastring.h> +#include <google/protobuf/generated_message_table_driven.h> +#include <google/protobuf/generated_message_util.h> +#include <google/protobuf/metadata_lite.h> +#include <google/protobuf/generated_message_reflection.h> +#include <google/protobuf/message.h> +#include <google/protobuf/repeated_field.h> // IWYU pragma: export +#include <google/protobuf/extension_set.h> // IWYU pragma: export +#include <google/protobuf/unknown_field_set.h> +// @@protoc_insertion_point(includes) +#include <google/protobuf/port_def.inc> +#define PROTOBUF_INTERNAL_EXPORT_google_2fprotobuf_2fany_2eproto PROTOBUF_EXPORT +PROTOBUF_NAMESPACE_OPEN +namespace internal { +class AnyMetadata; +} // namespace internal +PROTOBUF_NAMESPACE_CLOSE + +// Internal implementation detail -- do not use these members. +struct PROTOBUF_EXPORT TableStruct_google_2fprotobuf_2fany_2eproto { + static const ::PROTOBUF_NAMESPACE_ID::internal::ParseTableField entries[] + PROTOBUF_SECTION_VARIABLE(protodesc_cold); + static const ::PROTOBUF_NAMESPACE_ID::internal::AuxiliaryParseTableField aux[] + PROTOBUF_SECTION_VARIABLE(protodesc_cold); + static const ::PROTOBUF_NAMESPACE_ID::internal::ParseTable schema[1] + PROTOBUF_SECTION_VARIABLE(protodesc_cold); + static const ::PROTOBUF_NAMESPACE_ID::internal::FieldMetadata field_metadata[]; + static const ::PROTOBUF_NAMESPACE_ID::internal::SerializationTable serialization_table[]; + static const arc_ui32 offsets[]; +}; +PROTOBUF_EXPORT extern const ::PROTOBUF_NAMESPACE_ID::internal::DescriptorTable descriptor_table_google_2fprotobuf_2fany_2eproto; +PROTOBUF_NAMESPACE_OPEN +class Any; +struct AnyDefaultTypeInternal; +PROTOBUF_EXPORT extern AnyDefaultTypeInternal _Any_default_instance_; +PROTOBUF_NAMESPACE_CLOSE +PROTOBUF_NAMESPACE_OPEN +template<> PROTOBUF_EXPORT ::PROTOBUF_NAMESPACE_ID::Any* Arena::CreateMaybeMessage<::PROTOBUF_NAMESPACE_ID::Any>(Arena*); +PROTOBUF_NAMESPACE_CLOSE +PROTOBUF_NAMESPACE_OPEN + +// =================================================================== + +class PROTOBUF_EXPORT Any final : + public ::PROTOBUF_NAMESPACE_ID::Message /* @@protoc_insertion_point(class_definition:google.protobuf.Any) */ { + public: + inline Any() : Any(nullptr) {} + ~Any() override; + explicit constexpr Any(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized); + + Any(const Any& from); + Any(Any&& from) noexcept + : Any() { + *this = ::std::move(from); + } + + inline Any& operator=(const Any& from) { + CopyFrom(from); + return *this; + } + inline Any& operator=(Any&& from) noexcept { + if (this == &from) return *this; + if (GetOwningArena() == from.GetOwningArena() + #ifdef PROTOBUF_FORCE_COPY_IN_MOVE + && GetOwningArena() != nullptr + #endif // !PROTOBUF_FORCE_COPY_IN_MOVE + ) { + InternalSwap(&from); + } else { + CopyFrom(from); + } + return *this; + } + + static const ::PROTOBUF_NAMESPACE_ID::Descriptor* descriptor() { + return GetDescriptor(); + } + static const ::PROTOBUF_NAMESPACE_ID::Descriptor* GetDescriptor() { + return default_instance().GetMetadata().descriptor; + } + static const ::PROTOBUF_NAMESPACE_ID::Reflection* GetReflection() { + return default_instance().GetMetadata().reflection; + } + static const Any& default_instance() { + return *internal_default_instance(); + } + static inline const Any* internal_default_instance() { + return reinterpret_cast<const Any*>( + &_Any_default_instance_); + } + static constexpr int kIndexInFileMessages = + 0; + + // implements Any ----------------------------------------------- + + bool PackFrom(const ::PROTOBUF_NAMESPACE_ID::Message& message) { + return _any_metadata_.PackFrom(GetArena(), message); + } + bool PackFrom(const ::PROTOBUF_NAMESPACE_ID::Message& message, + ::PROTOBUF_NAMESPACE_ID::ConstStringParam type_url_prefix) { + return _any_metadata_.PackFrom(GetArena(), message, type_url_prefix); + } + bool UnpackTo(::PROTOBUF_NAMESPACE_ID::Message* message) const { + return _any_metadata_.UnpackTo(message); + } + static bool GetAnyFieldDescriptors( + const ::PROTOBUF_NAMESPACE_ID::Message& message, + const ::PROTOBUF_NAMESPACE_ID::FieldDescriptor** type_url_field, + const ::PROTOBUF_NAMESPACE_ID::FieldDescriptor** value_field); + template <typename T, class = typename std::enable_if<!std::is_convertible<T, const ::PROTOBUF_NAMESPACE_ID::Message&>::value>::type> + bool PackFrom(const T& message) { + return _any_metadata_.PackFrom<T>(GetArena(), message); + } + template <typename T, class = typename std::enable_if<!std::is_convertible<T, const ::PROTOBUF_NAMESPACE_ID::Message&>::value>::type> + bool PackFrom(const T& message, + ::PROTOBUF_NAMESPACE_ID::ConstStringParam type_url_prefix) { + return _any_metadata_.PackFrom<T>(GetArena(), message, type_url_prefix);} + template <typename T, class = typename std::enable_if<!std::is_convertible<T, const ::PROTOBUF_NAMESPACE_ID::Message&>::value>::type> + bool UnpackTo(T* message) const { + return _any_metadata_.UnpackTo<T>(message); + } + template<typename T> bool Is() const { + return _any_metadata_.Is<T>(); + } + static bool ParseAnyTypeUrl(::PROTOBUF_NAMESPACE_ID::ConstStringParam type_url, + TProtoStringType* full_type_name); + friend void swap(Any& a, Any& b) { + a.Swap(&b); + } + inline void Swap(Any* other) { + if (other == this) return; + #ifdef PROTOBUF_FORCE_COPY_IN_SWAP + if (GetOwningArena() != nullptr && + GetOwningArena() == other->GetOwningArena()) { + #else // PROTOBUF_FORCE_COPY_IN_SWAP + if (GetOwningArena() == other->GetOwningArena()) { + #endif // !PROTOBUF_FORCE_COPY_IN_SWAP + InternalSwap(other); + } else { + ::PROTOBUF_NAMESPACE_ID::internal::GenericSwap(this, other); + } + } + void UnsafeArenaSwap(Any* other) { + if (other == this) return; + GOOGLE_DCHECK(GetOwningArena() == other->GetOwningArena()); + InternalSwap(other); + } + + // implements Message ---------------------------------------------- + + Any* New(::PROTOBUF_NAMESPACE_ID::Arena* arena = nullptr) const final { + return CreateMaybeMessage<Any>(arena); + } + 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; + + size_t ByteSizeLong() const final; + const char* _InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) final; + uint8_t* _InternalSerialize( + uint8_t* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const final; + int GetCachedSize() const final { return _cached_size_.Get(); } + + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const final; + void InternalSwap(Any* other); + + private: + friend class ::PROTOBUF_NAMESPACE_ID::internal::AnyMetadata; + static ::PROTOBUF_NAMESPACE_ID::StringPiece FullMessageName() { + return "google.protobuf.Any"; + } + protected: + 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 ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + enum : int { + kTypeUrlFieldNumber = 1, + kValueFieldNumber = 2, + }; + // string type_url = 1; + void clear_type_url(); + const TProtoStringType& type_url() const; + template <typename ArgT0 = const TProtoStringType&, typename... ArgT> + void set_type_url(ArgT0&& arg0, ArgT... args); + TProtoStringType* mutable_type_url(); + PROTOBUF_NODISCARD TProtoStringType* release_type_url(); + void set_allocated_type_url(TProtoStringType* type_url); + private: + const TProtoStringType& _internal_type_url() const; + inline PROTOBUF_ALWAYS_INLINE void _internal_set_type_url(const TProtoStringType& value); + TProtoStringType* _internal_mutable_type_url(); + public: + + // bytes value = 2; + void clear_value(); + const TProtoStringType& value() const; + template <typename ArgT0 = const TProtoStringType&, typename... ArgT> + void set_value(ArgT0&& arg0, ArgT... args); + TProtoStringType* mutable_value(); + PROTOBUF_NODISCARD TProtoStringType* release_value(); + void set_allocated_value(TProtoStringType* value); + private: + const TProtoStringType& _internal_value() const; + inline PROTOBUF_ALWAYS_INLINE void _internal_set_value(const TProtoStringType& value); + TProtoStringType* _internal_mutable_value(); + public: + + // @@protoc_insertion_point(class_scope:google.protobuf.Any) + private: + class _Internal; + + template <typename T> friend class ::PROTOBUF_NAMESPACE_ID::Arena::InternalHelper; + typedef void InternalArenaConstructable_; + typedef void DestructorSkippable_; + ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr type_url_; + ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr value_; + mutable ::PROTOBUF_NAMESPACE_ID::internal::CachedSize _cached_size_; + ::PROTOBUF_NAMESPACE_ID::internal::AnyMetadata _any_metadata_; + friend struct ::TableStruct_google_2fprotobuf_2fany_2eproto; +}; +// =================================================================== + + +// =================================================================== + +#ifdef __GNUC__ + #pragma GCC diagnostic push + #pragma GCC diagnostic ignored "-Wstrict-aliasing" +#endif // __GNUC__ +// Any + +// string type_url = 1; +inline void Any::clear_type_url() { + type_url_.ClearToEmpty(); +} +inline const TProtoStringType& Any::type_url() const { + // @@protoc_insertion_point(field_get:google.protobuf.Any.type_url) + return _internal_type_url(); +} +template <typename ArgT0, typename... ArgT> +inline PROTOBUF_ALWAYS_INLINE +void Any::set_type_url(ArgT0&& arg0, ArgT... args) { + + type_url_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, static_cast<ArgT0 &&>(arg0), args..., GetArenaForAllocation()); + // @@protoc_insertion_point(field_set:google.protobuf.Any.type_url) +} +inline TProtoStringType* Any::mutable_type_url() { + TProtoStringType* _s = _internal_mutable_type_url(); + // @@protoc_insertion_point(field_mutable:google.protobuf.Any.type_url) + return _s; +} +inline const TProtoStringType& Any::_internal_type_url() const { + return type_url_.Get(); +} +inline void Any::_internal_set_type_url(const TProtoStringType& value) { + + type_url_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, value, GetArenaForAllocation()); +} +inline TProtoStringType* Any::_internal_mutable_type_url() { + + return type_url_.Mutable(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, GetArenaForAllocation()); +} +inline TProtoStringType* Any::release_type_url() { + // @@protoc_insertion_point(field_release:google.protobuf.Any.type_url) + return type_url_.Release(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArenaForAllocation()); +} +inline void Any::set_allocated_type_url(TProtoStringType* type_url) { + if (type_url != nullptr) { + + } else { + + } + type_url_.SetAllocated(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), type_url, + GetArenaForAllocation()); +#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING + if (type_url_.IsDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited())) { + type_url_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation()); + } +#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING + // @@protoc_insertion_point(field_set_allocated:google.protobuf.Any.type_url) +} + +// bytes value = 2; +inline void Any::clear_value() { + value_.ClearToEmpty(); +} +inline const TProtoStringType& Any::value() const { + // @@protoc_insertion_point(field_get:google.protobuf.Any.value) + return _internal_value(); +} +template <typename ArgT0, typename... ArgT> +inline PROTOBUF_ALWAYS_INLINE +void Any::set_value(ArgT0&& arg0, ArgT... args) { + + value_.SetBytes(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, static_cast<ArgT0 &&>(arg0), args..., GetArenaForAllocation()); + // @@protoc_insertion_point(field_set:google.protobuf.Any.value) +} +inline TProtoStringType* Any::mutable_value() { + TProtoStringType* _s = _internal_mutable_value(); + // @@protoc_insertion_point(field_mutable:google.protobuf.Any.value) + return _s; +} +inline const TProtoStringType& Any::_internal_value() const { + return value_.Get(); +} +inline void Any::_internal_set_value(const TProtoStringType& value) { + + value_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, value, GetArenaForAllocation()); +} +inline TProtoStringType* Any::_internal_mutable_value() { + + return value_.Mutable(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, GetArenaForAllocation()); +} +inline TProtoStringType* Any::release_value() { + // @@protoc_insertion_point(field_release:google.protobuf.Any.value) + return value_.Release(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArenaForAllocation()); +} +inline void Any::set_allocated_value(TProtoStringType* value) { + if (value != nullptr) { + + } else { + + } + value_.SetAllocated(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), value, + GetArenaForAllocation()); +#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING + if (value_.IsDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited())) { + value_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation()); + } +#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING + // @@protoc_insertion_point(field_set_allocated:google.protobuf.Any.value) +} + +#ifdef __GNUC__ + #pragma GCC diagnostic pop +#endif // __GNUC__ + +// @@protoc_insertion_point(namespace_scope) + +PROTOBUF_NAMESPACE_CLOSE + +// @@protoc_insertion_point(global_scope) + +#include <google/protobuf/port_undef.inc> +#endif // GOOGLE_PROTOBUF_INCLUDED_GOOGLE_PROTOBUF_INCLUDED_google_2fprotobuf_2fany_2eproto diff --git a/contrib/libs/protobuf_old/src/google/protobuf/any.proto b/contrib/libs/protobuf_old/src/google/protobuf/any.proto new file mode 100644 index 0000000000..6ed8a23cf5 --- /dev/null +++ b/contrib/libs/protobuf_old/src/google/protobuf/any.proto @@ -0,0 +1,158 @@ +// 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 google.protobuf; + +option csharp_namespace = "Google.Protobuf.WellKnownTypes"; +option go_package = "google.golang.org/protobuf/types/known/anypb"; +option java_package = "com.google.protobuf"; +option java_outer_classname = "AnyProto"; +option java_multiple_files = true; +option objc_class_prefix = "GPB"; + +// `Any` contains an arbitrary serialized protocol buffer message along with a +// URL that describes the type of the serialized message. +// +// Protobuf library provides support to pack/unpack Any values in the form +// of utility functions or additional generated methods of the Any type. +// +// Example 1: Pack and unpack a message in C++. +// +// Foo foo = ...; +// Any any; +// any.PackFrom(foo); +// ... +// if (any.UnpackTo(&foo)) { +// ... +// } +// +// Example 2: Pack and unpack a message in Java. +// +// Foo foo = ...; +// Any any = Any.pack(foo); +// ... +// if (any.is(Foo.class)) { +// foo = any.unpack(Foo.class); +// } +// +// Example 3: Pack and unpack a message in Python. +// +// foo = Foo(...) +// any = Any() +// any.Pack(foo) +// ... +// if any.Is(Foo.DESCRIPTOR): +// any.Unpack(foo) +// ... +// +// Example 4: Pack and unpack a message in Go +// +// foo := &pb.Foo{...} +// any, err := anypb.New(foo) +// if err != nil { +// ... +// } +// ... +// foo := &pb.Foo{} +// if err := any.UnmarshalTo(foo); err != nil { +// ... +// } +// +// The pack methods provided by protobuf library will by default use +// 'type.googleapis.com/full.type.name' as the type URL and the unpack +// methods only use the fully qualified type name after the last '/' +// in the type URL, for example "foo.bar.com/x/y.z" will yield type +// name "y.z". +// +// +// JSON +// ==== +// The JSON representation of an `Any` value uses the regular +// representation of the deserialized, embedded message, with an +// additional field `@type` which contains the type URL. Example: +// +// package google.profile; +// message Person { +// string first_name = 1; +// string last_name = 2; +// } +// +// { +// "@type": "type.googleapis.com/google.profile.Person", +// "firstName": <string>, +// "lastName": <string> +// } +// +// If the embedded message type is well-known and has a custom JSON +// representation, that representation will be embedded adding a field +// `value` which holds the custom JSON in addition to the `@type` +// field. Example (for message [google.protobuf.Duration][]): +// +// { +// "@type": "type.googleapis.com/google.protobuf.Duration", +// "value": "1.212s" +// } +// +message Any { + // A URL/resource name that uniquely identifies the type of the serialized + // protocol buffer message. This string must contain at least + // one "/" character. The last segment of the URL's path must represent + // the fully qualified name of the type (as in + // `path/google.protobuf.Duration`). The name should be in a canonical form + // (e.g., leading "." is not accepted). + // + // In practice, teams usually precompile into the binary all types that they + // expect it to use in the context of Any. However, for URLs which use the + // scheme `http`, `https`, or no scheme, one can optionally set up a type + // server that maps type URLs to message definitions as follows: + // + // * If no scheme is provided, `https` is assumed. + // * An HTTP GET on the URL must yield a [google.protobuf.Type][] + // value in binary format, or produce an error. + // * Applications are allowed to cache lookup results based on the + // URL, or have them precompiled into a binary to avoid any + // lookup. Therefore, binary compatibility needs to be preserved + // on changes to types. (Use versioned type names to manage + // breaking changes.) + // + // Note: this functionality is not currently available in the official + // protobuf release, and it is not used for type URLs beginning with + // type.googleapis.com. + // + // Schemes other than `http`, `https` (or the empty scheme) might be + // used with implementation specific semantics. + // + string type_url = 1; + + // Must be a valid serialized protocol buffer of the above specified type. + bytes value = 2; +} diff --git a/contrib/libs/protobuf_old/src/google/protobuf/any_lite.cc b/contrib/libs/protobuf_old/src/google/protobuf/any_lite.cc new file mode 100644 index 0000000000..5be2d7c401 --- /dev/null +++ b/contrib/libs/protobuf_old/src/google/protobuf/any_lite.cc @@ -0,0 +1,99 @@ +// 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 <google/protobuf/any.h> + +#include <google/protobuf/io/zero_copy_stream_impl_lite.h> +#include <google/protobuf/arenastring.h> +#include <google/protobuf/generated_message_util.h> +#include <google/protobuf/stubs/strutil.h> + +namespace google { +namespace protobuf { +namespace internal { + +TProtoStringType GetTypeUrl(StringPiece message_name, + StringPiece type_url_prefix) { + if (!type_url_prefix.empty() && + type_url_prefix[type_url_prefix.size() - 1] == '/') { + return StrCat(type_url_prefix, message_name); + } else { + return StrCat(type_url_prefix, "/", message_name); + } +} + +const char kAnyFullTypeName[] = "google.protobuf.Any"; +const char kTypeGoogleApisComPrefix[] = "type.googleapis.com/"; +const char kTypeGoogleProdComPrefix[] = "type.googleprod.com/"; + +bool AnyMetadata::InternalPackFrom(Arena* arena, const MessageLite& message, + StringPiece type_url_prefix, + StringPiece type_name) { + type_url_->Set(&::google::protobuf::internal::GetEmptyString(), + GetTypeUrl(type_name, type_url_prefix), arena); + return message.SerializeToString( + value_->Mutable(ArenaStringPtr::EmptyDefault{}, arena)); +} + +bool AnyMetadata::InternalUnpackTo(StringPiece type_name, + MessageLite* message) const { + if (!InternalIs(type_name)) { + return false; + } + return message->ParseFromString(value_->Get()); +} + +bool AnyMetadata::InternalIs(StringPiece type_name) const { + StringPiece type_url = type_url_->Get(); + return type_url.size() >= type_name.size() + 1 && + type_url[type_url.size() - type_name.size() - 1] == '/' && + HasSuffixString(type_url, type_name); +} + +bool ParseAnyTypeUrl(StringPiece type_url, TProtoStringType* url_prefix, + TProtoStringType* full_type_name) { + size_t pos = type_url.find_last_of('/'); + if (pos == TProtoStringType::npos || pos + 1 == type_url.size()) { + return false; + } + if (url_prefix) { + *url_prefix = TProtoStringType(type_url.substr(0, pos + 1)); + } + *full_type_name = TProtoStringType(type_url.substr(pos + 1)); + return true; +} + +bool ParseAnyTypeUrl(StringPiece type_url, TProtoStringType* full_type_name) { + return ParseAnyTypeUrl(type_url, nullptr, full_type_name); +} + +} // namespace internal +} // namespace protobuf +} // namespace google diff --git a/contrib/libs/protobuf_old/src/google/protobuf/api.pb.cc b/contrib/libs/protobuf_old/src/google/protobuf/api.pb.cc new file mode 100644 index 0000000000..bdaaa52ae1 --- /dev/null +++ b/contrib/libs/protobuf_old/src/google/protobuf/api.pb.cc @@ -0,0 +1,1291 @@ +// Generated by the protocol buffer compiler. DO NOT EDIT! +// source: google/protobuf/api.proto + +#include <google/protobuf/api.pb.h> + +#include <algorithm> + +#include <google/protobuf/io/coded_stream.h> +#include <google/protobuf/extension_set.h> +#include <google/protobuf/wire_format_lite.h> +#include <google/protobuf/descriptor.h> +#include <google/protobuf/generated_message_reflection.h> +#include <google/protobuf/reflection_ops.h> +#include <google/protobuf/wire_format.h> +// @@protoc_insertion_point(includes) +#include <google/protobuf/port_def.inc> + +PROTOBUF_PRAGMA_INIT_SEG +PROTOBUF_NAMESPACE_OPEN +constexpr Api::Api( + ::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized) + : methods_() + , options_() + , mixins_() + , name_(&::PROTOBUF_NAMESPACE_ID::internal::fixed_address_empty_string) + , version_(&::PROTOBUF_NAMESPACE_ID::internal::fixed_address_empty_string) + , source_context_(nullptr) + , syntax_(0) +{} +struct ApiDefaultTypeInternal { + constexpr ApiDefaultTypeInternal() + : _instance(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized{}) {} + ~ApiDefaultTypeInternal() {} + union { + Api _instance; + }; +}; +PROTOBUF_ATTRIBUTE_NO_DESTROY PROTOBUF_CONSTINIT ApiDefaultTypeInternal _Api_default_instance_; +constexpr Method::Method( + ::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized) + : options_() + , name_(&::PROTOBUF_NAMESPACE_ID::internal::fixed_address_empty_string) + , request_type_url_(&::PROTOBUF_NAMESPACE_ID::internal::fixed_address_empty_string) + , response_type_url_(&::PROTOBUF_NAMESPACE_ID::internal::fixed_address_empty_string) + , request_streaming_(false) + , response_streaming_(false) + , syntax_(0) +{} +struct MethodDefaultTypeInternal { + constexpr MethodDefaultTypeInternal() + : _instance(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized{}) {} + ~MethodDefaultTypeInternal() {} + union { + Method _instance; + }; +}; +PROTOBUF_ATTRIBUTE_NO_DESTROY PROTOBUF_CONSTINIT MethodDefaultTypeInternal _Method_default_instance_; +constexpr Mixin::Mixin( + ::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized) + : name_(&::PROTOBUF_NAMESPACE_ID::internal::fixed_address_empty_string) + , root_(&::PROTOBUF_NAMESPACE_ID::internal::fixed_address_empty_string){} +struct MixinDefaultTypeInternal { + constexpr MixinDefaultTypeInternal() + : _instance(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized{}) {} + ~MixinDefaultTypeInternal() {} + union { + Mixin _instance; + }; +}; +PROTOBUF_ATTRIBUTE_NO_DESTROY PROTOBUF_CONSTINIT MixinDefaultTypeInternal _Mixin_default_instance_; +PROTOBUF_NAMESPACE_CLOSE +static ::PROTOBUF_NAMESPACE_ID::Metadata file_level_metadata_google_2fprotobuf_2fapi_2eproto[3]; +static constexpr ::PROTOBUF_NAMESPACE_ID::EnumDescriptor const** file_level_enum_descriptors_google_2fprotobuf_2fapi_2eproto = nullptr; +static constexpr ::PROTOBUF_NAMESPACE_ID::ServiceDescriptor const** file_level_service_descriptors_google_2fprotobuf_2fapi_2eproto = nullptr; + +const arc_ui32 TableStruct_google_2fprotobuf_2fapi_2eproto::offsets[] PROTOBUF_SECTION_VARIABLE(protodesc_cold) = { + ~0u, // no _has_bits_ + PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::Api, _internal_metadata_), + ~0u, // no _extensions_ + ~0u, // no _oneof_case_ + ~0u, // no _weak_field_map_ + ~0u, // no _inlined_string_donated_ + PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::Api, name_), + PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::Api, methods_), + PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::Api, options_), + PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::Api, version_), + PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::Api, source_context_), + PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::Api, mixins_), + PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::Api, syntax_), + ~0u, // no _has_bits_ + PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::Method, _internal_metadata_), + ~0u, // no _extensions_ + ~0u, // no _oneof_case_ + ~0u, // no _weak_field_map_ + ~0u, // no _inlined_string_donated_ + PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::Method, name_), + PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::Method, request_type_url_), + PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::Method, request_streaming_), + PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::Method, response_type_url_), + PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::Method, response_streaming_), + PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::Method, options_), + PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::Method, syntax_), + ~0u, // no _has_bits_ + PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::Mixin, _internal_metadata_), + ~0u, // no _extensions_ + ~0u, // no _oneof_case_ + ~0u, // no _weak_field_map_ + ~0u, // no _inlined_string_donated_ + PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::Mixin, name_), + PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::Mixin, root_), +}; +static const ::PROTOBUF_NAMESPACE_ID::internal::MigrationSchema schemas[] PROTOBUF_SECTION_VARIABLE(protodesc_cold) = { + { 0, -1, -1, sizeof(::PROTOBUF_NAMESPACE_ID::Api)}, + { 13, -1, -1, sizeof(::PROTOBUF_NAMESPACE_ID::Method)}, + { 26, -1, -1, sizeof(::PROTOBUF_NAMESPACE_ID::Mixin)}, +}; + +static ::PROTOBUF_NAMESPACE_ID::Message const * const file_default_instances[] = { + reinterpret_cast<const ::PROTOBUF_NAMESPACE_ID::Message*>(&::PROTOBUF_NAMESPACE_ID::_Api_default_instance_), + reinterpret_cast<const ::PROTOBUF_NAMESPACE_ID::Message*>(&::PROTOBUF_NAMESPACE_ID::_Method_default_instance_), + reinterpret_cast<const ::PROTOBUF_NAMESPACE_ID::Message*>(&::PROTOBUF_NAMESPACE_ID::_Mixin_default_instance_), +}; + +const char descriptor_table_protodef_google_2fprotobuf_2fapi_2eproto[] PROTOBUF_SECTION_VARIABLE(protodesc_cold) = + "\n\031google/protobuf/api.proto\022\017google.prot" + "obuf\032$google/protobuf/source_context.pro" + "to\032\032google/protobuf/type.proto\"\201\002\n\003Api\022\014" + "\n\004name\030\001 \001(\t\022(\n\007methods\030\002 \003(\0132\027.google.p" + "rotobuf.Method\022(\n\007options\030\003 \003(\0132\027.google" + ".protobuf.Option\022\017\n\007version\030\004 \001(\t\0226\n\016sou" + "rce_context\030\005 \001(\0132\036.google.protobuf.Sour" + "ceContext\022&\n\006mixins\030\006 \003(\0132\026.google.proto" + "buf.Mixin\022\'\n\006syntax\030\007 \001(\0162\027.google.proto" + "buf.Syntax\"\325\001\n\006Method\022\014\n\004name\030\001 \001(\t\022\030\n\020r" + "equest_type_url\030\002 \001(\t\022\031\n\021request_streami" + "ng\030\003 \001(\010\022\031\n\021response_type_url\030\004 \001(\t\022\032\n\022r" + "esponse_streaming\030\005 \001(\010\022(\n\007options\030\006 \003(\013" + "2\027.google.protobuf.Option\022\'\n\006syntax\030\007 \001(" + "\0162\027.google.protobuf.Syntax\"#\n\005Mixin\022\014\n\004n" + "ame\030\001 \001(\t\022\014\n\004root\030\002 \001(\tBv\n\023com.google.pr" + "otobufB\010ApiProtoP\001Z,google.golang.org/pr" + "otobuf/types/known/apipb\242\002\003GPB\252\002\036Google." + "Protobuf.WellKnownTypesb\006proto3" + ; +static const ::PROTOBUF_NAMESPACE_ID::internal::DescriptorTable*const descriptor_table_google_2fprotobuf_2fapi_2eproto_deps[2] = { + &::descriptor_table_google_2fprotobuf_2fsource_5fcontext_2eproto, + &::descriptor_table_google_2fprotobuf_2ftype_2eproto, +}; +static ::PROTOBUF_NAMESPACE_ID::internal::once_flag descriptor_table_google_2fprotobuf_2fapi_2eproto_once; +const ::PROTOBUF_NAMESPACE_ID::internal::DescriptorTable descriptor_table_google_2fprotobuf_2fapi_2eproto = { + false, false, 751, descriptor_table_protodef_google_2fprotobuf_2fapi_2eproto, "google/protobuf/api.proto", + &descriptor_table_google_2fprotobuf_2fapi_2eproto_once, descriptor_table_google_2fprotobuf_2fapi_2eproto_deps, 2, 3, + schemas, file_default_instances, TableStruct_google_2fprotobuf_2fapi_2eproto::offsets, + file_level_metadata_google_2fprotobuf_2fapi_2eproto, file_level_enum_descriptors_google_2fprotobuf_2fapi_2eproto, file_level_service_descriptors_google_2fprotobuf_2fapi_2eproto, +}; +PROTOBUF_ATTRIBUTE_WEAK const ::PROTOBUF_NAMESPACE_ID::internal::DescriptorTable* descriptor_table_google_2fprotobuf_2fapi_2eproto_getter() { + return &descriptor_table_google_2fprotobuf_2fapi_2eproto; +} + +// Force running AddDescriptors() at dynamic initialization time. +PROTOBUF_ATTRIBUTE_INIT_PRIORITY static ::PROTOBUF_NAMESPACE_ID::internal::AddDescriptorsRunner dynamic_init_dummy_google_2fprotobuf_2fapi_2eproto(&descriptor_table_google_2fprotobuf_2fapi_2eproto); +PROTOBUF_NAMESPACE_OPEN + +// =================================================================== + +class Api::_Internal { + public: + static const ::PROTOBUF_NAMESPACE_ID::SourceContext& source_context(const Api* msg); +}; + +const ::PROTOBUF_NAMESPACE_ID::SourceContext& +Api::_Internal::source_context(const Api* msg) { + return *msg->source_context_; +} +void Api::clear_options() { + options_.Clear(); +} +void Api::clear_source_context() { + if (GetArenaForAllocation() == nullptr && source_context_ != nullptr) { + delete source_context_; + } + source_context_ = nullptr; +} +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(); + if (!is_message_owned) { + RegisterArenaDtor(arena); + } + // @@protoc_insertion_point(arena_constructor:google.protobuf.Api) +} +Api::Api(const Api& from) + : ::PROTOBUF_NAMESPACE_ID::Message(), + methods_(from.methods_), + options_(from.options_), + mixins_(from.mixins_) { + _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_); + name_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); + #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING + name_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation()); + #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING + if (!from._internal_name().empty()) { + name_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, from._internal_name(), + GetArenaForAllocation()); + } + version_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); + #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING + version_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation()); + #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING + if (!from._internal_version().empty()) { + version_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, from._internal_version(), + GetArenaForAllocation()); + } + if (from._internal_has_source_context()) { + source_context_ = new ::PROTOBUF_NAMESPACE_ID::SourceContext(*from.source_context_); + } else { + source_context_ = nullptr; + } + syntax_ = from.syntax_; + // @@protoc_insertion_point(copy_constructor:google.protobuf.Api) +} + +inline void Api::SharedCtor() { +name_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); +#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING + name_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation()); +#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING +version_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); +#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING + version_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation()); +#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING +::memset(reinterpret_cast<char*>(this) + static_cast<size_t>( + reinterpret_cast<char*>(&source_context_) - reinterpret_cast<char*>(this)), + 0, static_cast<size_t>(reinterpret_cast<char*>(&syntax_) - + reinterpret_cast<char*>(&source_context_)) + sizeof(syntax_)); +} + +Api::~Api() { + // @@protoc_insertion_point(destructor:google.protobuf.Api) + if (GetArenaForAllocation() != nullptr) return; + SharedDtor(); + _internal_metadata_.Delete<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(); +} + +inline void Api::SharedDtor() { + GOOGLE_DCHECK(GetArenaForAllocation() == nullptr); + name_.DestroyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); + version_.DestroyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); + if (this != internal_default_instance()) delete source_context_; +} + +void Api::ArenaDtor(void* object) { + Api* _this = reinterpret_cast< Api* >(object); + (void)_this; +} +void Api::RegisterArenaDtor(::PROTOBUF_NAMESPACE_ID::Arena*) { +} +void Api::SetCachedSize(int size) const { + _cached_size_.Set(size); +} + +void Api::Clear() { +// @@protoc_insertion_point(message_clear_start:google.protobuf.Api) + arc_ui32 cached_has_bits = 0; + // Prevent compiler warnings about cached_has_bits being unused + (void) cached_has_bits; + + methods_.Clear(); + options_.Clear(); + mixins_.Clear(); + name_.ClearToEmpty(); + version_.ClearToEmpty(); + if (GetArenaForAllocation() == nullptr && source_context_ != nullptr) { + delete source_context_; + } + source_context_ = nullptr; + syntax_ = 0; + _internal_metadata_.Clear<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(); +} + +const char* Api::_InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) { +#define CHK_(x) if (PROTOBUF_PREDICT_FALSE(!(x))) goto failure + while (!ctx->Done(&ptr)) { + arc_ui32 tag; + ptr = ::PROTOBUF_NAMESPACE_ID::internal::ReadTag(ptr, &tag); + switch (tag >> 3) { + // string name = 1; + case 1: + if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 10)) { + auto str = _internal_mutable_name(); + ptr = ::PROTOBUF_NAMESPACE_ID::internal::InlineGreedyStringParser(str, ptr, ctx); + CHK_(::PROTOBUF_NAMESPACE_ID::internal::VerifyUTF8(str, "google.protobuf.Api.name")); + CHK_(ptr); + } else + goto handle_unusual; + continue; + // repeated .google.protobuf.Method methods = 2; + case 2: + if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 18)) { + ptr -= 1; + do { + ptr += 1; + ptr = ctx->ParseMessage(_internal_add_methods(), ptr); + CHK_(ptr); + if (!ctx->DataAvailable(ptr)) break; + } while (::PROTOBUF_NAMESPACE_ID::internal::ExpectTag<18>(ptr)); + } else + goto handle_unusual; + continue; + // repeated .google.protobuf.Option options = 3; + case 3: + if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 26)) { + ptr -= 1; + do { + ptr += 1; + ptr = ctx->ParseMessage(_internal_add_options(), ptr); + CHK_(ptr); + if (!ctx->DataAvailable(ptr)) break; + } while (::PROTOBUF_NAMESPACE_ID::internal::ExpectTag<26>(ptr)); + } else + goto handle_unusual; + continue; + // string version = 4; + case 4: + if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 34)) { + auto str = _internal_mutable_version(); + ptr = ::PROTOBUF_NAMESPACE_ID::internal::InlineGreedyStringParser(str, ptr, ctx); + CHK_(::PROTOBUF_NAMESPACE_ID::internal::VerifyUTF8(str, "google.protobuf.Api.version")); + CHK_(ptr); + } else + goto handle_unusual; + continue; + // .google.protobuf.SourceContext source_context = 5; + case 5: + if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 42)) { + ptr = ctx->ParseMessage(_internal_mutable_source_context(), ptr); + CHK_(ptr); + } else + goto handle_unusual; + continue; + // repeated .google.protobuf.Mixin mixins = 6; + case 6: + if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 50)) { + ptr -= 1; + do { + ptr += 1; + ptr = ctx->ParseMessage(_internal_add_mixins(), ptr); + CHK_(ptr); + if (!ctx->DataAvailable(ptr)) break; + } while (::PROTOBUF_NAMESPACE_ID::internal::ExpectTag<50>(ptr)); + } else + goto handle_unusual; + continue; + // .google.protobuf.Syntax syntax = 7; + case 7: + if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 56)) { + arc_ui64 val = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint64(&ptr); + CHK_(ptr); + _internal_set_syntax(static_cast<::PROTOBUF_NAMESPACE_ID::Syntax>(val)); + } else + goto handle_unusual; + continue; + default: + goto handle_unusual; + } // switch + handle_unusual: + if ((tag == 0) || ((tag & 7) == 4)) { + CHK_(ptr); + ctx->SetLastTag(tag); + goto message_done; + } + ptr = UnknownFieldParse( + tag, + _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(), + ptr, ctx); + CHK_(ptr != nullptr); + } // while +message_done: + return ptr; +failure: + ptr = nullptr; + goto message_done; +#undef CHK_ +} + +uint8_t* Api::_InternalSerialize( + uint8_t* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const { + // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.Api) + arc_ui32 cached_has_bits = 0; + (void) cached_has_bits; + + // string name = 1; + if (!this->_internal_name().empty()) { + ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::VerifyUtf8String( + this->_internal_name().data(), static_cast<int>(this->_internal_name().length()), + ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::SERIALIZE, + "google.protobuf.Api.name"); + target = stream->WriteStringMaybeAliased( + 1, this->_internal_name(), target); + } + + // repeated .google.protobuf.Method methods = 2; + for (unsigned int i = 0, + n = static_cast<unsigned int>(this->_internal_methods_size()); i < n; i++) { + target = stream->EnsureSpace(target); + target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite:: + InternalWriteMessage(2, this->_internal_methods(i), target, stream); + } + + // repeated .google.protobuf.Option options = 3; + for (unsigned int i = 0, + n = static_cast<unsigned int>(this->_internal_options_size()); i < n; i++) { + target = stream->EnsureSpace(target); + target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite:: + InternalWriteMessage(3, this->_internal_options(i), target, stream); + } + + // string version = 4; + if (!this->_internal_version().empty()) { + ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::VerifyUtf8String( + this->_internal_version().data(), static_cast<int>(this->_internal_version().length()), + ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::SERIALIZE, + "google.protobuf.Api.version"); + target = stream->WriteStringMaybeAliased( + 4, this->_internal_version(), target); + } + + // .google.protobuf.SourceContext source_context = 5; + if (this->_internal_has_source_context()) { + target = stream->EnsureSpace(target); + target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite:: + InternalWriteMessage( + 5, _Internal::source_context(this), target, stream); + } + + // repeated .google.protobuf.Mixin mixins = 6; + for (unsigned int i = 0, + n = static_cast<unsigned int>(this->_internal_mixins_size()); i < n; i++) { + target = stream->EnsureSpace(target); + target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite:: + InternalWriteMessage(6, this->_internal_mixins(i), target, stream); + } + + // .google.protobuf.Syntax syntax = 7; + if (this->_internal_syntax() != 0) { + target = stream->EnsureSpace(target); + target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteEnumToArray( + 7, this->_internal_syntax(), target); + } + + if (PROTOBUF_PREDICT_FALSE(_internal_metadata_.have_unknown_fields())) { + target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::InternalSerializeUnknownFieldsToArray( + _internal_metadata_.unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(::PROTOBUF_NAMESPACE_ID::UnknownFieldSet::default_instance), target, stream); + } + // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.Api) + return target; +} + +size_t Api::ByteSizeLong() const { +// @@protoc_insertion_point(message_byte_size_start:google.protobuf.Api) + size_t total_size = 0; + + arc_ui32 cached_has_bits = 0; + // Prevent compiler warnings about cached_has_bits being unused + (void) cached_has_bits; + + // repeated .google.protobuf.Method methods = 2; + total_size += 1UL * this->_internal_methods_size(); + for (const auto& msg : this->methods_) { + total_size += + ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::MessageSize(msg); + } + + // repeated .google.protobuf.Option options = 3; + total_size += 1UL * this->_internal_options_size(); + for (const auto& msg : this->options_) { + total_size += + ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::MessageSize(msg); + } + + // repeated .google.protobuf.Mixin mixins = 6; + total_size += 1UL * this->_internal_mixins_size(); + for (const auto& msg : this->mixins_) { + total_size += + ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::MessageSize(msg); + } + + // string name = 1; + if (!this->_internal_name().empty()) { + total_size += 1 + + ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::StringSize( + this->_internal_name()); + } + + // string version = 4; + if (!this->_internal_version().empty()) { + total_size += 1 + + ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::StringSize( + this->_internal_version()); + } + + // .google.protobuf.SourceContext source_context = 5; + if (this->_internal_has_source_context()) { + total_size += 1 + + ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::MessageSize( + *source_context_); + } + + // .google.protobuf.Syntax syntax = 7; + if (this->_internal_syntax() != 0) { + total_size += 1 + + ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::EnumSize(this->_internal_syntax()); + } + + return MaybeComputeUnknownFieldsSize(total_size, &_cached_size_); +} + +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); + arc_ui32 cached_has_bits = 0; + (void) cached_has_bits; + + methods_.MergeFrom(from.methods_); + options_.MergeFrom(from.options_); + mixins_.MergeFrom(from.mixins_); + if (!from._internal_name().empty()) { + _internal_set_name(from._internal_name()); + } + if (!from._internal_version().empty()) { + _internal_set_version(from._internal_version()); + } + if (from._internal_has_source_context()) { + _internal_mutable_source_context()->::PROTOBUF_NAMESPACE_ID::SourceContext::MergeFrom(from._internal_source_context()); + } + if (from._internal_syntax() != 0) { + _internal_set_syntax(from._internal_syntax()); + } + _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_); +} + +void Api::CopyFrom(const Api& from) { +// @@protoc_insertion_point(class_specific_copy_from_start:google.protobuf.Api) + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool Api::IsInitialized() const { + return true; +} + +void Api::InternalSwap(Api* other) { + using std::swap; + auto* lhs_arena = GetArenaForAllocation(); + auto* rhs_arena = other->GetArenaForAllocation(); + _internal_metadata_.InternalSwap(&other->_internal_metadata_); + methods_.InternalSwap(&other->methods_); + options_.InternalSwap(&other->options_); + mixins_.InternalSwap(&other->mixins_); + ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::InternalSwap( + &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), + &name_, lhs_arena, + &other->name_, rhs_arena + ); + ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::InternalSwap( + &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), + &version_, lhs_arena, + &other->version_, rhs_arena + ); + ::PROTOBUF_NAMESPACE_ID::internal::memswap< + PROTOBUF_FIELD_OFFSET(Api, syntax_) + + sizeof(Api::syntax_) + - PROTOBUF_FIELD_OFFSET(Api, source_context_)>( + reinterpret_cast<char*>(&source_context_), + reinterpret_cast<char*>(&other->source_context_)); +} + +::PROTOBUF_NAMESPACE_ID::Metadata Api::GetMetadata() const { + return ::PROTOBUF_NAMESPACE_ID::internal::AssignDescriptors( + &descriptor_table_google_2fprotobuf_2fapi_2eproto_getter, &descriptor_table_google_2fprotobuf_2fapi_2eproto_once, + file_level_metadata_google_2fprotobuf_2fapi_2eproto[0]); +} + +// =================================================================== + +class Method::_Internal { + public: +}; + +void Method::clear_options() { + options_.Clear(); +} +Method::Method(::PROTOBUF_NAMESPACE_ID::Arena* arena, + bool is_message_owned) + : ::PROTOBUF_NAMESPACE_ID::Message(arena, is_message_owned), + options_(arena) { + SharedCtor(); + if (!is_message_owned) { + RegisterArenaDtor(arena); + } + // @@protoc_insertion_point(arena_constructor:google.protobuf.Method) +} +Method::Method(const Method& from) + : ::PROTOBUF_NAMESPACE_ID::Message(), + options_(from.options_) { + _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_); + name_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); + #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING + name_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation()); + #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING + if (!from._internal_name().empty()) { + name_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, from._internal_name(), + GetArenaForAllocation()); + } + request_type_url_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); + #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING + request_type_url_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation()); + #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING + if (!from._internal_request_type_url().empty()) { + request_type_url_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, from._internal_request_type_url(), + GetArenaForAllocation()); + } + response_type_url_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); + #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING + response_type_url_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation()); + #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING + if (!from._internal_response_type_url().empty()) { + response_type_url_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, from._internal_response_type_url(), + GetArenaForAllocation()); + } + ::memcpy(&request_streaming_, &from.request_streaming_, + static_cast<size_t>(reinterpret_cast<char*>(&syntax_) - + reinterpret_cast<char*>(&request_streaming_)) + sizeof(syntax_)); + // @@protoc_insertion_point(copy_constructor:google.protobuf.Method) +} + +inline void Method::SharedCtor() { +name_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); +#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING + name_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation()); +#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING +request_type_url_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); +#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING + request_type_url_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation()); +#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING +response_type_url_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); +#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING + response_type_url_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation()); +#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING +::memset(reinterpret_cast<char*>(this) + static_cast<size_t>( + reinterpret_cast<char*>(&request_streaming_) - reinterpret_cast<char*>(this)), + 0, static_cast<size_t>(reinterpret_cast<char*>(&syntax_) - + reinterpret_cast<char*>(&request_streaming_)) + sizeof(syntax_)); +} + +Method::~Method() { + // @@protoc_insertion_point(destructor:google.protobuf.Method) + if (GetArenaForAllocation() != nullptr) return; + SharedDtor(); + _internal_metadata_.Delete<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(); +} + +inline void Method::SharedDtor() { + GOOGLE_DCHECK(GetArenaForAllocation() == nullptr); + name_.DestroyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); + request_type_url_.DestroyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); + response_type_url_.DestroyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); +} + +void Method::ArenaDtor(void* object) { + Method* _this = reinterpret_cast< Method* >(object); + (void)_this; +} +void Method::RegisterArenaDtor(::PROTOBUF_NAMESPACE_ID::Arena*) { +} +void Method::SetCachedSize(int size) const { + _cached_size_.Set(size); +} + +void Method::Clear() { +// @@protoc_insertion_point(message_clear_start:google.protobuf.Method) + arc_ui32 cached_has_bits = 0; + // Prevent compiler warnings about cached_has_bits being unused + (void) cached_has_bits; + + options_.Clear(); + name_.ClearToEmpty(); + request_type_url_.ClearToEmpty(); + response_type_url_.ClearToEmpty(); + ::memset(&request_streaming_, 0, static_cast<size_t>( + reinterpret_cast<char*>(&syntax_) - + reinterpret_cast<char*>(&request_streaming_)) + sizeof(syntax_)); + _internal_metadata_.Clear<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(); +} + +const char* Method::_InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) { +#define CHK_(x) if (PROTOBUF_PREDICT_FALSE(!(x))) goto failure + while (!ctx->Done(&ptr)) { + arc_ui32 tag; + ptr = ::PROTOBUF_NAMESPACE_ID::internal::ReadTag(ptr, &tag); + switch (tag >> 3) { + // string name = 1; + case 1: + if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 10)) { + auto str = _internal_mutable_name(); + ptr = ::PROTOBUF_NAMESPACE_ID::internal::InlineGreedyStringParser(str, ptr, ctx); + CHK_(::PROTOBUF_NAMESPACE_ID::internal::VerifyUTF8(str, "google.protobuf.Method.name")); + CHK_(ptr); + } else + goto handle_unusual; + continue; + // string request_type_url = 2; + case 2: + if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 18)) { + auto str = _internal_mutable_request_type_url(); + ptr = ::PROTOBUF_NAMESPACE_ID::internal::InlineGreedyStringParser(str, ptr, ctx); + CHK_(::PROTOBUF_NAMESPACE_ID::internal::VerifyUTF8(str, "google.protobuf.Method.request_type_url")); + CHK_(ptr); + } else + goto handle_unusual; + continue; + // bool request_streaming = 3; + case 3: + if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 24)) { + request_streaming_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint64(&ptr); + CHK_(ptr); + } else + goto handle_unusual; + continue; + // string response_type_url = 4; + case 4: + if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 34)) { + auto str = _internal_mutable_response_type_url(); + ptr = ::PROTOBUF_NAMESPACE_ID::internal::InlineGreedyStringParser(str, ptr, ctx); + CHK_(::PROTOBUF_NAMESPACE_ID::internal::VerifyUTF8(str, "google.protobuf.Method.response_type_url")); + CHK_(ptr); + } else + goto handle_unusual; + continue; + // bool response_streaming = 5; + case 5: + if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 40)) { + response_streaming_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint64(&ptr); + CHK_(ptr); + } else + goto handle_unusual; + continue; + // repeated .google.protobuf.Option options = 6; + case 6: + if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 50)) { + ptr -= 1; + do { + ptr += 1; + ptr = ctx->ParseMessage(_internal_add_options(), ptr); + CHK_(ptr); + if (!ctx->DataAvailable(ptr)) break; + } while (::PROTOBUF_NAMESPACE_ID::internal::ExpectTag<50>(ptr)); + } else + goto handle_unusual; + continue; + // .google.protobuf.Syntax syntax = 7; + case 7: + if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 56)) { + arc_ui64 val = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint64(&ptr); + CHK_(ptr); + _internal_set_syntax(static_cast<::PROTOBUF_NAMESPACE_ID::Syntax>(val)); + } else + goto handle_unusual; + continue; + default: + goto handle_unusual; + } // switch + handle_unusual: + if ((tag == 0) || ((tag & 7) == 4)) { + CHK_(ptr); + ctx->SetLastTag(tag); + goto message_done; + } + ptr = UnknownFieldParse( + tag, + _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(), + ptr, ctx); + CHK_(ptr != nullptr); + } // while +message_done: + return ptr; +failure: + ptr = nullptr; + goto message_done; +#undef CHK_ +} + +uint8_t* Method::_InternalSerialize( + uint8_t* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const { + // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.Method) + arc_ui32 cached_has_bits = 0; + (void) cached_has_bits; + + // string name = 1; + if (!this->_internal_name().empty()) { + ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::VerifyUtf8String( + this->_internal_name().data(), static_cast<int>(this->_internal_name().length()), + ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::SERIALIZE, + "google.protobuf.Method.name"); + target = stream->WriteStringMaybeAliased( + 1, this->_internal_name(), target); + } + + // string request_type_url = 2; + if (!this->_internal_request_type_url().empty()) { + ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::VerifyUtf8String( + this->_internal_request_type_url().data(), static_cast<int>(this->_internal_request_type_url().length()), + ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::SERIALIZE, + "google.protobuf.Method.request_type_url"); + target = stream->WriteStringMaybeAliased( + 2, this->_internal_request_type_url(), target); + } + + // bool request_streaming = 3; + if (this->_internal_request_streaming() != 0) { + target = stream->EnsureSpace(target); + target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteBoolToArray(3, this->_internal_request_streaming(), target); + } + + // string response_type_url = 4; + if (!this->_internal_response_type_url().empty()) { + ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::VerifyUtf8String( + this->_internal_response_type_url().data(), static_cast<int>(this->_internal_response_type_url().length()), + ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::SERIALIZE, + "google.protobuf.Method.response_type_url"); + target = stream->WriteStringMaybeAliased( + 4, this->_internal_response_type_url(), target); + } + + // bool response_streaming = 5; + if (this->_internal_response_streaming() != 0) { + target = stream->EnsureSpace(target); + target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteBoolToArray(5, this->_internal_response_streaming(), target); + } + + // repeated .google.protobuf.Option options = 6; + for (unsigned int i = 0, + n = static_cast<unsigned int>(this->_internal_options_size()); i < n; i++) { + target = stream->EnsureSpace(target); + target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite:: + InternalWriteMessage(6, this->_internal_options(i), target, stream); + } + + // .google.protobuf.Syntax syntax = 7; + if (this->_internal_syntax() != 0) { + target = stream->EnsureSpace(target); + target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteEnumToArray( + 7, this->_internal_syntax(), target); + } + + if (PROTOBUF_PREDICT_FALSE(_internal_metadata_.have_unknown_fields())) { + target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::InternalSerializeUnknownFieldsToArray( + _internal_metadata_.unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(::PROTOBUF_NAMESPACE_ID::UnknownFieldSet::default_instance), target, stream); + } + // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.Method) + return target; +} + +size_t Method::ByteSizeLong() const { +// @@protoc_insertion_point(message_byte_size_start:google.protobuf.Method) + size_t total_size = 0; + + arc_ui32 cached_has_bits = 0; + // Prevent compiler warnings about cached_has_bits being unused + (void) cached_has_bits; + + // repeated .google.protobuf.Option options = 6; + total_size += 1UL * this->_internal_options_size(); + for (const auto& msg : this->options_) { + total_size += + ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::MessageSize(msg); + } + + // string name = 1; + if (!this->_internal_name().empty()) { + total_size += 1 + + ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::StringSize( + this->_internal_name()); + } + + // string request_type_url = 2; + if (!this->_internal_request_type_url().empty()) { + total_size += 1 + + ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::StringSize( + this->_internal_request_type_url()); + } + + // string response_type_url = 4; + if (!this->_internal_response_type_url().empty()) { + total_size += 1 + + ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::StringSize( + this->_internal_response_type_url()); + } + + // bool request_streaming = 3; + if (this->_internal_request_streaming() != 0) { + total_size += 1 + 1; + } + + // bool response_streaming = 5; + if (this->_internal_response_streaming() != 0) { + total_size += 1 + 1; + } + + // .google.protobuf.Syntax syntax = 7; + if (this->_internal_syntax() != 0) { + total_size += 1 + + ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::EnumSize(this->_internal_syntax()); + } + + return MaybeComputeUnknownFieldsSize(total_size, &_cached_size_); +} + +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); + arc_ui32 cached_has_bits = 0; + (void) cached_has_bits; + + options_.MergeFrom(from.options_); + if (!from._internal_name().empty()) { + _internal_set_name(from._internal_name()); + } + if (!from._internal_request_type_url().empty()) { + _internal_set_request_type_url(from._internal_request_type_url()); + } + if (!from._internal_response_type_url().empty()) { + _internal_set_response_type_url(from._internal_response_type_url()); + } + if (from._internal_request_streaming() != 0) { + _internal_set_request_streaming(from._internal_request_streaming()); + } + if (from._internal_response_streaming() != 0) { + _internal_set_response_streaming(from._internal_response_streaming()); + } + if (from._internal_syntax() != 0) { + _internal_set_syntax(from._internal_syntax()); + } + _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_); +} + +void Method::CopyFrom(const Method& from) { +// @@protoc_insertion_point(class_specific_copy_from_start:google.protobuf.Method) + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool Method::IsInitialized() const { + return true; +} + +void Method::InternalSwap(Method* other) { + using std::swap; + auto* lhs_arena = GetArenaForAllocation(); + auto* rhs_arena = other->GetArenaForAllocation(); + _internal_metadata_.InternalSwap(&other->_internal_metadata_); + options_.InternalSwap(&other->options_); + ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::InternalSwap( + &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), + &name_, lhs_arena, + &other->name_, rhs_arena + ); + ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::InternalSwap( + &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), + &request_type_url_, lhs_arena, + &other->request_type_url_, rhs_arena + ); + ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::InternalSwap( + &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), + &response_type_url_, lhs_arena, + &other->response_type_url_, rhs_arena + ); + ::PROTOBUF_NAMESPACE_ID::internal::memswap< + PROTOBUF_FIELD_OFFSET(Method, syntax_) + + sizeof(Method::syntax_) + - PROTOBUF_FIELD_OFFSET(Method, request_streaming_)>( + reinterpret_cast<char*>(&request_streaming_), + reinterpret_cast<char*>(&other->request_streaming_)); +} + +::PROTOBUF_NAMESPACE_ID::Metadata Method::GetMetadata() const { + return ::PROTOBUF_NAMESPACE_ID::internal::AssignDescriptors( + &descriptor_table_google_2fprotobuf_2fapi_2eproto_getter, &descriptor_table_google_2fprotobuf_2fapi_2eproto_once, + file_level_metadata_google_2fprotobuf_2fapi_2eproto[1]); +} + +// =================================================================== + +class Mixin::_Internal { + public: +}; + +Mixin::Mixin(::PROTOBUF_NAMESPACE_ID::Arena* arena, + bool is_message_owned) + : ::PROTOBUF_NAMESPACE_ID::Message(arena, is_message_owned) { + SharedCtor(); + if (!is_message_owned) { + RegisterArenaDtor(arena); + } + // @@protoc_insertion_point(arena_constructor:google.protobuf.Mixin) +} +Mixin::Mixin(const Mixin& from) + : ::PROTOBUF_NAMESPACE_ID::Message() { + _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_); + name_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); + #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING + name_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation()); + #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING + if (!from._internal_name().empty()) { + name_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, from._internal_name(), + GetArenaForAllocation()); + } + root_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); + #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING + root_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation()); + #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING + if (!from._internal_root().empty()) { + root_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, from._internal_root(), + GetArenaForAllocation()); + } + // @@protoc_insertion_point(copy_constructor:google.protobuf.Mixin) +} + +inline void Mixin::SharedCtor() { +name_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); +#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING + name_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation()); +#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING +root_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); +#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING + root_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation()); +#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING +} + +Mixin::~Mixin() { + // @@protoc_insertion_point(destructor:google.protobuf.Mixin) + if (GetArenaForAllocation() != nullptr) return; + SharedDtor(); + _internal_metadata_.Delete<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(); +} + +inline void Mixin::SharedDtor() { + GOOGLE_DCHECK(GetArenaForAllocation() == nullptr); + name_.DestroyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); + root_.DestroyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); +} + +void Mixin::ArenaDtor(void* object) { + Mixin* _this = reinterpret_cast< Mixin* >(object); + (void)_this; +} +void Mixin::RegisterArenaDtor(::PROTOBUF_NAMESPACE_ID::Arena*) { +} +void Mixin::SetCachedSize(int size) const { + _cached_size_.Set(size); +} + +void Mixin::Clear() { +// @@protoc_insertion_point(message_clear_start:google.protobuf.Mixin) + arc_ui32 cached_has_bits = 0; + // Prevent compiler warnings about cached_has_bits being unused + (void) cached_has_bits; + + name_.ClearToEmpty(); + root_.ClearToEmpty(); + _internal_metadata_.Clear<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(); +} + +const char* Mixin::_InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) { +#define CHK_(x) if (PROTOBUF_PREDICT_FALSE(!(x))) goto failure + while (!ctx->Done(&ptr)) { + arc_ui32 tag; + ptr = ::PROTOBUF_NAMESPACE_ID::internal::ReadTag(ptr, &tag); + switch (tag >> 3) { + // string name = 1; + case 1: + if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 10)) { + auto str = _internal_mutable_name(); + ptr = ::PROTOBUF_NAMESPACE_ID::internal::InlineGreedyStringParser(str, ptr, ctx); + CHK_(::PROTOBUF_NAMESPACE_ID::internal::VerifyUTF8(str, "google.protobuf.Mixin.name")); + CHK_(ptr); + } else + goto handle_unusual; + continue; + // string root = 2; + case 2: + if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 18)) { + auto str = _internal_mutable_root(); + ptr = ::PROTOBUF_NAMESPACE_ID::internal::InlineGreedyStringParser(str, ptr, ctx); + CHK_(::PROTOBUF_NAMESPACE_ID::internal::VerifyUTF8(str, "google.protobuf.Mixin.root")); + CHK_(ptr); + } else + goto handle_unusual; + continue; + default: + goto handle_unusual; + } // switch + handle_unusual: + if ((tag == 0) || ((tag & 7) == 4)) { + CHK_(ptr); + ctx->SetLastTag(tag); + goto message_done; + } + ptr = UnknownFieldParse( + tag, + _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(), + ptr, ctx); + CHK_(ptr != nullptr); + } // while +message_done: + return ptr; +failure: + ptr = nullptr; + goto message_done; +#undef CHK_ +} + +uint8_t* Mixin::_InternalSerialize( + uint8_t* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const { + // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.Mixin) + arc_ui32 cached_has_bits = 0; + (void) cached_has_bits; + + // string name = 1; + if (!this->_internal_name().empty()) { + ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::VerifyUtf8String( + this->_internal_name().data(), static_cast<int>(this->_internal_name().length()), + ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::SERIALIZE, + "google.protobuf.Mixin.name"); + target = stream->WriteStringMaybeAliased( + 1, this->_internal_name(), target); + } + + // string root = 2; + if (!this->_internal_root().empty()) { + ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::VerifyUtf8String( + this->_internal_root().data(), static_cast<int>(this->_internal_root().length()), + ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::SERIALIZE, + "google.protobuf.Mixin.root"); + target = stream->WriteStringMaybeAliased( + 2, this->_internal_root(), target); + } + + if (PROTOBUF_PREDICT_FALSE(_internal_metadata_.have_unknown_fields())) { + target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::InternalSerializeUnknownFieldsToArray( + _internal_metadata_.unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(::PROTOBUF_NAMESPACE_ID::UnknownFieldSet::default_instance), target, stream); + } + // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.Mixin) + return target; +} + +size_t Mixin::ByteSizeLong() const { +// @@protoc_insertion_point(message_byte_size_start:google.protobuf.Mixin) + size_t total_size = 0; + + arc_ui32 cached_has_bits = 0; + // Prevent compiler warnings about cached_has_bits being unused + (void) cached_has_bits; + + // string name = 1; + if (!this->_internal_name().empty()) { + total_size += 1 + + ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::StringSize( + this->_internal_name()); + } + + // string root = 2; + if (!this->_internal_root().empty()) { + total_size += 1 + + ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::StringSize( + this->_internal_root()); + } + + return MaybeComputeUnknownFieldsSize(total_size, &_cached_size_); +} + +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); + arc_ui32 cached_has_bits = 0; + (void) cached_has_bits; + + if (!from._internal_name().empty()) { + _internal_set_name(from._internal_name()); + } + if (!from._internal_root().empty()) { + _internal_set_root(from._internal_root()); + } + _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_); +} + +void Mixin::CopyFrom(const Mixin& from) { +// @@protoc_insertion_point(class_specific_copy_from_start:google.protobuf.Mixin) + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool Mixin::IsInitialized() const { + return true; +} + +void Mixin::InternalSwap(Mixin* other) { + using std::swap; + auto* lhs_arena = GetArenaForAllocation(); + auto* rhs_arena = other->GetArenaForAllocation(); + _internal_metadata_.InternalSwap(&other->_internal_metadata_); + ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::InternalSwap( + &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), + &name_, lhs_arena, + &other->name_, rhs_arena + ); + ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::InternalSwap( + &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), + &root_, lhs_arena, + &other->root_, rhs_arena + ); +} + +::PROTOBUF_NAMESPACE_ID::Metadata Mixin::GetMetadata() const { + return ::PROTOBUF_NAMESPACE_ID::internal::AssignDescriptors( + &descriptor_table_google_2fprotobuf_2fapi_2eproto_getter, &descriptor_table_google_2fprotobuf_2fapi_2eproto_once, + file_level_metadata_google_2fprotobuf_2fapi_2eproto[2]); +} + +// @@protoc_insertion_point(namespace_scope) +PROTOBUF_NAMESPACE_CLOSE +PROTOBUF_NAMESPACE_OPEN +template<> PROTOBUF_NOINLINE ::PROTOBUF_NAMESPACE_ID::Api* Arena::CreateMaybeMessage< ::PROTOBUF_NAMESPACE_ID::Api >(Arena* arena) { + return Arena::CreateMessageInternal< ::PROTOBUF_NAMESPACE_ID::Api >(arena); +} +template<> PROTOBUF_NOINLINE ::PROTOBUF_NAMESPACE_ID::Method* Arena::CreateMaybeMessage< ::PROTOBUF_NAMESPACE_ID::Method >(Arena* arena) { + return Arena::CreateMessageInternal< ::PROTOBUF_NAMESPACE_ID::Method >(arena); +} +template<> PROTOBUF_NOINLINE ::PROTOBUF_NAMESPACE_ID::Mixin* Arena::CreateMaybeMessage< ::PROTOBUF_NAMESPACE_ID::Mixin >(Arena* arena) { + return Arena::CreateMessageInternal< ::PROTOBUF_NAMESPACE_ID::Mixin >(arena); +} +PROTOBUF_NAMESPACE_CLOSE + +// @@protoc_insertion_point(global_scope) +#include <google/protobuf/port_undef.inc> diff --git a/contrib/libs/protobuf_old/src/google/protobuf/api.pb.h b/contrib/libs/protobuf_old/src/google/protobuf/api.pb.h new file mode 100644 index 0000000000..85e5252b82 --- /dev/null +++ b/contrib/libs/protobuf_old/src/google/protobuf/api.pb.h @@ -0,0 +1,1448 @@ +// Generated by the protocol buffer compiler. DO NOT EDIT! +// source: google/protobuf/api.proto + +#ifndef GOOGLE_PROTOBUF_INCLUDED_google_2fprotobuf_2fapi_2eproto +#define GOOGLE_PROTOBUF_INCLUDED_google_2fprotobuf_2fapi_2eproto + +#include <limits> +#include <string> + +#include <google/protobuf/port_def.inc> +#if PROTOBUF_VERSION < 3019000 +#error This file was generated by a newer version of protoc which is +#error incompatible with your Protocol Buffer headers. Please update +#error your headers. +#endif +#if 3019000 < PROTOBUF_MIN_PROTOC_VERSION +#error This file was generated by an older version of protoc which is +#error incompatible with your Protocol Buffer headers. Please +#error regenerate this file with a newer version of protoc. +#endif + +#include <google/protobuf/port_undef.inc> +#include <google/protobuf/io/coded_stream.h> +#include <google/protobuf/arena.h> +#include <google/protobuf/arenastring.h> +#include <google/protobuf/generated_message_table_driven.h> +#include <google/protobuf/generated_message_util.h> +#include <google/protobuf/metadata_lite.h> +#include <google/protobuf/generated_message_reflection.h> +#include <google/protobuf/message.h> +#include <google/protobuf/repeated_field.h> // IWYU pragma: export +#include <google/protobuf/extension_set.h> // IWYU pragma: export +#include <google/protobuf/unknown_field_set.h> +#include <google/protobuf/source_context.pb.h> +#include <google/protobuf/type.pb.h> +// @@protoc_insertion_point(includes) +#include <google/protobuf/port_def.inc> +#define PROTOBUF_INTERNAL_EXPORT_google_2fprotobuf_2fapi_2eproto PROTOBUF_EXPORT +PROTOBUF_NAMESPACE_OPEN +namespace internal { +class AnyMetadata; +} // namespace internal +PROTOBUF_NAMESPACE_CLOSE + +// Internal implementation detail -- do not use these members. +struct PROTOBUF_EXPORT TableStruct_google_2fprotobuf_2fapi_2eproto { + static const ::PROTOBUF_NAMESPACE_ID::internal::ParseTableField entries[] + PROTOBUF_SECTION_VARIABLE(protodesc_cold); + static const ::PROTOBUF_NAMESPACE_ID::internal::AuxiliaryParseTableField aux[] + PROTOBUF_SECTION_VARIABLE(protodesc_cold); + static const ::PROTOBUF_NAMESPACE_ID::internal::ParseTable schema[3] + PROTOBUF_SECTION_VARIABLE(protodesc_cold); + static const ::PROTOBUF_NAMESPACE_ID::internal::FieldMetadata field_metadata[]; + static const ::PROTOBUF_NAMESPACE_ID::internal::SerializationTable serialization_table[]; + static const arc_ui32 offsets[]; +}; +PROTOBUF_EXPORT extern const ::PROTOBUF_NAMESPACE_ID::internal::DescriptorTable descriptor_table_google_2fprotobuf_2fapi_2eproto; +PROTOBUF_NAMESPACE_OPEN +class Api; +struct ApiDefaultTypeInternal; +PROTOBUF_EXPORT extern ApiDefaultTypeInternal _Api_default_instance_; +class Method; +struct MethodDefaultTypeInternal; +PROTOBUF_EXPORT extern MethodDefaultTypeInternal _Method_default_instance_; +class Mixin; +struct MixinDefaultTypeInternal; +PROTOBUF_EXPORT extern MixinDefaultTypeInternal _Mixin_default_instance_; +PROTOBUF_NAMESPACE_CLOSE +PROTOBUF_NAMESPACE_OPEN +template<> PROTOBUF_EXPORT ::PROTOBUF_NAMESPACE_ID::Api* Arena::CreateMaybeMessage<::PROTOBUF_NAMESPACE_ID::Api>(Arena*); +template<> PROTOBUF_EXPORT ::PROTOBUF_NAMESPACE_ID::Method* Arena::CreateMaybeMessage<::PROTOBUF_NAMESPACE_ID::Method>(Arena*); +template<> PROTOBUF_EXPORT ::PROTOBUF_NAMESPACE_ID::Mixin* Arena::CreateMaybeMessage<::PROTOBUF_NAMESPACE_ID::Mixin>(Arena*); +PROTOBUF_NAMESPACE_CLOSE +PROTOBUF_NAMESPACE_OPEN + +// =================================================================== + +class PROTOBUF_EXPORT Api final : + public ::PROTOBUF_NAMESPACE_ID::Message /* @@protoc_insertion_point(class_definition:google.protobuf.Api) */ { + public: + inline Api() : Api(nullptr) {} + ~Api() override; + explicit constexpr Api(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized); + + Api(const Api& from); + Api(Api&& from) noexcept + : Api() { + *this = ::std::move(from); + } + + inline Api& operator=(const Api& from) { + CopyFrom(from); + return *this; + } + inline Api& operator=(Api&& from) noexcept { + if (this == &from) return *this; + if (GetOwningArena() == from.GetOwningArena() + #ifdef PROTOBUF_FORCE_COPY_IN_MOVE + && GetOwningArena() != nullptr + #endif // !PROTOBUF_FORCE_COPY_IN_MOVE + ) { + InternalSwap(&from); + } else { + CopyFrom(from); + } + return *this; + } + + static const ::PROTOBUF_NAMESPACE_ID::Descriptor* descriptor() { + return GetDescriptor(); + } + static const ::PROTOBUF_NAMESPACE_ID::Descriptor* GetDescriptor() { + return default_instance().GetMetadata().descriptor; + } + static const ::PROTOBUF_NAMESPACE_ID::Reflection* GetReflection() { + return default_instance().GetMetadata().reflection; + } + static const Api& default_instance() { + return *internal_default_instance(); + } + static inline const Api* internal_default_instance() { + return reinterpret_cast<const Api*>( + &_Api_default_instance_); + } + static constexpr int kIndexInFileMessages = + 0; + + friend void swap(Api& a, Api& b) { + a.Swap(&b); + } + inline void Swap(Api* other) { + if (other == this) return; + #ifdef PROTOBUF_FORCE_COPY_IN_SWAP + if (GetOwningArena() != nullptr && + GetOwningArena() == other->GetOwningArena()) { + #else // PROTOBUF_FORCE_COPY_IN_SWAP + if (GetOwningArena() == other->GetOwningArena()) { + #endif // !PROTOBUF_FORCE_COPY_IN_SWAP + InternalSwap(other); + } else { + ::PROTOBUF_NAMESPACE_ID::internal::GenericSwap(this, other); + } + } + void UnsafeArenaSwap(Api* other) { + if (other == this) return; + GOOGLE_DCHECK(GetOwningArena() == other->GetOwningArena()); + InternalSwap(other); + } + + // implements Message ---------------------------------------------- + + Api* New(::PROTOBUF_NAMESPACE_ID::Arena* arena = nullptr) const final { + return CreateMaybeMessage<Api>(arena); + } + 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; + + size_t ByteSizeLong() const final; + const char* _InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) final; + uint8_t* _InternalSerialize( + uint8_t* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const final; + int GetCachedSize() const final { return _cached_size_.Get(); } + + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const final; + void InternalSwap(Api* other); + + private: + friend class ::PROTOBUF_NAMESPACE_ID::internal::AnyMetadata; + static ::PROTOBUF_NAMESPACE_ID::StringPiece FullMessageName() { + return "google.protobuf.Api"; + } + protected: + 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 ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + enum : int { + kMethodsFieldNumber = 2, + kOptionsFieldNumber = 3, + kMixinsFieldNumber = 6, + kNameFieldNumber = 1, + kVersionFieldNumber = 4, + kSourceContextFieldNumber = 5, + kSyntaxFieldNumber = 7, + }; + // repeated .google.protobuf.Method methods = 2; + int methods_size() const; + private: + int _internal_methods_size() const; + public: + void clear_methods(); + ::PROTOBUF_NAMESPACE_ID::Method* mutable_methods(int index); + ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::Method >* + mutable_methods(); + private: + const ::PROTOBUF_NAMESPACE_ID::Method& _internal_methods(int index) const; + ::PROTOBUF_NAMESPACE_ID::Method* _internal_add_methods(); + public: + const ::PROTOBUF_NAMESPACE_ID::Method& methods(int index) const; + ::PROTOBUF_NAMESPACE_ID::Method* add_methods(); + const ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::Method >& + methods() const; + + // repeated .google.protobuf.Option options = 3; + int options_size() const; + private: + int _internal_options_size() const; + public: + void clear_options(); + ::PROTOBUF_NAMESPACE_ID::Option* mutable_options(int index); + ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::Option >* + mutable_options(); + private: + const ::PROTOBUF_NAMESPACE_ID::Option& _internal_options(int index) const; + ::PROTOBUF_NAMESPACE_ID::Option* _internal_add_options(); + public: + const ::PROTOBUF_NAMESPACE_ID::Option& options(int index) const; + ::PROTOBUF_NAMESPACE_ID::Option* add_options(); + const ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::Option >& + options() const; + + // repeated .google.protobuf.Mixin mixins = 6; + int mixins_size() const; + private: + int _internal_mixins_size() const; + public: + void clear_mixins(); + ::PROTOBUF_NAMESPACE_ID::Mixin* mutable_mixins(int index); + ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::Mixin >* + mutable_mixins(); + private: + const ::PROTOBUF_NAMESPACE_ID::Mixin& _internal_mixins(int index) const; + ::PROTOBUF_NAMESPACE_ID::Mixin* _internal_add_mixins(); + public: + const ::PROTOBUF_NAMESPACE_ID::Mixin& mixins(int index) const; + ::PROTOBUF_NAMESPACE_ID::Mixin* add_mixins(); + const ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::Mixin >& + mixins() const; + + // string name = 1; + void clear_name(); + const TProtoStringType& name() const; + template <typename ArgT0 = const TProtoStringType&, typename... ArgT> + void set_name(ArgT0&& arg0, ArgT... args); + TProtoStringType* mutable_name(); + PROTOBUF_NODISCARD TProtoStringType* release_name(); + void set_allocated_name(TProtoStringType* name); + private: + const TProtoStringType& _internal_name() const; + inline PROTOBUF_ALWAYS_INLINE void _internal_set_name(const TProtoStringType& value); + TProtoStringType* _internal_mutable_name(); + public: + + // string version = 4; + void clear_version(); + const TProtoStringType& version() const; + template <typename ArgT0 = const TProtoStringType&, typename... ArgT> + void set_version(ArgT0&& arg0, ArgT... args); + TProtoStringType* mutable_version(); + PROTOBUF_NODISCARD TProtoStringType* release_version(); + void set_allocated_version(TProtoStringType* version); + private: + const TProtoStringType& _internal_version() const; + inline PROTOBUF_ALWAYS_INLINE void _internal_set_version(const TProtoStringType& value); + TProtoStringType* _internal_mutable_version(); + public: + + // .google.protobuf.SourceContext source_context = 5; + bool has_source_context() const; + private: + bool _internal_has_source_context() const; + public: + void clear_source_context(); + const ::PROTOBUF_NAMESPACE_ID::SourceContext& source_context() const; + PROTOBUF_NODISCARD ::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: + const ::PROTOBUF_NAMESPACE_ID::SourceContext& _internal_source_context() const; + ::PROTOBUF_NAMESPACE_ID::SourceContext* _internal_mutable_source_context(); + public: + void unsafe_arena_set_allocated_source_context( + ::PROTOBUF_NAMESPACE_ID::SourceContext* source_context); + ::PROTOBUF_NAMESPACE_ID::SourceContext* unsafe_arena_release_source_context(); + + // .google.protobuf.Syntax syntax = 7; + void clear_syntax(); + ::PROTOBUF_NAMESPACE_ID::Syntax syntax() const; + void set_syntax(::PROTOBUF_NAMESPACE_ID::Syntax value); + private: + ::PROTOBUF_NAMESPACE_ID::Syntax _internal_syntax() const; + void _internal_set_syntax(::PROTOBUF_NAMESPACE_ID::Syntax value); + public: + + // @@protoc_insertion_point(class_scope:google.protobuf.Api) + private: + class _Internal; + + template <typename T> friend class ::PROTOBUF_NAMESPACE_ID::Arena::InternalHelper; + typedef void InternalArenaConstructable_; + typedef void DestructorSkippable_; + ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::Method > methods_; + ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::Option > options_; + ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::Mixin > mixins_; + ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr name_; + ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr version_; + ::PROTOBUF_NAMESPACE_ID::SourceContext* source_context_; + int syntax_; + mutable ::PROTOBUF_NAMESPACE_ID::internal::CachedSize _cached_size_; + friend struct ::TableStruct_google_2fprotobuf_2fapi_2eproto; +}; +// ------------------------------------------------------------------- + +class PROTOBUF_EXPORT Method final : + public ::PROTOBUF_NAMESPACE_ID::Message /* @@protoc_insertion_point(class_definition:google.protobuf.Method) */ { + public: + inline Method() : Method(nullptr) {} + ~Method() override; + explicit constexpr Method(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized); + + Method(const Method& from); + Method(Method&& from) noexcept + : Method() { + *this = ::std::move(from); + } + + inline Method& operator=(const Method& from) { + CopyFrom(from); + return *this; + } + inline Method& operator=(Method&& from) noexcept { + if (this == &from) return *this; + if (GetOwningArena() == from.GetOwningArena() + #ifdef PROTOBUF_FORCE_COPY_IN_MOVE + && GetOwningArena() != nullptr + #endif // !PROTOBUF_FORCE_COPY_IN_MOVE + ) { + InternalSwap(&from); + } else { + CopyFrom(from); + } + return *this; + } + + static const ::PROTOBUF_NAMESPACE_ID::Descriptor* descriptor() { + return GetDescriptor(); + } + static const ::PROTOBUF_NAMESPACE_ID::Descriptor* GetDescriptor() { + return default_instance().GetMetadata().descriptor; + } + static const ::PROTOBUF_NAMESPACE_ID::Reflection* GetReflection() { + return default_instance().GetMetadata().reflection; + } + static const Method& default_instance() { + return *internal_default_instance(); + } + static inline const Method* internal_default_instance() { + return reinterpret_cast<const Method*>( + &_Method_default_instance_); + } + static constexpr int kIndexInFileMessages = + 1; + + friend void swap(Method& a, Method& b) { + a.Swap(&b); + } + inline void Swap(Method* other) { + if (other == this) return; + #ifdef PROTOBUF_FORCE_COPY_IN_SWAP + if (GetOwningArena() != nullptr && + GetOwningArena() == other->GetOwningArena()) { + #else // PROTOBUF_FORCE_COPY_IN_SWAP + if (GetOwningArena() == other->GetOwningArena()) { + #endif // !PROTOBUF_FORCE_COPY_IN_SWAP + InternalSwap(other); + } else { + ::PROTOBUF_NAMESPACE_ID::internal::GenericSwap(this, other); + } + } + void UnsafeArenaSwap(Method* other) { + if (other == this) return; + GOOGLE_DCHECK(GetOwningArena() == other->GetOwningArena()); + InternalSwap(other); + } + + // implements Message ---------------------------------------------- + + Method* New(::PROTOBUF_NAMESPACE_ID::Arena* arena = nullptr) const final { + return CreateMaybeMessage<Method>(arena); + } + 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; + + size_t ByteSizeLong() const final; + const char* _InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) final; + uint8_t* _InternalSerialize( + uint8_t* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const final; + int GetCachedSize() const final { return _cached_size_.Get(); } + + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const final; + void InternalSwap(Method* other); + + private: + friend class ::PROTOBUF_NAMESPACE_ID::internal::AnyMetadata; + static ::PROTOBUF_NAMESPACE_ID::StringPiece FullMessageName() { + return "google.protobuf.Method"; + } + protected: + 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 ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + enum : int { + kOptionsFieldNumber = 6, + kNameFieldNumber = 1, + kRequestTypeUrlFieldNumber = 2, + kResponseTypeUrlFieldNumber = 4, + kRequestStreamingFieldNumber = 3, + kResponseStreamingFieldNumber = 5, + kSyntaxFieldNumber = 7, + }; + // repeated .google.protobuf.Option options = 6; + int options_size() const; + private: + int _internal_options_size() const; + public: + void clear_options(); + ::PROTOBUF_NAMESPACE_ID::Option* mutable_options(int index); + ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::Option >* + mutable_options(); + private: + const ::PROTOBUF_NAMESPACE_ID::Option& _internal_options(int index) const; + ::PROTOBUF_NAMESPACE_ID::Option* _internal_add_options(); + public: + const ::PROTOBUF_NAMESPACE_ID::Option& options(int index) const; + ::PROTOBUF_NAMESPACE_ID::Option* add_options(); + const ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::Option >& + options() const; + + // string name = 1; + void clear_name(); + const TProtoStringType& name() const; + template <typename ArgT0 = const TProtoStringType&, typename... ArgT> + void set_name(ArgT0&& arg0, ArgT... args); + TProtoStringType* mutable_name(); + PROTOBUF_NODISCARD TProtoStringType* release_name(); + void set_allocated_name(TProtoStringType* name); + private: + const TProtoStringType& _internal_name() const; + inline PROTOBUF_ALWAYS_INLINE void _internal_set_name(const TProtoStringType& value); + TProtoStringType* _internal_mutable_name(); + public: + + // string request_type_url = 2; + void clear_request_type_url(); + const TProtoStringType& request_type_url() const; + template <typename ArgT0 = const TProtoStringType&, typename... ArgT> + void set_request_type_url(ArgT0&& arg0, ArgT... args); + TProtoStringType* mutable_request_type_url(); + PROTOBUF_NODISCARD TProtoStringType* release_request_type_url(); + void set_allocated_request_type_url(TProtoStringType* request_type_url); + private: + const TProtoStringType& _internal_request_type_url() const; + inline PROTOBUF_ALWAYS_INLINE void _internal_set_request_type_url(const TProtoStringType& value); + TProtoStringType* _internal_mutable_request_type_url(); + public: + + // string response_type_url = 4; + void clear_response_type_url(); + const TProtoStringType& response_type_url() const; + template <typename ArgT0 = const TProtoStringType&, typename... ArgT> + void set_response_type_url(ArgT0&& arg0, ArgT... args); + TProtoStringType* mutable_response_type_url(); + PROTOBUF_NODISCARD TProtoStringType* release_response_type_url(); + void set_allocated_response_type_url(TProtoStringType* response_type_url); + private: + const TProtoStringType& _internal_response_type_url() const; + inline PROTOBUF_ALWAYS_INLINE void _internal_set_response_type_url(const TProtoStringType& value); + TProtoStringType* _internal_mutable_response_type_url(); + public: + + // bool request_streaming = 3; + void clear_request_streaming(); + bool request_streaming() const; + void set_request_streaming(bool value); + private: + bool _internal_request_streaming() const; + void _internal_set_request_streaming(bool value); + public: + + // bool response_streaming = 5; + void clear_response_streaming(); + bool response_streaming() const; + void set_response_streaming(bool value); + private: + bool _internal_response_streaming() const; + void _internal_set_response_streaming(bool value); + public: + + // .google.protobuf.Syntax syntax = 7; + void clear_syntax(); + ::PROTOBUF_NAMESPACE_ID::Syntax syntax() const; + void set_syntax(::PROTOBUF_NAMESPACE_ID::Syntax value); + private: + ::PROTOBUF_NAMESPACE_ID::Syntax _internal_syntax() const; + void _internal_set_syntax(::PROTOBUF_NAMESPACE_ID::Syntax value); + public: + + // @@protoc_insertion_point(class_scope:google.protobuf.Method) + private: + class _Internal; + + template <typename T> friend class ::PROTOBUF_NAMESPACE_ID::Arena::InternalHelper; + typedef void InternalArenaConstructable_; + typedef void DestructorSkippable_; + ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::Option > options_; + ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr name_; + ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr request_type_url_; + ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr response_type_url_; + bool request_streaming_; + bool response_streaming_; + int syntax_; + mutable ::PROTOBUF_NAMESPACE_ID::internal::CachedSize _cached_size_; + friend struct ::TableStruct_google_2fprotobuf_2fapi_2eproto; +}; +// ------------------------------------------------------------------- + +class PROTOBUF_EXPORT Mixin final : + public ::PROTOBUF_NAMESPACE_ID::Message /* @@protoc_insertion_point(class_definition:google.protobuf.Mixin) */ { + public: + inline Mixin() : Mixin(nullptr) {} + ~Mixin() override; + explicit constexpr Mixin(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized); + + Mixin(const Mixin& from); + Mixin(Mixin&& from) noexcept + : Mixin() { + *this = ::std::move(from); + } + + inline Mixin& operator=(const Mixin& from) { + CopyFrom(from); + return *this; + } + inline Mixin& operator=(Mixin&& from) noexcept { + if (this == &from) return *this; + if (GetOwningArena() == from.GetOwningArena() + #ifdef PROTOBUF_FORCE_COPY_IN_MOVE + && GetOwningArena() != nullptr + #endif // !PROTOBUF_FORCE_COPY_IN_MOVE + ) { + InternalSwap(&from); + } else { + CopyFrom(from); + } + return *this; + } + + static const ::PROTOBUF_NAMESPACE_ID::Descriptor* descriptor() { + return GetDescriptor(); + } + static const ::PROTOBUF_NAMESPACE_ID::Descriptor* GetDescriptor() { + return default_instance().GetMetadata().descriptor; + } + static const ::PROTOBUF_NAMESPACE_ID::Reflection* GetReflection() { + return default_instance().GetMetadata().reflection; + } + static const Mixin& default_instance() { + return *internal_default_instance(); + } + static inline const Mixin* internal_default_instance() { + return reinterpret_cast<const Mixin*>( + &_Mixin_default_instance_); + } + static constexpr int kIndexInFileMessages = + 2; + + friend void swap(Mixin& a, Mixin& b) { + a.Swap(&b); + } + inline void Swap(Mixin* other) { + if (other == this) return; + #ifdef PROTOBUF_FORCE_COPY_IN_SWAP + if (GetOwningArena() != nullptr && + GetOwningArena() == other->GetOwningArena()) { + #else // PROTOBUF_FORCE_COPY_IN_SWAP + if (GetOwningArena() == other->GetOwningArena()) { + #endif // !PROTOBUF_FORCE_COPY_IN_SWAP + InternalSwap(other); + } else { + ::PROTOBUF_NAMESPACE_ID::internal::GenericSwap(this, other); + } + } + void UnsafeArenaSwap(Mixin* other) { + if (other == this) return; + GOOGLE_DCHECK(GetOwningArena() == other->GetOwningArena()); + InternalSwap(other); + } + + // implements Message ---------------------------------------------- + + Mixin* New(::PROTOBUF_NAMESPACE_ID::Arena* arena = nullptr) const final { + return CreateMaybeMessage<Mixin>(arena); + } + 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; + + size_t ByteSizeLong() const final; + const char* _InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) final; + uint8_t* _InternalSerialize( + uint8_t* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const final; + int GetCachedSize() const final { return _cached_size_.Get(); } + + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const final; + void InternalSwap(Mixin* other); + + private: + friend class ::PROTOBUF_NAMESPACE_ID::internal::AnyMetadata; + static ::PROTOBUF_NAMESPACE_ID::StringPiece FullMessageName() { + return "google.protobuf.Mixin"; + } + protected: + 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 ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + enum : int { + kNameFieldNumber = 1, + kRootFieldNumber = 2, + }; + // string name = 1; + void clear_name(); + const TProtoStringType& name() const; + template <typename ArgT0 = const TProtoStringType&, typename... ArgT> + void set_name(ArgT0&& arg0, ArgT... args); + TProtoStringType* mutable_name(); + PROTOBUF_NODISCARD TProtoStringType* release_name(); + void set_allocated_name(TProtoStringType* name); + private: + const TProtoStringType& _internal_name() const; + inline PROTOBUF_ALWAYS_INLINE void _internal_set_name(const TProtoStringType& value); + TProtoStringType* _internal_mutable_name(); + public: + + // string root = 2; + void clear_root(); + const TProtoStringType& root() const; + template <typename ArgT0 = const TProtoStringType&, typename... ArgT> + void set_root(ArgT0&& arg0, ArgT... args); + TProtoStringType* mutable_root(); + PROTOBUF_NODISCARD TProtoStringType* release_root(); + void set_allocated_root(TProtoStringType* root); + private: + const TProtoStringType& _internal_root() const; + inline PROTOBUF_ALWAYS_INLINE void _internal_set_root(const TProtoStringType& value); + TProtoStringType* _internal_mutable_root(); + public: + + // @@protoc_insertion_point(class_scope:google.protobuf.Mixin) + private: + class _Internal; + + template <typename T> friend class ::PROTOBUF_NAMESPACE_ID::Arena::InternalHelper; + typedef void InternalArenaConstructable_; + typedef void DestructorSkippable_; + ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr name_; + ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr root_; + mutable ::PROTOBUF_NAMESPACE_ID::internal::CachedSize _cached_size_; + friend struct ::TableStruct_google_2fprotobuf_2fapi_2eproto; +}; +// =================================================================== + + +// =================================================================== + +#ifdef __GNUC__ + #pragma GCC diagnostic push + #pragma GCC diagnostic ignored "-Wstrict-aliasing" +#endif // __GNUC__ +// Api + +// string name = 1; +inline void Api::clear_name() { + name_.ClearToEmpty(); +} +inline const TProtoStringType& Api::name() const { + // @@protoc_insertion_point(field_get:google.protobuf.Api.name) + return _internal_name(); +} +template <typename ArgT0, typename... ArgT> +inline PROTOBUF_ALWAYS_INLINE +void Api::set_name(ArgT0&& arg0, ArgT... args) { + + name_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, static_cast<ArgT0 &&>(arg0), args..., GetArenaForAllocation()); + // @@protoc_insertion_point(field_set:google.protobuf.Api.name) +} +inline TProtoStringType* Api::mutable_name() { + TProtoStringType* _s = _internal_mutable_name(); + // @@protoc_insertion_point(field_mutable:google.protobuf.Api.name) + return _s; +} +inline const TProtoStringType& Api::_internal_name() const { + return name_.Get(); +} +inline void Api::_internal_set_name(const TProtoStringType& value) { + + name_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, value, GetArenaForAllocation()); +} +inline TProtoStringType* Api::_internal_mutable_name() { + + return name_.Mutable(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, GetArenaForAllocation()); +} +inline TProtoStringType* Api::release_name() { + // @@protoc_insertion_point(field_release:google.protobuf.Api.name) + return name_.Release(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArenaForAllocation()); +} +inline void Api::set_allocated_name(TProtoStringType* name) { + if (name != nullptr) { + + } else { + + } + name_.SetAllocated(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), name, + GetArenaForAllocation()); +#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING + if (name_.IsDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited())) { + name_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation()); + } +#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING + // @@protoc_insertion_point(field_set_allocated:google.protobuf.Api.name) +} + +// repeated .google.protobuf.Method methods = 2; +inline int Api::_internal_methods_size() const { + return methods_.size(); +} +inline int Api::methods_size() const { + return _internal_methods_size(); +} +inline void Api::clear_methods() { + methods_.Clear(); +} +inline ::PROTOBUF_NAMESPACE_ID::Method* Api::mutable_methods(int index) { + // @@protoc_insertion_point(field_mutable:google.protobuf.Api.methods) + return methods_.Mutable(index); +} +inline ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::Method >* +Api::mutable_methods() { + // @@protoc_insertion_point(field_mutable_list:google.protobuf.Api.methods) + return &methods_; +} +inline const ::PROTOBUF_NAMESPACE_ID::Method& Api::_internal_methods(int index) const { + return methods_.Get(index); +} +inline const ::PROTOBUF_NAMESPACE_ID::Method& Api::methods(int index) const { + // @@protoc_insertion_point(field_get:google.protobuf.Api.methods) + return _internal_methods(index); +} +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 _add; +} +inline const ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::Method >& +Api::methods() const { + // @@protoc_insertion_point(field_list:google.protobuf.Api.methods) + return methods_; +} + +// repeated .google.protobuf.Option options = 3; +inline int Api::_internal_options_size() const { + return options_.size(); +} +inline int Api::options_size() const { + return _internal_options_size(); +} +inline ::PROTOBUF_NAMESPACE_ID::Option* Api::mutable_options(int index) { + // @@protoc_insertion_point(field_mutable:google.protobuf.Api.options) + return options_.Mutable(index); +} +inline ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::Option >* +Api::mutable_options() { + // @@protoc_insertion_point(field_mutable_list:google.protobuf.Api.options) + return &options_; +} +inline const ::PROTOBUF_NAMESPACE_ID::Option& Api::_internal_options(int index) const { + return options_.Get(index); +} +inline const ::PROTOBUF_NAMESPACE_ID::Option& Api::options(int index) const { + // @@protoc_insertion_point(field_get:google.protobuf.Api.options) + return _internal_options(index); +} +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 _add; +} +inline const ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::Option >& +Api::options() const { + // @@protoc_insertion_point(field_list:google.protobuf.Api.options) + return options_; +} + +// string version = 4; +inline void Api::clear_version() { + version_.ClearToEmpty(); +} +inline const TProtoStringType& Api::version() const { + // @@protoc_insertion_point(field_get:google.protobuf.Api.version) + return _internal_version(); +} +template <typename ArgT0, typename... ArgT> +inline PROTOBUF_ALWAYS_INLINE +void Api::set_version(ArgT0&& arg0, ArgT... args) { + + version_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, static_cast<ArgT0 &&>(arg0), args..., GetArenaForAllocation()); + // @@protoc_insertion_point(field_set:google.protobuf.Api.version) +} +inline TProtoStringType* Api::mutable_version() { + TProtoStringType* _s = _internal_mutable_version(); + // @@protoc_insertion_point(field_mutable:google.protobuf.Api.version) + return _s; +} +inline const TProtoStringType& Api::_internal_version() const { + return version_.Get(); +} +inline void Api::_internal_set_version(const TProtoStringType& value) { + + version_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, value, GetArenaForAllocation()); +} +inline TProtoStringType* Api::_internal_mutable_version() { + + return version_.Mutable(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, GetArenaForAllocation()); +} +inline TProtoStringType* Api::release_version() { + // @@protoc_insertion_point(field_release:google.protobuf.Api.version) + return version_.Release(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArenaForAllocation()); +} +inline void Api::set_allocated_version(TProtoStringType* version) { + if (version != nullptr) { + + } else { + + } + version_.SetAllocated(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), version, + GetArenaForAllocation()); +#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING + if (version_.IsDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited())) { + version_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation()); + } +#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING + // @@protoc_insertion_point(field_set_allocated:google.protobuf.Api.version) +} + +// .google.protobuf.SourceContext source_context = 5; +inline bool Api::_internal_has_source_context() const { + return this != internal_default_instance() && source_context_ != nullptr; +} +inline bool Api::has_source_context() const { + return _internal_has_source_context(); +} +inline const ::PROTOBUF_NAMESPACE_ID::SourceContext& Api::_internal_source_context() const { + const ::PROTOBUF_NAMESPACE_ID::SourceContext* p = source_context_; + return p != nullptr ? *p : reinterpret_cast<const ::PROTOBUF_NAMESPACE_ID::SourceContext&>( + ::PROTOBUF_NAMESPACE_ID::_SourceContext_default_instance_); +} +inline const ::PROTOBUF_NAMESPACE_ID::SourceContext& Api::source_context() const { + // @@protoc_insertion_point(field_get:google.protobuf.Api.source_context) + return _internal_source_context(); +} +inline void Api::unsafe_arena_set_allocated_source_context( + ::PROTOBUF_NAMESPACE_ID::SourceContext* source_context) { + if (GetArenaForAllocation() == nullptr) { + delete reinterpret_cast<::PROTOBUF_NAMESPACE_ID::MessageLite*>(source_context_); + } + source_context_ = source_context; + if (source_context) { + + } else { + + } + // @@protoc_insertion_point(field_unsafe_arena_set_allocated:google.protobuf.Api.source_context) +} +inline ::PROTOBUF_NAMESPACE_ID::SourceContext* Api::release_source_context() { + + ::PROTOBUF_NAMESPACE_ID::SourceContext* temp = source_context_; + source_context_ = nullptr; +#ifdef PROTOBUF_FORCE_COPY_IN_RELEASE + auto* old = reinterpret_cast<::PROTOBUF_NAMESPACE_ID::MessageLite*>(temp); + temp = ::PROTOBUF_NAMESPACE_ID::internal::DuplicateIfNonNull(temp); + if (GetArenaForAllocation() == nullptr) { delete old; } +#else // PROTOBUF_FORCE_COPY_IN_RELEASE + if (GetArenaForAllocation() != nullptr) { + temp = ::PROTOBUF_NAMESPACE_ID::internal::DuplicateIfNonNull(temp); + } +#endif // !PROTOBUF_FORCE_COPY_IN_RELEASE + return temp; +} +inline ::PROTOBUF_NAMESPACE_ID::SourceContext* Api::unsafe_arena_release_source_context() { + // @@protoc_insertion_point(field_release:google.protobuf.Api.source_context) + + ::PROTOBUF_NAMESPACE_ID::SourceContext* temp = source_context_; + source_context_ = nullptr; + return temp; +} +inline ::PROTOBUF_NAMESPACE_ID::SourceContext* Api::_internal_mutable_source_context() { + + if (source_context_ == nullptr) { + auto* p = CreateMaybeMessage<::PROTOBUF_NAMESPACE_ID::SourceContext>(GetArenaForAllocation()); + source_context_ = p; + } + 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 _msg; +} +inline void Api::set_allocated_source_context(::PROTOBUF_NAMESPACE_ID::SourceContext* source_context) { + ::PROTOBUF_NAMESPACE_ID::Arena* message_arena = GetArenaForAllocation(); + if (message_arena == nullptr) { + delete reinterpret_cast< ::PROTOBUF_NAMESPACE_ID::MessageLite*>(source_context_); + } + if (source_context) { + ::PROTOBUF_NAMESPACE_ID::Arena* submessage_arena = + ::PROTOBUF_NAMESPACE_ID::Arena::InternalHelper< + ::PROTOBUF_NAMESPACE_ID::MessageLite>::GetOwningArena( + reinterpret_cast<::PROTOBUF_NAMESPACE_ID::MessageLite*>(source_context)); + if (message_arena != submessage_arena) { + source_context = ::PROTOBUF_NAMESPACE_ID::internal::GetOwnedMessage( + message_arena, source_context, submessage_arena); + } + + } else { + + } + source_context_ = source_context; + // @@protoc_insertion_point(field_set_allocated:google.protobuf.Api.source_context) +} + +// repeated .google.protobuf.Mixin mixins = 6; +inline int Api::_internal_mixins_size() const { + return mixins_.size(); +} +inline int Api::mixins_size() const { + return _internal_mixins_size(); +} +inline void Api::clear_mixins() { + mixins_.Clear(); +} +inline ::PROTOBUF_NAMESPACE_ID::Mixin* Api::mutable_mixins(int index) { + // @@protoc_insertion_point(field_mutable:google.protobuf.Api.mixins) + return mixins_.Mutable(index); +} +inline ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::Mixin >* +Api::mutable_mixins() { + // @@protoc_insertion_point(field_mutable_list:google.protobuf.Api.mixins) + return &mixins_; +} +inline const ::PROTOBUF_NAMESPACE_ID::Mixin& Api::_internal_mixins(int index) const { + return mixins_.Get(index); +} +inline const ::PROTOBUF_NAMESPACE_ID::Mixin& Api::mixins(int index) const { + // @@protoc_insertion_point(field_get:google.protobuf.Api.mixins) + return _internal_mixins(index); +} +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 _add; +} +inline const ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::Mixin >& +Api::mixins() const { + // @@protoc_insertion_point(field_list:google.protobuf.Api.mixins) + return mixins_; +} + +// .google.protobuf.Syntax syntax = 7; +inline void Api::clear_syntax() { + syntax_ = 0; +} +inline ::PROTOBUF_NAMESPACE_ID::Syntax Api::_internal_syntax() const { + return static_cast< ::PROTOBUF_NAMESPACE_ID::Syntax >(syntax_); +} +inline ::PROTOBUF_NAMESPACE_ID::Syntax Api::syntax() const { + // @@protoc_insertion_point(field_get:google.protobuf.Api.syntax) + return _internal_syntax(); +} +inline void Api::_internal_set_syntax(::PROTOBUF_NAMESPACE_ID::Syntax value) { + + syntax_ = value; +} +inline void Api::set_syntax(::PROTOBUF_NAMESPACE_ID::Syntax value) { + _internal_set_syntax(value); + // @@protoc_insertion_point(field_set:google.protobuf.Api.syntax) +} + +// ------------------------------------------------------------------- + +// Method + +// string name = 1; +inline void Method::clear_name() { + name_.ClearToEmpty(); +} +inline const TProtoStringType& Method::name() const { + // @@protoc_insertion_point(field_get:google.protobuf.Method.name) + return _internal_name(); +} +template <typename ArgT0, typename... ArgT> +inline PROTOBUF_ALWAYS_INLINE +void Method::set_name(ArgT0&& arg0, ArgT... args) { + + name_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, static_cast<ArgT0 &&>(arg0), args..., GetArenaForAllocation()); + // @@protoc_insertion_point(field_set:google.protobuf.Method.name) +} +inline TProtoStringType* Method::mutable_name() { + TProtoStringType* _s = _internal_mutable_name(); + // @@protoc_insertion_point(field_mutable:google.protobuf.Method.name) + return _s; +} +inline const TProtoStringType& Method::_internal_name() const { + return name_.Get(); +} +inline void Method::_internal_set_name(const TProtoStringType& value) { + + name_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, value, GetArenaForAllocation()); +} +inline TProtoStringType* Method::_internal_mutable_name() { + + return name_.Mutable(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, GetArenaForAllocation()); +} +inline TProtoStringType* Method::release_name() { + // @@protoc_insertion_point(field_release:google.protobuf.Method.name) + return name_.Release(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArenaForAllocation()); +} +inline void Method::set_allocated_name(TProtoStringType* name) { + if (name != nullptr) { + + } else { + + } + name_.SetAllocated(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), name, + GetArenaForAllocation()); +#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING + if (name_.IsDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited())) { + name_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation()); + } +#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING + // @@protoc_insertion_point(field_set_allocated:google.protobuf.Method.name) +} + +// string request_type_url = 2; +inline void Method::clear_request_type_url() { + request_type_url_.ClearToEmpty(); +} +inline const TProtoStringType& Method::request_type_url() const { + // @@protoc_insertion_point(field_get:google.protobuf.Method.request_type_url) + return _internal_request_type_url(); +} +template <typename ArgT0, typename... ArgT> +inline PROTOBUF_ALWAYS_INLINE +void Method::set_request_type_url(ArgT0&& arg0, ArgT... args) { + + request_type_url_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, static_cast<ArgT0 &&>(arg0), args..., GetArenaForAllocation()); + // @@protoc_insertion_point(field_set:google.protobuf.Method.request_type_url) +} +inline TProtoStringType* Method::mutable_request_type_url() { + TProtoStringType* _s = _internal_mutable_request_type_url(); + // @@protoc_insertion_point(field_mutable:google.protobuf.Method.request_type_url) + return _s; +} +inline const TProtoStringType& Method::_internal_request_type_url() const { + return request_type_url_.Get(); +} +inline void Method::_internal_set_request_type_url(const TProtoStringType& value) { + + request_type_url_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, value, GetArenaForAllocation()); +} +inline TProtoStringType* Method::_internal_mutable_request_type_url() { + + return request_type_url_.Mutable(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, GetArenaForAllocation()); +} +inline TProtoStringType* Method::release_request_type_url() { + // @@protoc_insertion_point(field_release:google.protobuf.Method.request_type_url) + return request_type_url_.Release(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArenaForAllocation()); +} +inline void Method::set_allocated_request_type_url(TProtoStringType* request_type_url) { + if (request_type_url != nullptr) { + + } else { + + } + request_type_url_.SetAllocated(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), request_type_url, + GetArenaForAllocation()); +#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING + if (request_type_url_.IsDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited())) { + request_type_url_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation()); + } +#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING + // @@protoc_insertion_point(field_set_allocated:google.protobuf.Method.request_type_url) +} + +// bool request_streaming = 3; +inline void Method::clear_request_streaming() { + request_streaming_ = false; +} +inline bool Method::_internal_request_streaming() const { + return request_streaming_; +} +inline bool Method::request_streaming() const { + // @@protoc_insertion_point(field_get:google.protobuf.Method.request_streaming) + return _internal_request_streaming(); +} +inline void Method::_internal_set_request_streaming(bool value) { + + request_streaming_ = value; +} +inline void Method::set_request_streaming(bool value) { + _internal_set_request_streaming(value); + // @@protoc_insertion_point(field_set:google.protobuf.Method.request_streaming) +} + +// string response_type_url = 4; +inline void Method::clear_response_type_url() { + response_type_url_.ClearToEmpty(); +} +inline const TProtoStringType& Method::response_type_url() const { + // @@protoc_insertion_point(field_get:google.protobuf.Method.response_type_url) + return _internal_response_type_url(); +} +template <typename ArgT0, typename... ArgT> +inline PROTOBUF_ALWAYS_INLINE +void Method::set_response_type_url(ArgT0&& arg0, ArgT... args) { + + response_type_url_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, static_cast<ArgT0 &&>(arg0), args..., GetArenaForAllocation()); + // @@protoc_insertion_point(field_set:google.protobuf.Method.response_type_url) +} +inline TProtoStringType* Method::mutable_response_type_url() { + TProtoStringType* _s = _internal_mutable_response_type_url(); + // @@protoc_insertion_point(field_mutable:google.protobuf.Method.response_type_url) + return _s; +} +inline const TProtoStringType& Method::_internal_response_type_url() const { + return response_type_url_.Get(); +} +inline void Method::_internal_set_response_type_url(const TProtoStringType& value) { + + response_type_url_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, value, GetArenaForAllocation()); +} +inline TProtoStringType* Method::_internal_mutable_response_type_url() { + + return response_type_url_.Mutable(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, GetArenaForAllocation()); +} +inline TProtoStringType* Method::release_response_type_url() { + // @@protoc_insertion_point(field_release:google.protobuf.Method.response_type_url) + return response_type_url_.Release(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArenaForAllocation()); +} +inline void Method::set_allocated_response_type_url(TProtoStringType* response_type_url) { + if (response_type_url != nullptr) { + + } else { + + } + response_type_url_.SetAllocated(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), response_type_url, + GetArenaForAllocation()); +#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING + if (response_type_url_.IsDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited())) { + response_type_url_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation()); + } +#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING + // @@protoc_insertion_point(field_set_allocated:google.protobuf.Method.response_type_url) +} + +// bool response_streaming = 5; +inline void Method::clear_response_streaming() { + response_streaming_ = false; +} +inline bool Method::_internal_response_streaming() const { + return response_streaming_; +} +inline bool Method::response_streaming() const { + // @@protoc_insertion_point(field_get:google.protobuf.Method.response_streaming) + return _internal_response_streaming(); +} +inline void Method::_internal_set_response_streaming(bool value) { + + response_streaming_ = value; +} +inline void Method::set_response_streaming(bool value) { + _internal_set_response_streaming(value); + // @@protoc_insertion_point(field_set:google.protobuf.Method.response_streaming) +} + +// repeated .google.protobuf.Option options = 6; +inline int Method::_internal_options_size() const { + return options_.size(); +} +inline int Method::options_size() const { + return _internal_options_size(); +} +inline ::PROTOBUF_NAMESPACE_ID::Option* Method::mutable_options(int index) { + // @@protoc_insertion_point(field_mutable:google.protobuf.Method.options) + return options_.Mutable(index); +} +inline ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::Option >* +Method::mutable_options() { + // @@protoc_insertion_point(field_mutable_list:google.protobuf.Method.options) + return &options_; +} +inline const ::PROTOBUF_NAMESPACE_ID::Option& Method::_internal_options(int index) const { + return options_.Get(index); +} +inline const ::PROTOBUF_NAMESPACE_ID::Option& Method::options(int index) const { + // @@protoc_insertion_point(field_get:google.protobuf.Method.options) + return _internal_options(index); +} +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 _add; +} +inline const ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::Option >& +Method::options() const { + // @@protoc_insertion_point(field_list:google.protobuf.Method.options) + return options_; +} + +// .google.protobuf.Syntax syntax = 7; +inline void Method::clear_syntax() { + syntax_ = 0; +} +inline ::PROTOBUF_NAMESPACE_ID::Syntax Method::_internal_syntax() const { + return static_cast< ::PROTOBUF_NAMESPACE_ID::Syntax >(syntax_); +} +inline ::PROTOBUF_NAMESPACE_ID::Syntax Method::syntax() const { + // @@protoc_insertion_point(field_get:google.protobuf.Method.syntax) + return _internal_syntax(); +} +inline void Method::_internal_set_syntax(::PROTOBUF_NAMESPACE_ID::Syntax value) { + + syntax_ = value; +} +inline void Method::set_syntax(::PROTOBUF_NAMESPACE_ID::Syntax value) { + _internal_set_syntax(value); + // @@protoc_insertion_point(field_set:google.protobuf.Method.syntax) +} + +// ------------------------------------------------------------------- + +// Mixin + +// string name = 1; +inline void Mixin::clear_name() { + name_.ClearToEmpty(); +} +inline const TProtoStringType& Mixin::name() const { + // @@protoc_insertion_point(field_get:google.protobuf.Mixin.name) + return _internal_name(); +} +template <typename ArgT0, typename... ArgT> +inline PROTOBUF_ALWAYS_INLINE +void Mixin::set_name(ArgT0&& arg0, ArgT... args) { + + name_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, static_cast<ArgT0 &&>(arg0), args..., GetArenaForAllocation()); + // @@protoc_insertion_point(field_set:google.protobuf.Mixin.name) +} +inline TProtoStringType* Mixin::mutable_name() { + TProtoStringType* _s = _internal_mutable_name(); + // @@protoc_insertion_point(field_mutable:google.protobuf.Mixin.name) + return _s; +} +inline const TProtoStringType& Mixin::_internal_name() const { + return name_.Get(); +} +inline void Mixin::_internal_set_name(const TProtoStringType& value) { + + name_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, value, GetArenaForAllocation()); +} +inline TProtoStringType* Mixin::_internal_mutable_name() { + + return name_.Mutable(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, GetArenaForAllocation()); +} +inline TProtoStringType* Mixin::release_name() { + // @@protoc_insertion_point(field_release:google.protobuf.Mixin.name) + return name_.Release(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArenaForAllocation()); +} +inline void Mixin::set_allocated_name(TProtoStringType* name) { + if (name != nullptr) { + + } else { + + } + name_.SetAllocated(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), name, + GetArenaForAllocation()); +#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING + if (name_.IsDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited())) { + name_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation()); + } +#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING + // @@protoc_insertion_point(field_set_allocated:google.protobuf.Mixin.name) +} + +// string root = 2; +inline void Mixin::clear_root() { + root_.ClearToEmpty(); +} +inline const TProtoStringType& Mixin::root() const { + // @@protoc_insertion_point(field_get:google.protobuf.Mixin.root) + return _internal_root(); +} +template <typename ArgT0, typename... ArgT> +inline PROTOBUF_ALWAYS_INLINE +void Mixin::set_root(ArgT0&& arg0, ArgT... args) { + + root_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, static_cast<ArgT0 &&>(arg0), args..., GetArenaForAllocation()); + // @@protoc_insertion_point(field_set:google.protobuf.Mixin.root) +} +inline TProtoStringType* Mixin::mutable_root() { + TProtoStringType* _s = _internal_mutable_root(); + // @@protoc_insertion_point(field_mutable:google.protobuf.Mixin.root) + return _s; +} +inline const TProtoStringType& Mixin::_internal_root() const { + return root_.Get(); +} +inline void Mixin::_internal_set_root(const TProtoStringType& value) { + + root_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, value, GetArenaForAllocation()); +} +inline TProtoStringType* Mixin::_internal_mutable_root() { + + return root_.Mutable(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, GetArenaForAllocation()); +} +inline TProtoStringType* Mixin::release_root() { + // @@protoc_insertion_point(field_release:google.protobuf.Mixin.root) + return root_.Release(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArenaForAllocation()); +} +inline void Mixin::set_allocated_root(TProtoStringType* root) { + if (root != nullptr) { + + } else { + + } + root_.SetAllocated(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), root, + GetArenaForAllocation()); +#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING + if (root_.IsDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited())) { + root_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation()); + } +#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING + // @@protoc_insertion_point(field_set_allocated:google.protobuf.Mixin.root) +} + +#ifdef __GNUC__ + #pragma GCC diagnostic pop +#endif // __GNUC__ +// ------------------------------------------------------------------- + +// ------------------------------------------------------------------- + + +// @@protoc_insertion_point(namespace_scope) + +PROTOBUF_NAMESPACE_CLOSE + +// @@protoc_insertion_point(global_scope) + +#include <google/protobuf/port_undef.inc> +#endif // GOOGLE_PROTOBUF_INCLUDED_GOOGLE_PROTOBUF_INCLUDED_google_2fprotobuf_2fapi_2eproto diff --git a/contrib/libs/protobuf_old/src/google/protobuf/api.proto b/contrib/libs/protobuf_old/src/google/protobuf/api.proto new file mode 100644 index 0000000000..3d598fc859 --- /dev/null +++ b/contrib/libs/protobuf_old/src/google/protobuf/api.proto @@ -0,0 +1,208 @@ +// 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 google.protobuf; + +import "google/protobuf/source_context.proto"; +import "google/protobuf/type.proto"; + +option csharp_namespace = "Google.Protobuf.WellKnownTypes"; +option java_package = "com.google.protobuf"; +option java_outer_classname = "ApiProto"; +option java_multiple_files = true; +option objc_class_prefix = "GPB"; +option go_package = "google.golang.org/protobuf/types/known/apipb"; + +// Api is a light-weight descriptor for an API Interface. +// +// Interfaces are also described as "protocol buffer services" in some contexts, +// such as by the "service" keyword in a .proto file, but they are different +// from API Services, which represent a concrete implementation of an interface +// as opposed to simply a description of methods and bindings. They are also +// sometimes simply referred to as "APIs" in other contexts, such as the name of +// this message itself. See https://cloud.google.com/apis/design/glossary for +// detailed terminology. +message Api { + // The fully qualified name of this interface, including package name + // followed by the interface's simple name. + string name = 1; + + // The methods of this interface, in unspecified order. + repeated Method methods = 2; + + // Any metadata attached to the interface. + repeated Option options = 3; + + // A version string for this interface. If specified, must have the form + // `major-version.minor-version`, as in `1.10`. If the minor version is + // omitted, it defaults to zero. If the entire version field is empty, the + // major version is derived from the package name, as outlined below. If the + // field is not empty, the version in the package name will be verified to be + // consistent with what is provided here. + // + // The versioning schema uses [semantic + // versioning](http://semver.org) where the major version number + // indicates a breaking change and the minor version an additive, + // non-breaking change. Both version numbers are signals to users + // what to expect from different versions, and should be carefully + // chosen based on the product plan. + // + // The major version is also reflected in the package name of the + // interface, which must end in `v<major-version>`, as in + // `google.feature.v1`. For major versions 0 and 1, the suffix can + // be omitted. Zero major versions must only be used for + // experimental, non-GA interfaces. + // + // + string version = 4; + + // Source context for the protocol buffer service represented by this + // message. + SourceContext source_context = 5; + + // Included interfaces. See [Mixin][]. + repeated Mixin mixins = 6; + + // The source syntax of the service. + Syntax syntax = 7; +} + +// Method represents a method of an API interface. +message Method { + // The simple name of this method. + string name = 1; + + // A URL of the input message type. + string request_type_url = 2; + + // If true, the request is streamed. + bool request_streaming = 3; + + // The URL of the output message type. + string response_type_url = 4; + + // If true, the response is streamed. + bool response_streaming = 5; + + // Any metadata attached to the method. + repeated Option options = 6; + + // The source syntax of this method. + Syntax syntax = 7; +} + +// Declares an API Interface to be included in this interface. The including +// interface must redeclare all the methods from the included interface, but +// documentation and options are inherited as follows: +// +// - If after comment and whitespace stripping, the documentation +// string of the redeclared method is empty, it will be inherited +// from the original method. +// +// - Each annotation belonging to the service config (http, +// visibility) which is not set in the redeclared method will be +// inherited. +// +// - If an http annotation is inherited, the path pattern will be +// modified as follows. Any version prefix will be replaced by the +// version of the including interface plus the [root][] path if +// specified. +// +// Example of a simple mixin: +// +// package google.acl.v1; +// service AccessControl { +// // Get the underlying ACL object. +// rpc GetAcl(GetAclRequest) returns (Acl) { +// option (google.api.http).get = "/v1/{resource=**}:getAcl"; +// } +// } +// +// package google.storage.v2; +// service Storage { +// rpc GetAcl(GetAclRequest) returns (Acl); +// +// // Get a data record. +// rpc GetData(GetDataRequest) returns (Data) { +// option (google.api.http).get = "/v2/{resource=**}"; +// } +// } +// +// Example of a mixin configuration: +// +// apis: +// - name: google.storage.v2.Storage +// mixins: +// - name: google.acl.v1.AccessControl +// +// The mixin construct implies that all methods in `AccessControl` are +// also declared with same name and request/response types in +// `Storage`. A documentation generator or annotation processor will +// see the effective `Storage.GetAcl` method after inheriting +// documentation and annotations as follows: +// +// service Storage { +// // Get the underlying ACL object. +// rpc GetAcl(GetAclRequest) returns (Acl) { +// option (google.api.http).get = "/v2/{resource=**}:getAcl"; +// } +// ... +// } +// +// Note how the version in the path pattern changed from `v1` to `v2`. +// +// If the `root` field in the mixin is specified, it should be a +// relative path under which inherited HTTP paths are placed. Example: +// +// apis: +// - name: google.storage.v2.Storage +// mixins: +// - name: google.acl.v1.AccessControl +// root: acls +// +// This implies the following inherited HTTP annotation: +// +// service Storage { +// // Get the underlying ACL object. +// rpc GetAcl(GetAclRequest) returns (Acl) { +// option (google.api.http).get = "/v2/acls/{resource=**}:getAcl"; +// } +// ... +// } +message Mixin { + // The fully qualified name of the interface which is included. + string name = 1; + + // If non-empty specifies a path under which inherited HTTP paths + // are rooted. + string root = 2; +} diff --git a/contrib/libs/protobuf_old/src/google/protobuf/arena.cc b/contrib/libs/protobuf_old/src/google/protobuf/arena.cc new file mode 100644 index 0000000000..e3047f9669 --- /dev/null +++ b/contrib/libs/protobuf_old/src/google/protobuf/arena.cc @@ -0,0 +1,511 @@ +// 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 <google/protobuf/arena.h> + +#include <algorithm> +#include <atomic> +#include <cstddef> +#include <cstdint> +#include <limits> +#include <typeinfo> + +#include <google/protobuf/arena_impl.h> + +#include <google/protobuf/stubs/mutex.h> +#ifdef ADDRESS_SANITIZER +#include <sanitizer/asan_interface.h> +#endif // ADDRESS_SANITIZER + +#include <google/protobuf/port_def.inc> + +namespace google { +namespace protobuf { +namespace internal { + +static SerialArena::Memory AllocateMemory(const AllocationPolicy* policy_ptr, + size_t last_size, size_t min_bytes) { + AllocationPolicy policy; // default policy + if (policy_ptr) policy = *policy_ptr; + size_t size; + if (last_size != 0) { + // Double the current block size, up to a limit. + auto max_size = policy.max_block_size; + size = std::min(2 * last_size, max_size); + } else { + size = policy.start_block_size; + } + // Verify that min_bytes + kBlockHeaderSize won't overflow. + GOOGLE_CHECK_LE(min_bytes, + std::numeric_limits<size_t>::max() - SerialArena::kBlockHeaderSize); + size = std::max(size, SerialArena::kBlockHeaderSize + min_bytes); + + void* mem; + if (policy.block_alloc == nullptr) { + mem = ::operator new(size); + } else { + mem = policy.block_alloc(size); + } + return {mem, size}; +} + +class GetDeallocator { + public: + GetDeallocator(const AllocationPolicy* policy, size_t* space_allocated) + : dealloc_(policy ? policy->block_dealloc : nullptr), + space_allocated_(space_allocated) {} + + void operator()(SerialArena::Memory mem) const { +#ifdef ADDRESS_SANITIZER + // This memory was provided by the underlying allocator as unpoisoned, + // so return it in an unpoisoned state. + ASAN_UNPOISON_MEMORY_REGION(mem.ptr, mem.size); +#endif // ADDRESS_SANITIZER + if (dealloc_) { + dealloc_(mem.ptr, mem.size); + } else { +#if defined(__GXX_DELETE_WITH_SIZE__) || defined(__cpp_sized_deallocation) + ::operator delete(mem.ptr, mem.size); +#else + ::operator delete(mem.ptr); +#endif + } + *space_allocated_ += mem.size; + } + + private: + void (*dealloc_)(void*, size_t); + size_t* space_allocated_; +}; + +SerialArena::SerialArena(Block* b, void* owner) : space_allocated_(b->size) { + owner_ = owner; + head_ = b; + ptr_ = b->Pointer(kBlockHeaderSize + ThreadSafeArena::kSerialArenaSize); + limit_ = b->Pointer(b->size & static_cast<size_t>(-8)); +} + +SerialArena* SerialArena::New(Memory mem, void* owner) { + GOOGLE_DCHECK_LE(kBlockHeaderSize + ThreadSafeArena::kSerialArenaSize, mem.size); + + auto b = new (mem.ptr) Block{nullptr, mem.size}; + return new (b->Pointer(kBlockHeaderSize)) SerialArena(b, owner); +} + +template <typename Deallocator> +SerialArena::Memory SerialArena::Free(Deallocator deallocator) { + Block* b = head_; + Memory mem = {b, b->size}; + while (b->next) { + b = b->next; // We must first advance before deleting this block + deallocator(mem); + mem = {b, b->size}; + } + return mem; +} + +PROTOBUF_NOINLINE +std::pair<void*, SerialArena::CleanupNode*> +SerialArena::AllocateAlignedWithCleanupFallback( + size_t n, const AllocationPolicy* policy) { + AllocateNewBlock(n + kCleanupSize, policy); + return AllocateFromExistingWithCleanupFallback(n); +} + +PROTOBUF_NOINLINE +void* SerialArena::AllocateAlignedFallback(size_t n, + const AllocationPolicy* policy) { + AllocateNewBlock(n, policy); + return AllocateFromExisting(n); +} + +void SerialArena::AllocateNewBlock(size_t n, const AllocationPolicy* policy) { + // Sync limit to block + head_->start = reinterpret_cast<CleanupNode*>(limit_); + + // Record how much used in this block. + space_used_ += ptr_ - head_->Pointer(kBlockHeaderSize); + + auto mem = AllocateMemory(policy, head_->size, n); + // We don't want to emit an expensive RMW instruction that requires + // exclusive access to a cacheline. Hence we write it in terms of a + // regular add. + auto relaxed = std::memory_order_relaxed; + space_allocated_.store(space_allocated_.load(relaxed) + mem.size, relaxed); + head_ = new (mem.ptr) Block{head_, mem.size}; + ptr_ = head_->Pointer(kBlockHeaderSize); + limit_ = head_->Pointer(head_->size); + +#ifdef ADDRESS_SANITIZER + ASAN_POISON_MEMORY_REGION(ptr_, limit_ - ptr_); +#endif // ADDRESS_SANITIZER +} + +arc_ui64 SerialArena::SpaceUsed() const { + arc_ui64 space_used = ptr_ - head_->Pointer(kBlockHeaderSize); + space_used += space_used_; + // Remove the overhead of the SerialArena itself. + space_used -= ThreadSafeArena::kSerialArenaSize; + return space_used; +} + +void SerialArena::CleanupList() { + Block* b = head_; + b->start = reinterpret_cast<CleanupNode*>(limit_); + do { + auto* limit = reinterpret_cast<CleanupNode*>( + b->Pointer(b->size & static_cast<size_t>(-8))); + auto it = b->start; + auto num = limit - it; + if (num > 0) { + for (; it < limit; it++) { + it->cleanup(it->elem); + } + } + b = b->next; + } while (b); +} + + +ThreadSafeArena::CacheAlignedLifecycleIdGenerator + ThreadSafeArena::lifecycle_id_generator_; +#if defined(GOOGLE_PROTOBUF_NO_THREADLOCAL) +ThreadSafeArena::ThreadCache& ThreadSafeArena::thread_cache() { + static internal::ThreadLocalStorage<ThreadCache>* thread_cache_ = + new internal::ThreadLocalStorage<ThreadCache>(); + return *thread_cache_->Get(); +} +#elif defined(PROTOBUF_USE_DLLS) +ThreadSafeArena::ThreadCache& ThreadSafeArena::thread_cache() { + static PROTOBUF_THREAD_LOCAL ThreadCache thread_cache_ = { + 0, static_cast<LifecycleIdAtomic>(-1), nullptr}; + return thread_cache_; +} +#else +PROTOBUF_THREAD_LOCAL ThreadSafeArena::ThreadCache + ThreadSafeArena::thread_cache_ = {0, static_cast<LifecycleIdAtomic>(-1), + nullptr}; +#endif + +void ThreadSafeArena::InitializeFrom(void* mem, size_t size) { + GOOGLE_DCHECK_EQ(reinterpret_cast<uintptr_t>(mem) & 7, 0u); + GOOGLE_DCHECK(!AllocPolicy()); // Reset should call InitializeWithPolicy instead. + Init(); + + // Ignore initial block if it is too small. + if (mem != nullptr && size >= kBlockHeaderSize + kSerialArenaSize) { + alloc_policy_.set_is_user_owned_initial_block(true); + SetInitialBlock(mem, size); + } +} + +void ThreadSafeArena::InitializeWithPolicy(void* mem, size_t size, + AllocationPolicy policy) { +#ifndef NDEBUG + const arc_ui64 old_alloc_policy = alloc_policy_.get_raw(); + // If there was a policy (e.g., in Reset()), make sure flags were preserved. +#define GOOGLE_DCHECK_POLICY_FLAGS_() \ + if (old_alloc_policy > 3) \ + GOOGLE_CHECK_EQ(old_alloc_policy & 3, alloc_policy_.get_raw() & 3) +#else +#define GOOGLE_DCHECK_POLICY_FLAGS_() +#endif // NDEBUG + + if (policy.IsDefault()) { + // Legacy code doesn't use the API above, but provides the initial block + // through ArenaOptions. I suspect most do not touch the allocation + // policy parameters. + InitializeFrom(mem, size); + GOOGLE_DCHECK_POLICY_FLAGS_(); + return; + } + GOOGLE_DCHECK_EQ(reinterpret_cast<uintptr_t>(mem) & 7, 0u); + Init(); + + // Ignore initial block if it is too small. We include an optional + // AllocationPolicy in this check, so that this can be allocated on the + // first block. + constexpr size_t kAPSize = internal::AlignUpTo8(sizeof(AllocationPolicy)); + constexpr size_t kMinimumSize = kBlockHeaderSize + kSerialArenaSize + kAPSize; + + // The value for alloc_policy_ stores whether or not allocations should be + // recorded. + alloc_policy_.set_should_record_allocs( + policy.metrics_collector != nullptr && + policy.metrics_collector->RecordAllocs()); + // Make sure we have an initial block to store the AllocationPolicy. + if (mem != nullptr && size >= kMinimumSize) { + alloc_policy_.set_is_user_owned_initial_block(true); + } else { + auto tmp = AllocateMemory(&policy, 0, kMinimumSize); + mem = tmp.ptr; + size = tmp.size; + } + SetInitialBlock(mem, size); + + auto sa = threads_.load(std::memory_order_relaxed); + // We ensured enough space so this cannot fail. + void* p; + if (!sa || !sa->MaybeAllocateAligned(kAPSize, &p)) { + GOOGLE_LOG(FATAL) << "MaybeAllocateAligned cannot fail here."; + return; + } + new (p) AllocationPolicy{policy}; + // Low bits store flags, so they mustn't be overwritten. + GOOGLE_DCHECK_EQ(0, reinterpret_cast<uintptr_t>(p) & 3); + alloc_policy_.set_policy(reinterpret_cast<AllocationPolicy*>(p)); + GOOGLE_DCHECK_POLICY_FLAGS_(); + +#undef GOOGLE_DCHECK_POLICY_FLAGS_ +} + +void ThreadSafeArena::Init() { +#ifndef NDEBUG + const bool was_message_owned = IsMessageOwned(); +#endif // NDEBUG + ThreadCache& tc = thread_cache(); + auto id = tc.next_lifecycle_id; + // We increment lifecycle_id's by multiples of two so we can use bit 0 as + // a tag. + constexpr arc_ui64 kDelta = 2; + constexpr arc_ui64 kInc = ThreadCache::kPerThreadIds * kDelta; + if (PROTOBUF_PREDICT_FALSE((id & (kInc - 1)) == 0)) { + constexpr auto relaxed = std::memory_order_relaxed; + // On platforms that don't support arc_ui64 atomics we can certainly not + // afford to increment by large intervals and expect uniqueness due to + // wrapping, hence we only add by 1. + id = lifecycle_id_generator_.id.fetch_add(1, relaxed) * kInc; + } + tc.next_lifecycle_id = id + kDelta; + // Message ownership is stored in tag_and_id_, and is set in the constructor. + // This flag bit must be preserved, even across calls to Reset(). + tag_and_id_ = id | (tag_and_id_ & kMessageOwnedArena); + hint_.store(nullptr, std::memory_order_relaxed); + threads_.store(nullptr, std::memory_order_relaxed); +#ifndef NDEBUG + GOOGLE_CHECK_EQ(was_message_owned, IsMessageOwned()); +#endif // NDEBUG +} + +void ThreadSafeArena::SetInitialBlock(void* mem, size_t size) { + SerialArena* serial = SerialArena::New({mem, size}, &thread_cache()); + serial->set_next(NULL); + threads_.store(serial, std::memory_order_relaxed); + CacheSerialArena(serial); +} + +ThreadSafeArena::~ThreadSafeArena() { + // Have to do this in a first pass, because some of the destructors might + // refer to memory in other blocks. + CleanupList(); + + size_t space_allocated = 0; + auto mem = Free(&space_allocated); + + // Policy is about to get deleted. + auto* p = alloc_policy_.get(); + ArenaMetricsCollector* collector = p ? p->metrics_collector : nullptr; + + if (alloc_policy_.is_user_owned_initial_block()) { + space_allocated += mem.size; + } else { + GetDeallocator(alloc_policy_.get(), &space_allocated)(mem); + } + + if (collector) collector->OnDestroy(space_allocated); +} + +SerialArena::Memory ThreadSafeArena::Free(size_t* space_allocated) { + SerialArena::Memory mem = {nullptr, 0}; + auto deallocator = GetDeallocator(alloc_policy_.get(), space_allocated); + PerSerialArena([deallocator, &mem](SerialArena* a) { + if (mem.ptr) deallocator(mem); + mem = a->Free(deallocator); + }); + return mem; +} + +arc_ui64 ThreadSafeArena::Reset() { + // Have to do this in a first pass, because some of the destructors might + // refer to memory in other blocks. + CleanupList(); + + // Discard all blocks except the special block (if present). + size_t space_allocated = 0; + auto mem = Free(&space_allocated); + + AllocationPolicy* policy = alloc_policy_.get(); + if (policy) { + auto saved_policy = *policy; + if (alloc_policy_.is_user_owned_initial_block()) { + space_allocated += mem.size; + } else { + GetDeallocator(alloc_policy_.get(), &space_allocated)(mem); + mem.ptr = nullptr; + mem.size = 0; + } + ArenaMetricsCollector* collector = saved_policy.metrics_collector; + if (collector) collector->OnReset(space_allocated); + InitializeWithPolicy(mem.ptr, mem.size, saved_policy); + } else { + GOOGLE_DCHECK(!alloc_policy_.should_record_allocs()); + // Nullptr policy + if (alloc_policy_.is_user_owned_initial_block()) { + space_allocated += mem.size; + InitializeFrom(mem.ptr, mem.size); + } else { + GetDeallocator(alloc_policy_.get(), &space_allocated)(mem); + Init(); + } + } + + return space_allocated; +} + +std::pair<void*, SerialArena::CleanupNode*> +ThreadSafeArena::AllocateAlignedWithCleanup(size_t n, + const std::type_info* type) { + SerialArena* arena; + if (PROTOBUF_PREDICT_TRUE(!alloc_policy_.should_record_allocs() && + GetSerialArenaFast(&arena))) { + return arena->AllocateAlignedWithCleanup(n, alloc_policy_.get()); + } else { + return AllocateAlignedWithCleanupFallback(n, type); + } +} + +void ThreadSafeArena::AddCleanup(void* elem, void (*cleanup)(void*)) { + SerialArena* arena; + if (PROTOBUF_PREDICT_FALSE(!GetSerialArenaFast(&arena))) { + arena = GetSerialArenaFallback(&thread_cache()); + } + arena->AddCleanup(elem, cleanup, AllocPolicy()); +} + +PROTOBUF_NOINLINE +void* ThreadSafeArena::AllocateAlignedFallback(size_t n, + const std::type_info* type) { + if (alloc_policy_.should_record_allocs()) { + alloc_policy_.RecordAlloc(type, n); + SerialArena* arena; + if (PROTOBUF_PREDICT_TRUE(GetSerialArenaFast(&arena))) { + return arena->AllocateAligned(n, alloc_policy_.get()); + } + } + return GetSerialArenaFallback(&thread_cache()) + ->AllocateAligned(n, alloc_policy_.get()); +} + +PROTOBUF_NOINLINE +std::pair<void*, SerialArena::CleanupNode*> +ThreadSafeArena::AllocateAlignedWithCleanupFallback( + size_t n, const std::type_info* type) { + if (alloc_policy_.should_record_allocs()) { + alloc_policy_.RecordAlloc(type, n); + SerialArena* arena; + if (GetSerialArenaFast(&arena)) { + return arena->AllocateAlignedWithCleanup(n, alloc_policy_.get()); + } + } + return GetSerialArenaFallback(&thread_cache()) + ->AllocateAlignedWithCleanup(n, alloc_policy_.get()); +} + +arc_ui64 ThreadSafeArena::SpaceAllocated() const { + SerialArena* serial = threads_.load(std::memory_order_acquire); + arc_ui64 res = 0; + for (; serial; serial = serial->next()) { + res += serial->SpaceAllocated(); + } + return res; +} + +arc_ui64 ThreadSafeArena::SpaceUsed() const { + SerialArena* serial = threads_.load(std::memory_order_acquire); + arc_ui64 space_used = 0; + for (; serial; serial = serial->next()) { + space_used += serial->SpaceUsed(); + } + return space_used - (alloc_policy_.get() ? sizeof(AllocationPolicy) : 0); +} + +void ThreadSafeArena::CleanupList() { + PerSerialArena([](SerialArena* a) { a->CleanupList(); }); +} + +PROTOBUF_NOINLINE +SerialArena* ThreadSafeArena::GetSerialArenaFallback(void* me) { + // Look for this SerialArena in our linked list. + SerialArena* serial = threads_.load(std::memory_order_acquire); + for (; serial; serial = serial->next()) { + if (serial->owner() == me) { + break; + } + } + + if (!serial) { + // This thread doesn't have any SerialArena, which also means it doesn't + // have any blocks yet. So we'll allocate its first block now. + serial = SerialArena::New( + AllocateMemory(alloc_policy_.get(), 0, kSerialArenaSize), me); + + SerialArena* head = threads_.load(std::memory_order_relaxed); + do { + serial->set_next(head); + } while (!threads_.compare_exchange_weak( + head, serial, std::memory_order_release, std::memory_order_relaxed)); + } + + CacheSerialArena(serial); + return serial; +} + +} // namespace internal + +PROTOBUF_FUNC_ALIGN(32) +void* Arena::AllocateAlignedNoHook(size_t n) { + return impl_.AllocateAligned(n, nullptr); +} + +PROTOBUF_FUNC_ALIGN(32) +void* Arena::AllocateAlignedWithHook(size_t n, const std::type_info* type) { + return impl_.AllocateAligned(n, type); +} + +PROTOBUF_FUNC_ALIGN(32) +std::pair<void*, internal::SerialArena::CleanupNode*> +Arena::AllocateAlignedWithCleanup(size_t n, const std::type_info* type) { + return impl_.AllocateAlignedWithCleanup(n, type); +} + +} // namespace protobuf +} // namespace google + +#include <google/protobuf/port_undef.inc> diff --git a/contrib/libs/protobuf_old/src/google/protobuf/arena.h b/contrib/libs/protobuf_old/src/google/protobuf/arena.h new file mode 100644 index 0000000000..7763d7aa5f --- /dev/null +++ b/contrib/libs/protobuf_old/src/google/protobuf/arena.h @@ -0,0 +1,821 @@ +// 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 defines an Arena allocator for better allocation performance. + +#ifndef GOOGLE_PROTOBUF_ARENA_H__ +#define GOOGLE_PROTOBUF_ARENA_H__ + + +#include <limits> +#include <type_traits> +#include <utility> +#ifdef max +#undef max // Visual Studio defines this macro +#endif +#if defined(_MSC_VER) && !defined(_LIBCPP_STD_VER) && !_HAS_EXCEPTIONS +// Work around bugs in MSVC <typeinfo> header when _HAS_EXCEPTIONS=0. +#include <exception> +#include <typeinfo> +namespace std { +using type_info = ::type_info; +} +#else +#include <typeinfo> +#endif + +#include <type_traits> +#include <google/protobuf/arena_impl.h> +#include <google/protobuf/port.h> + +#include <google/protobuf/port_def.inc> + +#ifdef SWIG +#error "You cannot SWIG proto headers" +#endif + +namespace google { +namespace protobuf { + +struct ArenaOptions; // defined below +class Arena; // defined below +class Message; // defined in message.h +class MessageLite; +template <typename Key, typename T> +class Map; + +namespace arena_metrics { + +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 +class InlinedStringField; // defined in inlined_string_field.h +class LazyField; // defined in lazy_field.h +class EpsCopyInputStream; // defined in parse_context.h + +template <typename Type> +class GenericTypeHandler; // defined in repeated_field.h + +inline PROTOBUF_ALWAYS_INLINE +void* AlignTo(void* ptr, size_t align) { + return reinterpret_cast<void*>( + (reinterpret_cast<uintptr_t>(ptr) + align - 1) & (~align + 1)); +} + +// Templated cleanup methods. +template <typename T> +void arena_destruct_object(void* object) { + reinterpret_cast<T*>(object)->~T(); +} + +template <bool destructor_skippable, typename T> +struct ObjectDestructor { + constexpr static void (*destructor)(void*) = &arena_destruct_object<T>; +}; + +template <typename T> +struct ObjectDestructor<true, T> { + constexpr static void (*destructor)(void*) = nullptr; +}; + +template <typename T> +void arena_delete_object(void* object) { + delete reinterpret_cast<T*>(object); +} +} // namespace internal + +// ArenaOptions provides optional additional parameters to arena construction +// that control its block-allocation behavior. +struct ArenaOptions { + // This defines the size of the first block requested from the system malloc. + // Subsequent block sizes will increase in a geometric series up to a maximum. + size_t start_block_size; + + // This defines the maximum block size requested from system malloc (unless an + // individual arena allocation request occurs with a size larger than this + // maximum). Requested block sizes increase up to this value, then remain + // here. + size_t max_block_size; + + // An initial block of memory for the arena to use, or NULL for none. If + // provided, the block must live at least as long as the arena itself. The + // creator of the Arena retains ownership of the block after the Arena is + // destroyed. + char* initial_block; + + // The size of the initial block, if provided. + size_t initial_block_size; + + // A function pointer to an alloc method that returns memory blocks of size + // requested. By default, it contains a ptr to the malloc function. + // + // NOTE: block_alloc and dealloc functions are expected to behave like + // malloc and free, including Asan poisoning. + void* (*block_alloc)(size_t); + // A function pointer to a dealloc method that takes ownership of the blocks + // from the arena. By default, it contains a ptr to a wrapper function that + // calls free. + void (*block_dealloc)(void*, size_t); + + ArenaOptions() + : start_block_size(internal::AllocationPolicy::kDefaultStartBlockSize), + max_block_size(internal::AllocationPolicy::kDefaultMaxBlockSize), + initial_block(NULL), + initial_block_size(0), + block_alloc(nullptr), + block_dealloc(nullptr), + make_metrics_collector(nullptr) {} + + private: + // If make_metrics_collector is not nullptr, it will be called at Arena init + // time. It may return a pointer to a collector instance that will be notified + // of interesting events related to the arena. + internal::ArenaMetricsCollector* (*make_metrics_collector)(); + + internal::ArenaMetricsCollector* MetricsCollector() const { + return make_metrics_collector ? (*make_metrics_collector)() : nullptr; + } + + internal::AllocationPolicy AllocationPolicy() const { + internal::AllocationPolicy res; + res.start_block_size = start_block_size; + res.max_block_size = max_block_size; + res.block_alloc = block_alloc; + res.block_dealloc = block_dealloc; + res.metrics_collector = MetricsCollector(); + return res; + } + + friend void arena_metrics::EnableArenaMetrics(ArenaOptions*); + + friend class Arena; + friend class ArenaOptionsTestFriend; +}; + +// Support for non-RTTI environments. (The metrics hooks API uses type +// information.) +#if PROTOBUF_RTTI +#define RTTI_TYPE_ID(type) (&typeid(type)) +#else +#define RTTI_TYPE_ID(type) (NULL) +#endif + +// Arena allocator. Arena allocation replaces ordinary (heap-based) allocation +// with new/delete, and improves performance by aggregating allocations into +// larger blocks and freeing allocations all at once. Protocol messages are +// allocated on an arena by using Arena::CreateMessage<T>(Arena*), below, and +// are automatically freed when the arena is destroyed. +// +// This is a thread-safe implementation: multiple threads may allocate from the +// arena concurrently. Destruction is not thread-safe and the destructing +// thread must synchronize with users of the arena first. +// +// An arena provides two allocation interfaces: CreateMessage<T>, which works +// for arena-enabled proto2 message types as well as other types that satisfy +// the appropriate protocol (described below), and Create<T>, which works for +// any arbitrary type T. CreateMessage<T> is better when the type T supports it, +// because this interface (i) passes the arena pointer to the created object so +// that its sub-objects and internal allocations can use the arena too, and (ii) +// elides the object's destructor call when possible. Create<T> does not place +// any special requirements on the type T, and will invoke the object's +// destructor when the arena is destroyed. +// +// The arena message allocation protocol, required by +// CreateMessage<T>(Arena* arena, Args&&... args), is as follows: +// +// - The type T must have (at least) two constructors: a constructor callable +// with `args` (without `arena`), called when a T is allocated on the heap; +// and a constructor callable with `Arena* arena, Args&&... args`, called when +// a T is allocated on an arena. If the second constructor is called with a +// NULL arena pointer, it must be equivalent to invoking the first +// (`args`-only) constructor. +// +// - The type T must have a particular type trait: a nested type +// |InternalArenaConstructable_|. This is usually a typedef to |void|. If no +// such type trait exists, then the instantiation CreateMessage<T> will fail +// to compile. +// +// - The type T *may* have the type trait |DestructorSkippable_|. If this type +// trait is present in the type, then its destructor will not be called if and +// only if it was passed a non-NULL arena pointer. If this type trait is not +// present on the type, then its destructor is always called when the +// containing arena is destroyed. +// +// This protocol is implemented by all arena-enabled proto2 message classes as +// well as protobuf container types like RepeatedPtrField and Map. The protocol +// is internal to protobuf and is not guaranteed to be stable. Non-proto types +// should not rely on this protocol. +class PROTOBUF_EXPORT PROTOBUF_ALIGNAS(8) Arena { + public: + // Default constructor with sensible default options, tuned for average + // use-cases. + inline Arena() : impl_() {} + + // Construct an arena with default options, except for the supplied + // initial block. It is more efficient to use this constructor + // instead of passing ArenaOptions if the only configuration needed + // by the caller is supplying an initial block. + inline Arena(char* initial_block, size_t initial_block_size) + : impl_(initial_block, initial_block_size) {} + + // Arena constructor taking custom options. See ArenaOptions above for + // descriptions of the options available. + explicit Arena(const ArenaOptions& options) + : impl_(options.initial_block, options.initial_block_size, + options.AllocationPolicy()) {} + + // Block overhead. Use this as a guide for how much to over-allocate the + // initial block if you want an allocation of size N to fit inside it. + // + // WARNING: if you allocate multiple objects, it is difficult to guarantee + // that a series of allocations will fit in the initial block, especially if + // Arena changes its alignment guarantees in the future! + static const size_t kBlockOverhead = + internal::ThreadSafeArena::kBlockHeaderSize + + internal::ThreadSafeArena::kSerialArenaSize; + + inline ~Arena() {} + + // TODO(protobuf-team): Fix callers to use constructor and delete this method. + void Init(const ArenaOptions&) {} + + // API to create proto2 message objects on the arena. If the arena passed in + // is NULL, then a heap allocated object is returned. Type T must be a message + // defined in a .proto file with cc_enable_arenas set to true, otherwise a + // compilation error will occur. + // + // RepeatedField and RepeatedPtrField may also be instantiated directly on an + // arena with this method. + // + // This function also accepts any type T that satisfies the arena message + // allocation protocol, documented above. + template <typename T, typename... Args> + PROTOBUF_ALWAYS_INLINE static T* CreateMessage(Arena* arena, Args&&... args) { + static_assert( + InternalHelper<T>::is_arena_constructable::value, + "CreateMessage can only construct types that are ArenaConstructable"); + // We must delegate to CreateMaybeMessage() and NOT CreateMessageInternal() + // because protobuf generated classes specialize CreateMaybeMessage() and we + // need to use that specialization for code size reasons. + return Arena::CreateMaybeMessage<T>(arena, static_cast<Args&&>(args)...); + } + + // API to create any objects on the arena. Note that only the object will + // be created on the arena; the underlying ptrs (in case of a proto2 message) + // will be still heap allocated. Proto messages should usually be allocated + // with CreateMessage<T>() instead. + // + // Note that even if T satisfies the arena message construction protocol + // (InternalArenaConstructable_ trait and optional DestructorSkippable_ + // trait), as described above, this function does not follow the protocol; + // instead, it treats T as a black-box type, just as if it did not have these + // traits. Specifically, T's constructor arguments will always be only those + // passed to Create<T>() -- no additional arena pointer is implicitly added. + // Furthermore, the destructor will always be called at arena destruction time + // (unless the destructor is trivial). Hence, from T's point of view, it is as + // if the object were allocated on the heap (except that the underlying memory + // is obtained from the arena). + template <typename T, typename... Args> + PROTOBUF_NDEBUG_INLINE static T* Create(Arena* arena, Args&&... args) { + return CreateInternal<T>(arena, std::is_convertible<T*, MessageLite*>(), + static_cast<Args&&>(args)...); + } + + // Create an array of object type T on the arena *without* invoking the + // constructor of T. If `arena` is null, then the return value should be freed + // with `delete[] x;` (or `::operator delete[](x);`). + // To ensure safe uses, this function checks at compile time + // (when compiled as C++11) that T is trivially default-constructible and + // trivially destructible. + template <typename T> + PROTOBUF_NDEBUG_INLINE static T* CreateArray(Arena* arena, + size_t num_elements) { + static_assert(std::is_trivial<T>::value, + "CreateArray requires a trivially constructible type"); + static_assert(std::is_trivially_destructible<T>::value, + "CreateArray requires a trivially destructible type"); + GOOGLE_CHECK_LE(num_elements, std::numeric_limits<size_t>::max() / sizeof(T)) + << "Requested size is too large to fit into size_t."; + if (arena == NULL) { + return static_cast<T*>(::operator new[](num_elements * sizeof(T))); + } else { + return arena->CreateInternalRawArray<T>(num_elements); + } + } + + // The following are routines are for monitoring. They will approximate the + // total sum allocated and used memory, but the exact value is an + // implementation deal. For instance allocated space depends on growth + // policies. Do not use these in unit tests. + // Returns the total space allocated by the arena, which is the sum of the + // sizes of the underlying blocks. + arc_ui64 SpaceAllocated() const { return impl_.SpaceAllocated(); } + // Returns the total space used by the arena. Similar to SpaceAllocated but + // does not include free space and block overhead. The total space returned + // may not include space used by other threads executing concurrently with + // the call to this method. + arc_ui64 SpaceUsed() const { return impl_.SpaceUsed(); } + + // Frees all storage allocated by this arena after calling destructors + // registered with OwnDestructor() and freeing objects registered with Own(). + // Any objects allocated on this arena are unusable after this call. It also + // returns the total space used by the arena which is the sums of the sizes + // of the allocated blocks. This method is not thread-safe. + arc_ui64 Reset() { return impl_.Reset(); } + + // Adds |object| to a list of heap-allocated objects to be freed with |delete| + // when the arena is destroyed or reset. + template <typename T> + PROTOBUF_ALWAYS_INLINE void Own(T* object) { + OwnInternal(object, std::is_convertible<T*, MessageLite*>()); + } + + // Adds |object| to a list of objects whose destructors will be manually + // called when the arena is destroyed or reset. This differs from Own() in + // that it does not free the underlying memory with |delete|; hence, it is + // normally only used for objects that are placement-newed into + // arena-allocated memory. + template <typename T> + PROTOBUF_ALWAYS_INLINE void OwnDestructor(T* object) { + if (object != NULL) { + impl_.AddCleanup(object, &internal::arena_destruct_object<T>); + } + } + + // Adds a custom member function on an object to the list of destructors that + // will be manually called when the arena is destroyed or reset. This differs + // from OwnDestructor() in that any member function may be specified, not only + // the class destructor. + PROTOBUF_ALWAYS_INLINE void OwnCustomDestructor(void* object, + void (*destruct)(void*)) { + impl_.AddCleanup(object, destruct); + } + + // Retrieves the arena associated with |value| if |value| is an arena-capable + // message, or NULL otherwise. If possible, the call resolves at compile time. + // Note that we can often devirtualize calls to `value->GetArena()` so usually + // calling this method is unnecessary. + template <typename T> + PROTOBUF_ALWAYS_INLINE static Arena* GetArena(const T* value) { + return GetArenaInternal(value); + } + + template <typename T> + class InternalHelper { + public: + // Provides access to protected GetOwningArena to generated messages. + static Arena* GetOwningArena(const T* p) { return p->GetOwningArena(); } + + // Provides access to protected GetArenaForAllocation to generated messages. + static Arena* GetArenaForAllocation(const T* p) { + return GetArenaForAllocationInternal( + p, std::is_convertible<T*, MessageLite*>()); + } + + // Creates message-owned arena. + static Arena* CreateMessageOwnedArena() { + return new Arena(internal::MessageOwned{}); + } + + // Checks whether the given arena is message-owned. + static bool IsMessageOwnedArena(Arena* arena) { + return arena->IsMessageOwned(); + } + + 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> + static double DestructorSkippable(...); + + typedef std::integral_constant< + bool, sizeof(DestructorSkippable<T>(static_cast<const T*>(0))) == + sizeof(char) || + std::is_trivially_destructible<T>::value> + is_destructor_skippable; + + template <typename U> + static char ArenaConstructable( + const typename U::InternalArenaConstructable_*); + template <typename U> + static double ArenaConstructable(...); + + typedef std::integral_constant<bool, sizeof(ArenaConstructable<T>( + static_cast<const T*>(0))) == + sizeof(char)> + is_arena_constructable; + + template <typename U, + typename std::enable_if< + std::is_same<Arena*, decltype(std::declval<const U>() + .GetArena())>::value, + int>::type = 0> + static char HasGetArena(decltype(&U::GetArena)); + template <typename U> + static double HasGetArena(...); + + typedef std::integral_constant<bool, sizeof(HasGetArena<T>(nullptr)) == + sizeof(char)> + has_get_arena; + + template <typename... Args> + static T* Construct(void* ptr, Args&&... args) { + return new (ptr) T(static_cast<Args&&>(args)...); + } + + static inline PROTOBUF_ALWAYS_INLINE T* New() { + return new T(nullptr); + } + + 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 + // time. This is public only to allow construction of higher-level templated + // utilities. + // + // is_arena_constructable<T>::value is true if the message type T has arena + // support enabled, and false otherwise. + // + // is_destructor_skippable<T>::value is true if the message type T has told + // the arena that it is safe to skip the destructor, and false otherwise. + // + // This is inside Arena because only Arena has the friend relationships + // necessary to see the underlying generated code traits. + template <typename T> + struct is_arena_constructable : InternalHelper<T>::is_arena_constructable {}; + template <typename T> + struct is_destructor_skippable : InternalHelper<T>::is_destructor_skippable { + }; + + private: + internal::ThreadSafeArena impl_; + + template <typename T> + struct has_get_arena : InternalHelper<T>::has_get_arena {}; + + // Constructor solely used by message-owned arena. + inline Arena(internal::MessageOwned) : impl_(internal::MessageOwned{}) {} + + // Checks whether this arena is message-owned. + PROTOBUF_ALWAYS_INLINE bool IsMessageOwned() const { + return impl_.IsMessageOwned(); + } + + template <typename T, typename... Args> + PROTOBUF_NDEBUG_INLINE static T* CreateMessageInternal(Arena* arena, + Args&&... args) { + static_assert( + InternalHelper<T>::is_arena_constructable::value, + "CreateMessage can only construct types that are ArenaConstructable"); + if (arena == NULL) { + return new T(nullptr, static_cast<Args&&>(args)...); + } else { + return arena->DoCreateMessage<T>(static_cast<Args&&>(args)...); + } + } + + // This specialization for no arguments is necessary, because its behavior is + // slightly different. When the arena pointer is nullptr, it calls T() + // instead of T(nullptr). + template <typename T> + PROTOBUF_NDEBUG_INLINE static T* CreateMessageInternal(Arena* arena) { + static_assert( + InternalHelper<T>::is_arena_constructable::value, + "CreateMessage can only construct types that are ArenaConstructable"); + if (arena == NULL) { + // Generated arena constructor T(Arena*) is protected. Call via + // InternalHelper. + return InternalHelper<T>::New(); + } else { + return arena->DoCreateMessage<T>(); + } + } + + // Allocate and also optionally call collector with the allocated type info + // when allocation recording is enabled. + PROTOBUF_NDEBUG_INLINE void* AllocateInternal(size_t size, size_t align, + void (*destructor)(void*), + const std::type_info* type) { + // Monitor allocation if needed. + if (destructor == nullptr) { + return AllocateAlignedWithHook(size, align, type); + } else { + if (align <= 8) { + auto res = AllocateAlignedWithCleanup(internal::AlignUpTo8(size), type); + res.second->elem = res.first; + res.second->cleanup = destructor; + return res.first; + } else { + auto res = AllocateAlignedWithCleanup(size + align - 8, type); + auto ptr = internal::AlignTo(res.first, align); + res.second->elem = ptr; + res.second->cleanup = destructor; + return ptr; + } + } + } + + // CreateMessage<T> requires that T supports arenas, but this private method + // works whether or not T supports arenas. These are not exposed to user code + // as it can cause confusing API usages, and end up having double free in + // user code. These are used only internally from LazyField and Repeated + // fields, since they are designed to work in all mode combinations. + template <typename Msg, typename... Args> + PROTOBUF_ALWAYS_INLINE static Msg* DoCreateMaybeMessage(Arena* arena, + std::true_type, + Args&&... args) { + return CreateMessageInternal<Msg>(arena, std::forward<Args>(args)...); + } + + template <typename T, typename... Args> + PROTOBUF_ALWAYS_INLINE static T* DoCreateMaybeMessage(Arena* arena, + std::false_type, + Args&&... args) { + return Create<T>(arena, std::forward<Args>(args)...); + } + + template <typename T, typename... Args> + PROTOBUF_ALWAYS_INLINE static T* CreateMaybeMessage(Arena* arena, + Args&&... args) { + return DoCreateMaybeMessage<T>(arena, is_arena_constructable<T>(), + std::forward<Args>(args)...); + } + + // Just allocate the required size for the given type assuming the + // type has a trivial constructor. + template <typename T> + PROTOBUF_NDEBUG_INLINE T* CreateInternalRawArray(size_t num_elements) { + GOOGLE_CHECK_LE(num_elements, std::numeric_limits<size_t>::max() / sizeof(T)) + << "Requested size is too large to fit into size_t."; + // We count on compiler to realize that if sizeof(T) is a multiple of + // 8 AlignUpTo can be elided. + const size_t n = sizeof(T) * num_elements; + return static_cast<T*>( + AllocateAlignedWithHook(n, alignof(T), RTTI_TYPE_ID(T))); + } + + template <typename T, typename... Args> + PROTOBUF_NDEBUG_INLINE T* DoCreateMessage(Args&&... args) { + return InternalHelper<T>::Construct( + AllocateInternal(sizeof(T), alignof(T), + internal::ObjectDestructor< + InternalHelper<T>::is_destructor_skippable::value, + T>::destructor, + RTTI_TYPE_ID(T)), + this, std::forward<Args>(args)...); + } + + // CreateInArenaStorage is used to implement map field. Without it, + // Map need to call generated message's protected arena constructor, + // which needs to declare Map as friend of generated message. + template <typename T, typename... Args> + static void CreateInArenaStorage(T* ptr, Arena* arena, Args&&... args) { + CreateInArenaStorageInternal(ptr, arena, + typename is_arena_constructable<T>::type(), + std::forward<Args>(args)...); + if (arena != nullptr) { + RegisterDestructorInternal( + ptr, arena, + typename InternalHelper<T>::is_destructor_skippable::type()); + } + } + + template <typename T, typename... Args> + static void CreateInArenaStorageInternal(T* ptr, Arena* arena, + std::true_type, Args&&... args) { + InternalHelper<T>::Construct(ptr, arena, std::forward<Args>(args)...); + } + template <typename T, typename... Args> + static void CreateInArenaStorageInternal(T* ptr, Arena* /* arena */, + std::false_type, Args&&... args) { + new (ptr) T(std::forward<Args>(args)...); + } + + template <typename T> + static void RegisterDestructorInternal(T* /* ptr */, Arena* /* arena */, + std::true_type) {} + template <typename T> + static void RegisterDestructorInternal(T* ptr, Arena* arena, + std::false_type) { + arena->OwnDestructor(ptr); + } + + // These implement Create(). The second parameter has type 'true_type' if T is + // a subtype of Message and 'false_type' otherwise. + template <typename T, typename... Args> + PROTOBUF_ALWAYS_INLINE static T* CreateInternal(Arena* arena, std::true_type, + Args&&... args) { + if (arena == nullptr) { + return new T(std::forward<Args>(args)...); + } else { + auto destructor = + internal::ObjectDestructor<std::is_trivially_destructible<T>::value, + T>::destructor; + T* result = + new (arena->AllocateInternal(sizeof(T), alignof(T), destructor, + RTTI_TYPE_ID(T))) + T(std::forward<Args>(args)...); + return result; + } + } + template <typename T, typename... Args> + PROTOBUF_ALWAYS_INLINE static T* CreateInternal(Arena* arena, std::false_type, + Args&&... args) { + if (arena == nullptr) { + return new T(std::forward<Args>(args)...); + } else { + auto destructor = + internal::ObjectDestructor<std::is_trivially_destructible<T>::value, + T>::destructor; + return new (arena->AllocateInternal(sizeof(T), alignof(T), destructor, + RTTI_TYPE_ID(T))) + T(std::forward<Args>(args)...); + } + } + + // These implement Own(), which registers an object for deletion (destructor + // call and operator delete()). The second parameter has type 'true_type' if T + // is a subtype of Message and 'false_type' otherwise. Collapsing + // all template instantiations to one for generic Message reduces code size, + // using the virtual destructor instead. + template <typename T> + PROTOBUF_ALWAYS_INLINE void OwnInternal(T* object, std::true_type) { + if (object != NULL) { + impl_.AddCleanup(object, &internal::arena_delete_object<MessageLite>); + } + } + template <typename T> + PROTOBUF_ALWAYS_INLINE void OwnInternal(T* object, std::false_type) { + if (object != NULL) { + impl_.AddCleanup(object, &internal::arena_delete_object<T>); + } + } + + // Implementation for GetArena(). Only message objects with + // InternalArenaConstructable_ tags can be associated with an arena, and such + // objects must implement a GetArena() method. + template <typename T, typename std::enable_if< + is_arena_constructable<T>::value, int>::type = 0> + PROTOBUF_ALWAYS_INLINE static Arena* GetArenaInternal(const T* value) { + return InternalHelper<T>::GetArena(value); + } + template <typename T, + typename std::enable_if<!is_arena_constructable<T>::value && + has_get_arena<T>::value, + int>::type = 0> + PROTOBUF_ALWAYS_INLINE static Arena* GetArenaInternal(const T* value) { + return value->GetArena(); + } + template <typename T, + typename std::enable_if<!is_arena_constructable<T>::value && + !has_get_arena<T>::value, + int>::type = 0> + PROTOBUF_ALWAYS_INLINE static Arena* GetArenaInternal(const T* value) { + (void)value; + return nullptr; + } + + template <typename T> + PROTOBUF_ALWAYS_INLINE static Arena* GetOwningArena(const T* value) { + return GetOwningArenaInternal( + value, std::is_convertible<T*, MessageLite*>()); + } + + // Implementation for GetOwningArena(). All and only message objects have + // GetOwningArena() method. + template <typename T> + PROTOBUF_ALWAYS_INLINE static Arena* GetOwningArenaInternal( + const T* value, std::true_type) { + return InternalHelper<T>::GetOwningArena(value); + } + template <typename T> + PROTOBUF_ALWAYS_INLINE static Arena* GetOwningArenaInternal( + const T* /* value */, std::false_type) { + return nullptr; + } + + // For friends of arena. + void* AllocateAligned(size_t n, size_t align = 8) { + if (align <= 8) { + return AllocateAlignedNoHook(internal::AlignUpTo8(n)); + } else { + // We are wasting space by over allocating align - 8 bytes. Compared + // to a dedicated function that takes current alignment in consideration. + // Such a scheme would only waste (align - 8)/2 bytes on average, but + // requires a dedicated function in the outline arena allocation + // functions. Possibly re-evaluate tradeoffs later. + return internal::AlignTo(AllocateAlignedNoHook(n + align - 8), align); + } + } + + void* AllocateAlignedWithHook(size_t n, size_t align, + const std::type_info* type) { + if (align <= 8) { + return AllocateAlignedWithHook(internal::AlignUpTo8(n), type); + } else { + // We are wasting space by over allocating align - 8 bytes. Compared + // to a dedicated function that takes current alignment in consideration. + // Such a schemee would only waste (align - 8)/2 bytes on average, but + // requires a dedicated function in the outline arena allocation + // functions. Possibly re-evaluate tradeoffs later. + return internal::AlignTo(AllocateAlignedWithHook(n + align - 8, type), + align); + } + } + + void* AllocateAlignedNoHook(size_t n); + void* AllocateAlignedWithHook(size_t n, const std::type_info* type); + std::pair<void*, internal::SerialArena::CleanupNode*> + AllocateAlignedWithCleanup(size_t n, const std::type_info* type); + + template <typename Type> + friend class internal::GenericTypeHandler; + friend struct internal::ArenaStringPtr; // For AllocateAligned. + friend class internal::InlinedStringField; // For AllocateAligned. + friend class internal::LazyField; // For CreateMaybeMessage. + friend class internal::EpsCopyInputStream; // For parser performance + friend class MessageLite; + template <typename Key, typename T> + friend class Map; +}; + +// Defined above for supporting environments without RTTI. +#undef RTTI_TYPE_ID + +} // namespace protobuf +} // namespace google + +#include <google/protobuf/port_undef.inc> + +#endif // GOOGLE_PROTOBUF_ARENA_H__ diff --git a/contrib/libs/protobuf_old/src/google/protobuf/arena_impl.h b/contrib/libs/protobuf_old/src/google/protobuf/arena_impl.h new file mode 100644 index 0000000000..76aa3bb045 --- /dev/null +++ b/contrib/libs/protobuf_old/src/google/protobuf/arena_impl.h @@ -0,0 +1,562 @@ +// 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 defines an Arena allocator for better allocation performance. + +#ifndef GOOGLE_PROTOBUF_ARENA_IMPL_H__ +#define GOOGLE_PROTOBUF_ARENA_IMPL_H__ + +#include <atomic> +#include <limits> +#include <typeinfo> + +#include <google/protobuf/stubs/common.h> +#include <google/protobuf/stubs/logging.h> + +#ifdef ADDRESS_SANITIZER +#include <sanitizer/asan_interface.h> +#endif // ADDRESS_SANITIZER + +#include <google/protobuf/port_def.inc> + + +namespace google { +namespace protobuf { +namespace internal { + +inline constexpr size_t AlignUpTo8(size_t n) { + // Align n to next multiple of 8 (from Hacker's Delight, Chapter 3.) + return (n + 7) & static_cast<size_t>(-8); +} + +using LifecycleIdAtomic = arc_ui64; + +// MetricsCollector collects stats for a particular arena. +class PROTOBUF_EXPORT ArenaMetricsCollector { + public: + ArenaMetricsCollector(bool record_allocs) : record_allocs_(record_allocs) {} + + // Invoked when the arena is about to be destroyed. This method will + // typically finalize any metric collection and delete the collector. + // space_allocated is the space used by the arena. + virtual void OnDestroy(arc_ui64 space_allocated) = 0; + + // OnReset() is called when the associated arena is reset. + // space_allocated is the space used by the arena just before the reset. + virtual void OnReset(arc_ui64 space_allocated) = 0; + + // OnAlloc is called when an allocation happens. + // type_info is promised to be static - its lifetime extends to + // match program's lifetime (It is given by typeid operator). + // Note: typeid(void) will be passed as allocated_type every time we + // intentionally want to avoid monitoring an allocation. (i.e. internal + // allocations for managing the arena) + virtual void OnAlloc(const std::type_info* allocated_type, + arc_ui64 alloc_size) = 0; + + // Does OnAlloc() need to be called? If false, metric collection overhead + // will be reduced since we will not do extra work per allocation. + bool RecordAllocs() { return record_allocs_; } + + protected: + // This class is destructed by the call to OnDestroy(). + ~ArenaMetricsCollector() = default; + const bool record_allocs_; +}; + +struct AllocationPolicy { + static constexpr size_t kDefaultStartBlockSize = 256; + static constexpr size_t kDefaultMaxBlockSize = 8192; + + size_t start_block_size = kDefaultStartBlockSize; + size_t max_block_size = kDefaultMaxBlockSize; + void* (*block_alloc)(size_t) = nullptr; + void (*block_dealloc)(void*, size_t) = nullptr; + ArenaMetricsCollector* metrics_collector = nullptr; + + bool IsDefault() const { + return start_block_size == kDefaultMaxBlockSize && + max_block_size == kDefaultMaxBlockSize && block_alloc == nullptr && + block_dealloc == nullptr && metrics_collector == nullptr; + } +}; + +// Tagged pointer to an AllocationPolicy. +class TaggedAllocationPolicyPtr { + public: + constexpr TaggedAllocationPolicyPtr() : policy_(0) {} + + explicit TaggedAllocationPolicyPtr(AllocationPolicy* policy) + : policy_(reinterpret_cast<uintptr_t>(policy)) {} + + void set_policy(AllocationPolicy* policy) { + auto bits = policy_ & kTagsMask; + policy_ = reinterpret_cast<uintptr_t>(policy) | bits; + } + + AllocationPolicy* get() { + return reinterpret_cast<AllocationPolicy*>(policy_ & kPtrMask); + } + const AllocationPolicy* get() const { + return reinterpret_cast<const AllocationPolicy*>(policy_ & kPtrMask); + } + + AllocationPolicy& operator*() { return *get(); } + const AllocationPolicy& operator*() const { return *get(); } + + AllocationPolicy* operator->() { return get(); } + const AllocationPolicy* operator->() const { return get(); } + + bool is_user_owned_initial_block() const { + return static_cast<bool>(get_mask<kUserOwnedInitialBlock>()); + } + void set_is_user_owned_initial_block(bool v) { + set_mask<kUserOwnedInitialBlock>(v); + } + + bool should_record_allocs() const { + return static_cast<bool>(get_mask<kRecordAllocs>()); + } + void set_should_record_allocs(bool v) { set_mask<kRecordAllocs>(v); } + + uintptr_t get_raw() const { return policy_; } + + inline void RecordAlloc(const std::type_info* allocated_type, + size_t n) const { + get()->metrics_collector->OnAlloc(allocated_type, n); + } + + private: + enum : uintptr_t { + kUserOwnedInitialBlock = 1, + kRecordAllocs = 2, + }; + + static constexpr uintptr_t kTagsMask = 7; + static constexpr uintptr_t kPtrMask = ~kTagsMask; + + template <uintptr_t kMask> + uintptr_t get_mask() const { + return policy_ & kMask; + } + template <uintptr_t kMask> + void set_mask(bool v) { + if (v) { + policy_ |= kMask; + } else { + policy_ &= ~kMask; + } + } + uintptr_t policy_; +}; + +// A simple arena allocator. Calls to allocate functions must be properly +// serialized by the caller, hence this class cannot be used as a general +// purpose allocator in a multi-threaded program. It serves as a building block +// for ThreadSafeArena, which provides a thread-safe arena allocator. +// +// This class manages +// 1) Arena bump allocation + owning memory blocks. +// 2) Maintaining a cleanup list. +// It delagetes the actual memory allocation back to ThreadSafeArena, which +// contains the information on block growth policy and backing memory allocation +// used. +class PROTOBUF_EXPORT SerialArena { + public: + struct Memory { + void* ptr; + size_t size; + }; + + // Node contains the ptr of the object to be cleaned up and the associated + // cleanup function ptr. + struct CleanupNode { + void* elem; // Pointer to the object to be cleaned up. + void (*cleanup)(void*); // Function pointer to the destructor or deleter. + }; + + void CleanupList(); + arc_ui64 SpaceAllocated() const { + return space_allocated_.load(std::memory_order_relaxed); + } + arc_ui64 SpaceUsed() const; + + bool HasSpace(size_t n) { return n <= static_cast<size_t>(limit_ - ptr_); } + + void* AllocateAligned(size_t n, const AllocationPolicy* policy) { + GOOGLE_DCHECK_EQ(internal::AlignUpTo8(n), n); // Must be already aligned. + GOOGLE_DCHECK_GE(limit_, ptr_); + if (PROTOBUF_PREDICT_FALSE(!HasSpace(n))) { + return AllocateAlignedFallback(n, policy); + } + return AllocateFromExisting(n); + } + + private: + void* AllocateFromExisting(size_t n) { + void* ret = ptr_; + ptr_ += n; +#ifdef ADDRESS_SANITIZER + ASAN_UNPOISON_MEMORY_REGION(ret, n); +#endif // ADDRESS_SANITIZER + return ret; + } + + public: + // Allocate space if the current region provides enough space. + bool MaybeAllocateAligned(size_t n, void** out) { + GOOGLE_DCHECK_EQ(internal::AlignUpTo8(n), n); // Must be already aligned. + GOOGLE_DCHECK_GE(limit_, ptr_); + if (PROTOBUF_PREDICT_FALSE(!HasSpace(n))) return false; + *out = AllocateFromExisting(n); + return true; + } + + std::pair<void*, CleanupNode*> AllocateAlignedWithCleanup( + size_t n, const AllocationPolicy* policy) { + GOOGLE_DCHECK_EQ(internal::AlignUpTo8(n), n); // Must be already aligned. + if (PROTOBUF_PREDICT_FALSE(!HasSpace(n + kCleanupSize))) { + return AllocateAlignedWithCleanupFallback(n, policy); + } + return AllocateFromExistingWithCleanupFallback(n); + } + + private: + std::pair<void*, CleanupNode*> AllocateFromExistingWithCleanupFallback( + size_t n) { + void* ret = ptr_; + ptr_ += n; + limit_ -= kCleanupSize; +#ifdef ADDRESS_SANITIZER + ASAN_UNPOISON_MEMORY_REGION(ret, n); + ASAN_UNPOISON_MEMORY_REGION(limit_, kCleanupSize); +#endif // ADDRESS_SANITIZER + return CreatePair(ret, reinterpret_cast<CleanupNode*>(limit_)); + } + + public: + void AddCleanup(void* elem, void (*cleanup)(void*), + const AllocationPolicy* policy) { + auto res = AllocateAlignedWithCleanup(0, policy); + res.second->elem = elem; + res.second->cleanup = cleanup; + } + + void* owner() const { return owner_; } + SerialArena* next() const { return next_; } + void set_next(SerialArena* next) { next_ = next; } + + private: + friend class ThreadSafeArena; + friend class ArenaBenchmark; + + // Creates a new SerialArena inside mem using the remaining memory as for + // future allocations. + static SerialArena* New(SerialArena::Memory mem, void* owner); + // Free SerialArena returning the memory passed in to New + template <typename Deallocator> + Memory Free(Deallocator deallocator); + + // Blocks are variable length malloc-ed objects. The following structure + // describes the common header for all blocks. + struct Block { + Block(Block* next, size_t size) : next(next), size(size), start(nullptr) {} + + char* Pointer(size_t n) { + GOOGLE_DCHECK(n <= size); + return reinterpret_cast<char*>(this) + n; + } + + Block* const next; + const size_t size; + CleanupNode* start; + // data follows + }; + + void* owner_; // &ThreadCache of this thread; + Block* head_; // Head of linked list of blocks. + SerialArena* next_; // Next SerialArena in this linked list. + size_t space_used_ = 0; // Necessary for metrics. + std::atomic<size_t> space_allocated_; + + // Next pointer to allocate from. Always 8-byte aligned. Points inside + // head_ (and head_->pos will always be non-canonical). We keep these + // here to reduce indirection. + char* ptr_; + char* limit_; + + // Constructor is private as only New() should be used. + inline SerialArena(Block* b, void* owner); + void* AllocateAlignedFallback(size_t n, const AllocationPolicy* policy); + std::pair<void*, CleanupNode*> AllocateAlignedWithCleanupFallback( + size_t n, const AllocationPolicy* policy); + void AllocateNewBlock(size_t n, const AllocationPolicy* policy); + + std::pair<void*, CleanupNode*> CreatePair(void* ptr, CleanupNode* node) { + return {ptr, node}; + } + + public: + static constexpr size_t kBlockHeaderSize = AlignUpTo8(sizeof(Block)); + static constexpr size_t kCleanupSize = AlignUpTo8(sizeof(CleanupNode)); +}; + +// Tag type used to invoke the constructor of message-owned arena. +// Only message-owned arenas use this constructor for creation. +// Such constructors are internal implementation details of the library. +struct MessageOwned { + explicit MessageOwned() = default; +}; + +// This class provides the core Arena memory allocation library. Different +// implementations only need to implement the public interface below. +// Arena is not a template type as that would only be useful if all protos +// in turn would be templates, which will/cannot happen. However separating +// the memory allocation part from the cruft of the API users expect we can +// use #ifdef the select the best implementation based on hardware / OS. +class PROTOBUF_EXPORT ThreadSafeArena { + public: + ThreadSafeArena() { Init(); } + + // Constructor solely used by message-owned arena. + ThreadSafeArena(internal::MessageOwned) : tag_and_id_(kMessageOwnedArena) { + Init(); + } + + ThreadSafeArena(char* mem, size_t size) { InitializeFrom(mem, size); } + + explicit ThreadSafeArena(void* mem, size_t size, + const AllocationPolicy& policy) { + InitializeWithPolicy(mem, size, policy); + } + + // Destructor deletes all owned heap allocated objects, and destructs objects + // that have non-trivial destructors, except for proto2 message objects whose + // destructors can be skipped. Also, frees all blocks except the initial block + // if it was passed in. + ~ThreadSafeArena(); + + arc_ui64 Reset(); + + arc_ui64 SpaceAllocated() const; + arc_ui64 SpaceUsed() const; + + void* AllocateAligned(size_t n, const std::type_info* type) { + SerialArena* arena; + if (PROTOBUF_PREDICT_TRUE(!alloc_policy_.should_record_allocs() && + GetSerialArenaFast(&arena))) { + return arena->AllocateAligned(n, AllocPolicy()); + } else { + return AllocateAlignedFallback(n, type); + } + } + + // This function allocates n bytes if the common happy case is true and + // returns true. Otherwise does nothing and returns false. This strange + // semantics is necessary to allow callers to program functions that only + // have fallback function calls in tail position. This substantially improves + // code for the happy path. + PROTOBUF_NDEBUG_INLINE bool MaybeAllocateAligned(size_t n, void** out) { + SerialArena* a; + if (PROTOBUF_PREDICT_TRUE(!alloc_policy_.should_record_allocs() && + GetSerialArenaFromThreadCache(&a))) { + return a->MaybeAllocateAligned(n, out); + } + return false; + } + + std::pair<void*, SerialArena::CleanupNode*> AllocateAlignedWithCleanup( + size_t n, const std::type_info* type); + + // Add object pointer and cleanup function pointer to the list. + void AddCleanup(void* elem, void (*cleanup)(void*)); + + // Checks whether this arena is message-owned. + PROTOBUF_ALWAYS_INLINE bool IsMessageOwned() const { + return tag_and_id_ & kMessageOwnedArena; + } + + private: + // Unique for each arena. Changes on Reset(). + arc_ui64 tag_and_id_ = 0; + // The LSB of tag_and_id_ indicates if the arena is message-owned. + enum : arc_ui64 { kMessageOwnedArena = 1 }; + + TaggedAllocationPolicyPtr alloc_policy_; // Tagged pointer to AllocPolicy. + + // Pointer to a linked list of SerialArena. + std::atomic<SerialArena*> threads_; + std::atomic<SerialArena*> hint_; // Fast thread-local block access + + const AllocationPolicy* AllocPolicy() const { return alloc_policy_.get(); } + void InitializeFrom(void* mem, size_t size); + void InitializeWithPolicy(void* mem, size_t size, AllocationPolicy policy); + void* AllocateAlignedFallback(size_t n, const std::type_info* type); + std::pair<void*, SerialArena::CleanupNode*> + AllocateAlignedWithCleanupFallback(size_t n, const std::type_info* type); + + void Init(); + void SetInitialBlock(void* mem, size_t size); + + // Delete or Destruct all objects owned by the arena. + void CleanupList(); + + inline arc_ui64 LifeCycleId() const { + return tag_and_id_ & ~kMessageOwnedArena; + } + + inline void CacheSerialArena(SerialArena* serial) { + thread_cache().last_serial_arena = serial; + thread_cache().last_lifecycle_id_seen = tag_and_id_; + // TODO(haberman): evaluate whether we would gain efficiency by getting rid + // of hint_. It's the only write we do to ThreadSafeArena in the allocation + // path, which will dirty the cache line. + + hint_.store(serial, std::memory_order_release); + } + + PROTOBUF_NDEBUG_INLINE bool GetSerialArenaFast(SerialArena** arena) { + if (GetSerialArenaFromThreadCache(arena)) return true; + + // Check whether we own the last accessed SerialArena on this arena. This + // fast path optimizes the case where a single thread uses multiple arenas. + ThreadCache* tc = &thread_cache(); + SerialArena* serial = hint_.load(std::memory_order_acquire); + if (PROTOBUF_PREDICT_TRUE(serial != NULL && serial->owner() == tc)) { + *arena = serial; + return true; + } + return false; + } + + PROTOBUF_NDEBUG_INLINE bool GetSerialArenaFromThreadCache( + SerialArena** arena) { + // If this thread already owns a block in this arena then try to use that. + // This fast path optimizes the case where multiple threads allocate from + // the same arena. + ThreadCache* tc = &thread_cache(); + if (PROTOBUF_PREDICT_TRUE(tc->last_lifecycle_id_seen == tag_and_id_)) { + *arena = tc->last_serial_arena; + return true; + } + return false; + } + SerialArena* GetSerialArenaFallback(void* me); + + template <typename Functor> + void PerSerialArena(Functor fn) { + // By omitting an Acquire barrier we ensure that any user code that doesn't + // properly synchronize Reset() or the destructor will throw a TSAN warning. + SerialArena* serial = threads_.load(std::memory_order_relaxed); + + for (; serial; serial = serial->next()) fn(serial); + } + + // Releases all memory except the first block which it returns. The first + // block might be owned by the user and thus need some extra checks before + // deleting. + SerialArena::Memory Free(size_t* space_allocated); + +#ifdef _MSC_VER +#pragma warning(disable : 4324) +#endif + struct alignas(64) ThreadCache { +#if defined(GOOGLE_PROTOBUF_NO_THREADLOCAL) + // If we are using the ThreadLocalStorage class to store the ThreadCache, + // then the ThreadCache's default constructor has to be responsible for + // initializing it. + ThreadCache() + : next_lifecycle_id(0), + last_lifecycle_id_seen(-1), + last_serial_arena(NULL) {} +#endif + + // Number of per-thread lifecycle IDs to reserve. Must be power of two. + // To reduce contention on a global atomic, each thread reserves a batch of + // IDs. The following number is calculated based on a stress test with + // ~6500 threads all frequently allocating a new arena. + static constexpr size_t kPerThreadIds = 256; + // Next lifecycle ID available to this thread. We need to reserve a new + // batch, if `next_lifecycle_id & (kPerThreadIds - 1) == 0`. + arc_ui64 next_lifecycle_id; + // The ThreadCache is considered valid as long as this matches the + // lifecycle_id of the arena being used. + arc_ui64 last_lifecycle_id_seen; + SerialArena* last_serial_arena; + }; + + // Lifecycle_id can be highly contended variable in a situation of lots of + // arena creation. Make sure that other global variables are not sharing the + // cacheline. +#ifdef _MSC_VER +#pragma warning(disable : 4324) +#endif + struct alignas(64) CacheAlignedLifecycleIdGenerator { + std::atomic<LifecycleIdAtomic> id; + }; + static CacheAlignedLifecycleIdGenerator lifecycle_id_generator_; +#if defined(GOOGLE_PROTOBUF_NO_THREADLOCAL) + // iOS does not support __thread keyword so we use a custom thread local + // storage class we implemented. + static ThreadCache& thread_cache(); +#elif defined(PROTOBUF_USE_DLLS) + // Thread local variables cannot be exposed through DLL interface but we can + // wrap them in static functions. + static ThreadCache& thread_cache(); +#else + static PROTOBUF_THREAD_LOCAL ThreadCache thread_cache_; + static ThreadCache& thread_cache() { return thread_cache_; } +#endif + + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ThreadSafeArena); + // All protos have pointers back to the arena hence Arena must have + // pointer stability. + ThreadSafeArena(ThreadSafeArena&&) = delete; + ThreadSafeArena& operator=(ThreadSafeArena&&) = delete; + + public: + // kBlockHeaderSize is sizeof(Block), aligned up to the nearest multiple of 8 + // to protect the invariant that pos is always at a multiple of 8. + static constexpr size_t kBlockHeaderSize = SerialArena::kBlockHeaderSize; + static constexpr size_t kSerialArenaSize = + (sizeof(SerialArena) + 7) & static_cast<size_t>(-8); + static_assert(kBlockHeaderSize % 8 == 0, + "kBlockHeaderSize must be a multiple of 8."); + static_assert(kSerialArenaSize % 8 == 0, + "kSerialArenaSize must be a multiple of 8."); +}; + +} // namespace internal +} // namespace protobuf +} // namespace google + +#include <google/protobuf/port_undef.inc> + +#endif // GOOGLE_PROTOBUF_ARENA_IMPL_H__ diff --git a/contrib/libs/protobuf_old/src/google/protobuf/arenastring.cc b/contrib/libs/protobuf_old/src/google/protobuf/arenastring.cc new file mode 100644 index 0000000000..c64864e4b1 --- /dev/null +++ b/contrib/libs/protobuf_old/src/google/protobuf/arenastring.cc @@ -0,0 +1,286 @@ +// 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 <google/protobuf/arenastring.h> + +#include <google/protobuf/stubs/logging.h> +#include <google/protobuf/stubs/common.h> +#include <google/protobuf/parse_context.h> +#include <google/protobuf/io/coded_stream.h> +#include <google/protobuf/message_lite.h> +#include <google/protobuf/stubs/mutex.h> +#include <google/protobuf/stubs/strutil.h> +#include <google/protobuf/stubs/stl_util.h> + +// clang-format off +#include <google/protobuf/port_def.inc> +// clang-format on + +namespace google { +namespace protobuf { +namespace internal { + +const TProtoStringType& LazyString::Init() const { + static WrappedMutex mu{GOOGLE_PROTOBUF_LINKER_INITIALIZED}; + mu.Lock(); + const TProtoStringType* res = inited_.load(std::memory_order_acquire); + if (res == nullptr) { + auto init_value = init_value_; + res = ::new (static_cast<void*>(string_buf_)) + TProtoStringType(init_value.ptr, init_value.size); + inited_.store(res, std::memory_order_release); + } + mu.Unlock(); + return *res; +} + + +TProtoStringType* ArenaStringPtr::SetAndReturnNewString() { + TProtoStringType* new_string = new TProtoStringType(); + tagged_ptr_.Set(new_string); + return new_string; +} + +void ArenaStringPtr::DestroyNoArenaSlowPath() { delete UnsafeMutablePointer(); } + +void ArenaStringPtr::Set(const TProtoStringType* default_value, + ConstStringParam value, ::google::protobuf::Arena* arena) { + if (IsDefault(default_value)) { + tagged_ptr_.Set(Arena::Create<TProtoStringType>(arena, value)); + } else { + UnsafeMutablePointer()->assign(value.data(), value.length()); + } +} + +void ArenaStringPtr::Set(const TProtoStringType* default_value, TProtoStringType&& value, + ::google::protobuf::Arena* arena) { + if (IsDefault(default_value)) { + if (arena == nullptr) { + tagged_ptr_.Set(new TProtoStringType(std::move(value))); + } else { + tagged_ptr_.Set(Arena::Create<TProtoStringType>(arena, std::move(value))); + } + } else if (IsDonatedString()) { + TProtoStringType* current = tagged_ptr_.Get(); + auto* s = new (current) TProtoStringType(std::move(value)); + arena->OwnDestructor(s); + tagged_ptr_.Set(s); + } else /* !IsDonatedString() */ { + *UnsafeMutablePointer() = std::move(value); + } +} + +void ArenaStringPtr::Set(EmptyDefault, ConstStringParam value, + ::google::protobuf::Arena* arena) { + Set(&GetEmptyStringAlreadyInited(), value, arena); +} + +void ArenaStringPtr::Set(EmptyDefault, TProtoStringType&& value, + ::google::protobuf::Arena* arena) { + Set(&GetEmptyStringAlreadyInited(), std::move(value), arena); +} + +void ArenaStringPtr::Set(NonEmptyDefault, ConstStringParam value, + ::google::protobuf::Arena* arena) { + Set(nullptr, value, arena); +} + +void ArenaStringPtr::Set(NonEmptyDefault, TProtoStringType&& value, + ::google::protobuf::Arena* arena) { + Set(nullptr, std::move(value), arena); +} + +TProtoStringType* ArenaStringPtr::Mutable(EmptyDefault, ::google::protobuf::Arena* arena) { + if (!IsDonatedString() && !IsDefault(&GetEmptyStringAlreadyInited())) { + return UnsafeMutablePointer(); + } else { + return MutableSlow(arena); + } +} + +TProtoStringType* ArenaStringPtr::Mutable(const LazyString& default_value, + ::google::protobuf::Arena* arena) { + if (!IsDonatedString() && !IsDefault(nullptr)) { + return UnsafeMutablePointer(); + } else { + return MutableSlow(arena, default_value); + } +} + +TProtoStringType* ArenaStringPtr::MutableNoCopy(const TProtoStringType* default_value, + ::google::protobuf::Arena* arena) { + if (!IsDonatedString() && !IsDefault(default_value)) { + return UnsafeMutablePointer(); + } else { + GOOGLE_DCHECK(IsDefault(default_value)); + // Allocate empty. The contents are not relevant. + TProtoStringType* new_string = Arena::Create<TProtoStringType>(arena); + tagged_ptr_.Set(new_string); + return new_string; + } +} + +template <typename... Lazy> +TProtoStringType* ArenaStringPtr::MutableSlow(::google::protobuf::Arena* arena, + const Lazy&... lazy_default) { + const TProtoStringType* const default_value = + sizeof...(Lazy) == 0 ? &GetEmptyStringAlreadyInited() : nullptr; + GOOGLE_DCHECK(IsDefault(default_value)); + TProtoStringType* new_string = + Arena::Create<TProtoStringType>(arena, lazy_default.get()...); + tagged_ptr_.Set(new_string); + return new_string; +} + +TProtoStringType* ArenaStringPtr::Release(const TProtoStringType* default_value, + ::google::protobuf::Arena* arena) { + if (IsDefault(default_value)) { + return nullptr; + } else { + return ReleaseNonDefault(default_value, arena); + } +} + +TProtoStringType* ArenaStringPtr::ReleaseNonDefault(const TProtoStringType* default_value, + ::google::protobuf::Arena* arena) { + GOOGLE_DCHECK(!IsDefault(default_value)); + + if (!IsDonatedString()) { + TProtoStringType* released; + if (arena != nullptr) { + released = new TProtoStringType; + released->swap(*UnsafeMutablePointer()); + } else { + released = UnsafeMutablePointer(); + } + tagged_ptr_.Set(const_cast<TProtoStringType*>(default_value)); + return released; + } else /* IsDonatedString() */ { + GOOGLE_DCHECK(arena != nullptr); + TProtoStringType* released = new TProtoStringType(Get()); + tagged_ptr_.Set(const_cast<TProtoStringType*>(default_value)); + return released; + } +} + +void ArenaStringPtr::SetAllocated(const TProtoStringType* default_value, + TProtoStringType* value, ::google::protobuf::Arena* arena) { + // Release what we have first. + if (arena == nullptr && !IsDefault(default_value)) { + delete UnsafeMutablePointer(); + } + if (value == nullptr) { + tagged_ptr_.Set(const_cast<TProtoStringType*>(default_value)); + } else { +#ifdef NDEBUG + tagged_ptr_.Set(value); + if (arena != nullptr) { + arena->Own(value); + } +#else + // On debug builds, copy the string so the address differs. delete will + // fail if value was a stack-allocated temporary/etc., which would have + // failed when arena ran its cleanup list. + TProtoStringType* new_value = Arena::Create<TProtoStringType>(arena, *value); + delete value; + tagged_ptr_.Set(new_value); +#endif + } +} + +void ArenaStringPtr::Destroy(const TProtoStringType* default_value, + ::google::protobuf::Arena* arena) { + if (arena == nullptr) { + GOOGLE_DCHECK(!IsDonatedString()); + if (!IsDefault(default_value)) { + delete UnsafeMutablePointer(); + } + } +} + +void ArenaStringPtr::Destroy(EmptyDefault, ::google::protobuf::Arena* arena) { + Destroy(&GetEmptyStringAlreadyInited(), arena); +} + +void ArenaStringPtr::Destroy(NonEmptyDefault, ::google::protobuf::Arena* arena) { + Destroy(nullptr, arena); +} + +void ArenaStringPtr::ClearToEmpty() { + if (IsDefault(&GetEmptyStringAlreadyInited())) { + // Already set to default -- do nothing. + } else { + // Unconditionally mask away the tag. + // + // UpdateDonatedString uses assign when capacity is larger than the new + // value, which is trivially true in the donated string case. + // const_cast<TProtoStringType*>(PtrValue<TProtoStringType>())->clear(); + tagged_ptr_.Get()->clear(); + } +} + +void ArenaStringPtr::ClearToDefault(const LazyString& default_value, + ::google::protobuf::Arena* arena) { + (void)arena; + if (IsDefault(nullptr)) { + // Already set to default -- do nothing. + } else if (!IsDonatedString()) { + UnsafeMutablePointer()->assign(default_value.get()); + } +} + +inline void SetStrWithHeapBuffer(TProtoStringType* str, ArenaStringPtr* s) { + TaggedPtr<TProtoStringType> res; + res.Set(str); + s->UnsafeSetTaggedPointer(res); +} + +const char* EpsCopyInputStream::ReadArenaString(const char* ptr, + ArenaStringPtr* s, + Arena* arena) { + GOOGLE_DCHECK(arena != nullptr); + + int size = ReadSize(&ptr); + if (!ptr) return nullptr; + + auto* str = Arena::Create<TProtoStringType>(arena); + ptr = ReadString(ptr, size, str); + GOOGLE_PROTOBUF_PARSER_ASSERT(ptr); + + SetStrWithHeapBuffer(str, s); + + return ptr; +} + +} // namespace internal +} // namespace protobuf +} // namespace google + +#include <google/protobuf/port_undef.inc> diff --git a/contrib/libs/protobuf_old/src/google/protobuf/arenastring.h b/contrib/libs/protobuf_old/src/google/protobuf/arenastring.h new file mode 100644 index 0000000000..f9e65a9fc8 --- /dev/null +++ b/contrib/libs/protobuf_old/src/google/protobuf/arenastring.h @@ -0,0 +1,420 @@ +// 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_ARENASTRING_H__ +#define GOOGLE_PROTOBUF_ARENASTRING_H__ + +#include <string> +#include <type_traits> +#include <utility> + +#include <google/protobuf/stubs/logging.h> +#include <google/protobuf/stubs/common.h> +#include <google/protobuf/arena.h> +#include <google/protobuf/port.h> + +#include <google/protobuf/port_def.inc> + +#ifdef SWIG +#error "You cannot SWIG proto headers" +#endif + + +namespace google { +namespace protobuf { +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 { + public: + // We explicitly make LazyString an aggregate so that MSVC can do constant + // initialization on it without marking it `constexpr`. + // We do not want to use `constexpr` because it makes it harder to have extern + // storage for it and causes library bloat. + struct InitValue { + const char* ptr; + size_t size; + }; + // We keep a union of the initialization value and the TProtoStringType to save on + // space. We don't need the string array after Init() is done. + union { + mutable InitValue init_value_; + alignas(TProtoStringType) mutable char string_buf_[sizeof(TProtoStringType)]; + }; + mutable std::atomic<const TProtoStringType*> inited_; + + const TProtoStringType& get() const { + // This check generates less code than a call-once invocation. + auto* res = inited_.load(std::memory_order_acquire); + if (PROTOBUF_PREDICT_FALSE(res == nullptr)) return Init(); + return *res; + } + + private: + // Initialize the string in `string_buf_`, update `inited_` and return it. + // We return it here to avoid having to read it again in the inlined code. + const TProtoStringType& Init() const; +}; + +template <typename T> +class TaggedPtr { + public: + TaggedPtr() = default; + explicit constexpr TaggedPtr(const ExplicitlyConstructed<TProtoStringType>* ptr) + : ptr_(const_cast<ExplicitlyConstructed<TProtoStringType>*>(ptr)) {} + + void SetTagged(T* p) { + Set(p); + ptr_ = reinterpret_cast<void*>(as_int() | 1); + } + void Set(T* p) { ptr_ = p; } + T* Get() const { return reinterpret_cast<T*>(as_int() & -2); } + bool IsTagged() const { return as_int() & 1; } + + // Returned value is only safe to dereference if IsTagged() == false. + // It is safe to compare. + T* UnsafeGet() const { return static_cast<T*>(ptr_); } + + bool IsNull() { return ptr_ == nullptr; } + + private: + uintptr_t as_int() const { return reinterpret_cast<uintptr_t>(ptr_); } + void* ptr_; +}; + +static_assert(std::is_trivial<TaggedPtr<TProtoStringType>>::value, + "TaggedPtr must be trivial"); + +// This class encapsulates a pointer to a TProtoStringType with or without a donated +// buffer, tagged by bottom bit. It is a high-level wrapper that almost directly +// corresponds to the interface required by string fields in generated +// code. It replaces the old TProtoStringType* pointer in such cases. +// +// The object has different but similar code paths for when the default value is +// the empty string and when it is a non-empty string. +// The empty string is handled different throughout the library and there is a +// single global instance of it we can share. +// +// For fields with an empty string default value, there are three distinct +// states: +// +// - Pointer set to 'String' tag (LSB is 0), equal to +// &GetEmptyStringAlreadyInited(): field is set to its default value. Points +// to a true TProtoStringType*, but we do not own that TProtoStringType* (it's a +// globally shared instance). +// +// - Pointer set to 'String' tag (LSB is 0), but not equal to the global empty +// string: field points to a true TProtoStringType* instance that we own. This +// instance is either on the heap or on the arena (i.e. registered on +// free()/destructor-call list) as appropriate. +// +// - Pointer set to 'DonatedString' tag (LSB is 1): points to a TProtoStringType +// instance with a buffer on the arena (arena is never nullptr in this case). +// +// For fields with a non-empty string default value, there are three distinct +// states: +// +// - Pointer set to 'String' tag (LSB is 0), equal to `nullptr`: +// Field is in "default" mode and does not point to any actual instance. +// Methods that might need to create an instance of the object will pass a +// `const LazyString&` for it. +// +// - Pointer set to 'String' tag (LSB is 0), but not equal to `nullptr`: +// field points to a true TProtoStringType* instance that we own. This instance is +// either on the heap or on the arena (i.e. registered on +// free()/destructor-call list) as appropriate. +// +// - Pointer set to 'DonatedString' tag (LSB is 1): points to a TProtoStringType +// instance with a buffer on the arena (arena is never nullptr in this case). +// +// Generated code and reflection code both ensure that ptr_ is never null for +// fields with an empty default. +// Because ArenaStringPtr is used in oneof unions, its constructor is a NOP and +// so the field is always manually initialized via method calls. +// +// Side-note: why pass information about the default on every API call? Because +// we don't want to hold it in a member variable, or else this would go into +// every proto message instance. This would be a huge waste of space, since the +// default instance pointer is typically a global (static class field). We want +// the generated code to be as efficient as possible, and if we take +// the default value information as a parameter that's in practice taken from a +// static class field, and compare ptr_ to the default value, we end up with a +// single "cmp %reg, GLOBAL" in the resulting machine code. (Note that this also +// requires the String tag to be 0 so we can avoid the mask before comparing.) +struct PROTOBUF_EXPORT ArenaStringPtr { + ArenaStringPtr() = default; + explicit constexpr ArenaStringPtr( + const ExplicitlyConstructed<TProtoStringType>* default_value) + : tagged_ptr_(default_value) {} + + // Some methods below are overloaded on a `default_value` and on tags. + // The tagged overloads help reduce code size in the callers in generated + // code, while the `default_value` overloads are useful from reflection. + // By-value empty struct arguments are elided in the ABI. + struct EmptyDefault {}; + struct NonEmptyDefault {}; + + void Set(const TProtoStringType* default_value, ConstStringParam value, + ::google::protobuf::Arena* arena); + void Set(const TProtoStringType* default_value, TProtoStringType&& value, + ::google::protobuf::Arena* arena); + void Set(EmptyDefault, ConstStringParam value, ::google::protobuf::Arena* arena); + void Set(EmptyDefault, TProtoStringType&& value, ::google::protobuf::Arena* arena); + void Set(NonEmptyDefault, ConstStringParam value, ::google::protobuf::Arena* arena); + void Set(NonEmptyDefault, TProtoStringType&& value, ::google::protobuf::Arena* arena); + template <typename FirstParam> + void Set(FirstParam p1, const char* str, ::google::protobuf::Arena* arena) { + Set(p1, ConstStringParam(str), arena); + } + template <typename FirstParam> + void Set(FirstParam p1, const char* str, size_t size, + ::google::protobuf::Arena* arena) { + ConstStringParam sp{str, size}; // for string_view and `const string &` + Set(p1, sp, arena); + } + template <typename FirstParam, typename RefWrappedType> + void Set(FirstParam p1, + std::reference_wrapper<RefWrappedType> const_string_ref, + ::google::protobuf::Arena* arena) { + Set(p1, const_string_ref.get(), arena); + } + + template <typename FirstParam, typename SecondParam> + void SetBytes(FirstParam p1, SecondParam&& p2, ::google::protobuf::Arena* arena) { + Set(p1, static_cast<SecondParam&&>(p2), arena); + } + template <typename FirstParam> + void SetBytes(FirstParam p1, const void* str, size_t size, + ::google::protobuf::Arena* arena) { + // must work whether ConstStringParam is string_view or `const string &` + ConstStringParam sp{static_cast<const char*>(str), size}; + Set(p1, sp, arena); + } + + // Basic accessors. + PROTOBUF_NDEBUG_INLINE const TProtoStringType& Get() const { + // Unconditionally mask away the tag. + return *tagged_ptr_.Get(); + } + PROTOBUF_NDEBUG_INLINE const TProtoStringType* GetPointer() const { + // Unconditionally mask away the tag. + return tagged_ptr_.Get(); + } + + // For fields with an empty default value. + TProtoStringType* Mutable(EmptyDefault, ::google::protobuf::Arena* arena); + // For fields with a non-empty default value. + TProtoStringType* Mutable(const LazyString& default_value, ::google::protobuf::Arena* arena); + + // Release returns a TProtoStringType* instance that is heap-allocated and is not + // Own()'d by any arena. If the field is not set, this returns nullptr. The + // caller retains ownership. Clears this field back to nullptr state. Used to + // implement release_<field>() methods on generated classes. + PROTOBUF_NODISCARD TProtoStringType* Release(const TProtoStringType* default_value, + ::google::protobuf::Arena* arena); + PROTOBUF_NODISCARD TProtoStringType* ReleaseNonDefault( + const TProtoStringType* default_value, ::google::protobuf::Arena* arena); + + // Takes a TProtoStringType that is heap-allocated, and takes ownership. The + // TProtoStringType's destructor is registered with the arena. Used to implement + // set_allocated_<field> in generated classes. + void SetAllocated(const TProtoStringType* default_value, TProtoStringType* value, + ::google::protobuf::Arena* arena); + + // Swaps internal pointers. Arena-safety semantics: this is guarded by the + // logic in Swap()/UnsafeArenaSwap() at the message level, so this method is + // 'unsafe' if called directly. + inline PROTOBUF_NDEBUG_INLINE static void InternalSwap( + const TProtoStringType* default_value, ArenaStringPtr* rhs, Arena* rhs_arena, + ArenaStringPtr* lhs, Arena* lhs_arena); + + // Frees storage (if not on an arena). + void Destroy(const TProtoStringType* default_value, ::google::protobuf::Arena* arena); + void Destroy(EmptyDefault, ::google::protobuf::Arena* arena); + void Destroy(NonEmptyDefault, ::google::protobuf::Arena* arena); + + // Clears content, but keeps allocated TProtoStringType, to avoid the overhead of + // heap operations. After this returns, the content (as seen by the user) will + // always be the empty TProtoStringType. Assumes that |default_value| is an empty + // TProtoStringType. + void ClearToEmpty(); + + // Clears content, assuming that the current value is not the empty + // string default. + void ClearNonDefaultToEmpty(); + + // Clears content, but keeps allocated TProtoStringType if arena != nullptr, to + // avoid the overhead of heap operations. After this returns, the content + // (as seen by the user) will always be equal to |default_value|. + void ClearToDefault(const LazyString& default_value, ::google::protobuf::Arena* arena); + + // Called from generated code / reflection runtime only. Resets value to point + // to a default string pointer, with the semantics that this + // ArenaStringPtr does not own the pointed-to memory. Disregards initial value + // of ptr_ (so this is the *ONLY* safe method to call after construction or + // when reinitializing after becoming the active field in a oneof union). + inline void UnsafeSetDefault(const TProtoStringType* default_value); + + // Returns a mutable pointer, but doesn't initialize the string to the + // default value. + TProtoStringType* MutableNoArenaNoDefault(const TProtoStringType* default_value); + + // Get a mutable pointer with unspecified contents. + // Similar to `MutableNoArenaNoDefault`, but also handles the arena case. + // If the value was donated, the contents are discarded. + TProtoStringType* MutableNoCopy(const TProtoStringType* default_value, + ::google::protobuf::Arena* arena); + + // Destroy the string. Assumes `arena == nullptr`. + void DestroyNoArena(const TProtoStringType* default_value); + + // Internal setter used only at parse time to directly set a donated string + // value. + void UnsafeSetTaggedPointer(TaggedPtr<TProtoStringType> value) { + tagged_ptr_ = value; + } + // Generated code only! An optimization, in certain cases the generated + // code is certain we can obtain a TProtoStringType with no default checks and + // tag tests. + TProtoStringType* UnsafeMutablePointer() PROTOBUF_RETURNS_NONNULL; + + inline bool IsDefault(const TProtoStringType* default_value) const { + // Relies on the fact that kPtrTagString == 0, so if IsString(), ptr_ is the + // actual TProtoStringType pointer (and if !IsString(), ptr_ will never be equal + // to any aligned |default_value| pointer). The key is that we want to avoid + // masking in the fastpath const-pointer Get() case for non-arena code. + return tagged_ptr_.UnsafeGet() == default_value; + } + + private: + TaggedPtr<TProtoStringType> tagged_ptr_; + + 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 + // Variadic to support 0 args for EmptyDefault and 1 arg for LazyString. + template <typename... Lazy> + TProtoStringType* MutableSlow(::google::protobuf::Arena* arena, const Lazy&... lazy_default); + + // Sets value to a newly allocated string and returns it + TProtoStringType* SetAndReturnNewString(); + + // Destroys the non-default string value out-of-line + void DestroyNoArenaSlowPath(); + +}; + +inline void ArenaStringPtr::UnsafeSetDefault(const TProtoStringType* value) { + tagged_ptr_.Set(const_cast<TProtoStringType*>(value)); +} + +// Make sure rhs_arena allocated rhs, and lhs_arena allocated lhs. +inline PROTOBUF_NDEBUG_INLINE void ArenaStringPtr::InternalSwap( // + const TProtoStringType* default_value, // + ArenaStringPtr* rhs, Arena* rhs_arena, // + ArenaStringPtr* lhs, Arena* lhs_arena) { + // Silence unused variable warnings in release buildls. + (void)default_value; + (void)rhs_arena; + (void)lhs_arena; + std::swap(lhs->tagged_ptr_, rhs->tagged_ptr_); +#ifdef PROTOBUF_FORCE_COPY_IN_SWAP + auto force_realloc = [default_value](ArenaStringPtr* p, Arena* arena) { + if (p->IsDefault(default_value)) return; + TProtoStringType* old_value = p->tagged_ptr_.Get(); + TProtoStringType* new_value = + p->IsDonatedString() + ? Arena::Create<TProtoStringType>(arena, *old_value) + : Arena::Create<TProtoStringType>(arena, std::move(*old_value)); + if (arena == nullptr) delete old_value; + p->tagged_ptr_.Set(new_value); + }; + // Because, at this point, tagged_ptr_ has been swapped, arena should also be + // swapped. + force_realloc(lhs, rhs_arena); + force_realloc(rhs, lhs_arena); +#endif // PROTOBUF_FORCE_COPY_IN_SWAP +} + +inline void ArenaStringPtr::ClearNonDefaultToEmpty() { + // Unconditionally mask away the tag. + tagged_ptr_.Get()->clear(); +} + +inline TProtoStringType* ArenaStringPtr::MutableNoArenaNoDefault( + const TProtoStringType* default_value) { + // VERY IMPORTANT for performance and code size: this will reduce to a member + // variable load, a pointer check (against |default_value|, in practice a + // static global) and a branch to the slowpath (which calls operator new and + // the ctor). DO NOT add any tagged-pointer operations here. + if (IsDefault(default_value)) { + return SetAndReturnNewString(); + } else { + return UnsafeMutablePointer(); + } +} + +inline void ArenaStringPtr::DestroyNoArena(const TProtoStringType* default_value) { + if (!IsDefault(default_value)) { + DestroyNoArenaSlowPath(); + } +} + +inline TProtoStringType* ArenaStringPtr::UnsafeMutablePointer() { + GOOGLE_DCHECK(!tagged_ptr_.IsTagged()); + GOOGLE_DCHECK(tagged_ptr_.UnsafeGet() != nullptr); + return tagged_ptr_.UnsafeGet(); +} + + +} // namespace internal +} // namespace protobuf +} // namespace google + +#include <google/protobuf/port_undef.inc> + +#endif // GOOGLE_PROTOBUF_ARENASTRING_H__ diff --git a/contrib/libs/protobuf_old/src/google/protobuf/descriptor.cc b/contrib/libs/protobuf_old/src/google/protobuf/descriptor.cc new file mode 100644 index 0000000000..abf1bf02dd --- /dev/null +++ b/contrib/libs/protobuf_old/src/google/protobuf/descriptor.cc @@ -0,0 +1,8023 @@ +// 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: kenton@google.com (Kenton Varda) +// Based on original Protocol Buffers design by +// Sanjay Ghemawat, Jeff Dean, and others. + +#include <google/protobuf/descriptor.h> + +#include <algorithm> +#include <array> +#include <functional> +#include <limits> +#include <map> +#include <memory> +#include <set> +#include <string> +#include <unordered_map> +#include <unordered_set> +#include <vector> + +#include <google/protobuf/stubs/common.h> +#include <google/protobuf/stubs/logging.h> +#include <google/protobuf/stubs/stringprintf.h> +#include <google/protobuf/stubs/strutil.h> +#include <google/protobuf/any.h> +#include <google/protobuf/descriptor.pb.h> +#include <google/protobuf/stubs/once.h> +#include <google/protobuf/io/coded_stream.h> +#include <google/protobuf/io/tokenizer.h> +#include <google/protobuf/io/zero_copy_stream_impl.h> +#include <google/protobuf/descriptor_database.h> +#include <google/protobuf/dynamic_message.h> +#include <google/protobuf/generated_message_util.h> +#include <google/protobuf/text_format.h> +#include <google/protobuf/unknown_field_set.h> +#include <google/protobuf/wire_format.h> +#include <google/protobuf/stubs/casts.h> +#include <google/protobuf/stubs/substitute.h> +#include <google/protobuf/io/strtod.h> +#include <google/protobuf/stubs/map_util.h> +#include <google/protobuf/stubs/stl_util.h> +#include <google/protobuf/stubs/hash.h> + +#undef PACKAGE // autoheader #defines this. :( + + +#include <google/protobuf/port_def.inc> + +namespace google { +namespace protobuf { + +class Symbol { + public: + enum Type { + NULL_SYMBOL, + MESSAGE, + FIELD, + ONEOF, + ENUM, + ENUM_VALUE, + ENUM_VALUE_OTHER_PARENT, + SERVICE, + METHOD, + PACKAGE, + QUERY_KEY + }; + + Symbol() : ptr_(nullptr) {} + + // Every object we store derives from internal::SymbolBase, where we store the + // symbol type enum. + // Storing in the object can be done without using more space in most cases, + // while storing it in the Symbol type would require 8 bytes. +#define DEFINE_MEMBERS(TYPE, TYPE_CONSTANT, FIELD) \ + explicit Symbol(TYPE* value) : ptr_(value) { \ + value->symbol_type_ = TYPE_CONSTANT; \ + } \ + const TYPE* FIELD() const { \ + return type() == TYPE_CONSTANT ? static_cast<const TYPE*>(ptr_) : nullptr; \ + } + + DEFINE_MEMBERS(Descriptor, MESSAGE, descriptor) + DEFINE_MEMBERS(FieldDescriptor, FIELD, field_descriptor) + DEFINE_MEMBERS(OneofDescriptor, ONEOF, oneof_descriptor) + DEFINE_MEMBERS(EnumDescriptor, ENUM, enum_descriptor) + DEFINE_MEMBERS(ServiceDescriptor, SERVICE, service_descriptor) + DEFINE_MEMBERS(MethodDescriptor, METHOD, method_descriptor) + + // We use a special node for FileDescriptor. + // It is potentially added to the table with multiple different names, so we + // need a separate place to put the name. + struct Package : internal::SymbolBase { + const TProtoStringType* name; + const FileDescriptor* file; + }; + DEFINE_MEMBERS(Package, PACKAGE, package_file_descriptor) + + // Enum values have two different parents. + // We use two different identitied for the same object to determine the two + // different insertions in the map. + static Symbol EnumValue(EnumValueDescriptor* value, int n) { + Symbol s; + internal::SymbolBase* ptr; + if (n == 0) { + ptr = static_cast<internal::SymbolBaseN<0>*>(value); + ptr->symbol_type_ = ENUM_VALUE; + } else { + ptr = static_cast<internal::SymbolBaseN<1>*>(value); + ptr->symbol_type_ = ENUM_VALUE_OTHER_PARENT; + } + s.ptr_ = ptr; + return s; + } + + const EnumValueDescriptor* enum_value_descriptor() const { + return type() == ENUM_VALUE + ? static_cast<const EnumValueDescriptor*>( + static_cast<const internal::SymbolBaseN<0>*>(ptr_)) + : type() == ENUM_VALUE_OTHER_PARENT + ? static_cast<const EnumValueDescriptor*>( + static_cast<const internal::SymbolBaseN<1>*>(ptr_)) + : nullptr; + } + + // Not a real symbol. + // Only used for heterogeneous lookups and never actually inserted in the + // tables. + struct QueryKey : internal::SymbolBase { + StringPiece name; + const void* parent; + int field_number; + }; + DEFINE_MEMBERS(QueryKey, QUERY_KEY, query_key); +#undef DEFINE_MEMBERS + + Type type() const { + return ptr_ == nullptr ? NULL_SYMBOL + : static_cast<Type>(ptr_->symbol_type_); + } + bool IsNull() const { return type() == NULL_SYMBOL; } + bool IsType() const { return type() == MESSAGE || type() == ENUM; } + bool IsAggregate() const { + return type() == MESSAGE || type() == PACKAGE || type() == ENUM || + type() == SERVICE; + } + + const FileDescriptor* GetFile() const { + switch (type()) { + case MESSAGE: + return descriptor()->file(); + case FIELD: + return field_descriptor()->file(); + case ONEOF: + return oneof_descriptor()->containing_type()->file(); + case ENUM: + return enum_descriptor()->file(); + case ENUM_VALUE: + return enum_value_descriptor()->type()->file(); + case SERVICE: + return service_descriptor()->file(); + case METHOD: + return method_descriptor()->service()->file(); + case PACKAGE: + return package_file_descriptor()->file; + default: + return nullptr; + } + } + + StringPiece full_name() const { + switch (type()) { + case MESSAGE: + return descriptor()->full_name(); + case FIELD: + return field_descriptor()->full_name(); + case ONEOF: + return oneof_descriptor()->full_name(); + case ENUM: + return enum_descriptor()->full_name(); + case ENUM_VALUE: + return enum_value_descriptor()->full_name(); + case SERVICE: + return service_descriptor()->full_name(); + case METHOD: + return method_descriptor()->full_name(); + case PACKAGE: + return *package_file_descriptor()->name; + case QUERY_KEY: + return query_key()->name; + default: + GOOGLE_CHECK(false); + } + return ""; + } + + std::pair<const void*, StringPiece> parent_name_key() const { + const auto or_file = [&](const void* p) { return p ? p : GetFile(); }; + switch (type()) { + case MESSAGE: + return {or_file(descriptor()->containing_type()), descriptor()->name()}; + case FIELD: { + auto* field = field_descriptor(); + return {or_file(field->is_extension() ? field->extension_scope() + : field->containing_type()), + field->name()}; + } + case ONEOF: + return {oneof_descriptor()->containing_type(), + oneof_descriptor()->name()}; + case ENUM: + return {or_file(enum_descriptor()->containing_type()), + enum_descriptor()->name()}; + case ENUM_VALUE: + return {or_file(enum_value_descriptor()->type()->containing_type()), + enum_value_descriptor()->name()}; + case ENUM_VALUE_OTHER_PARENT: + return {enum_value_descriptor()->type(), + enum_value_descriptor()->name()}; + case SERVICE: + return {GetFile(), service_descriptor()->name()}; + case METHOD: + return {method_descriptor()->service(), method_descriptor()->name()}; + case QUERY_KEY: + return {query_key()->parent, query_key()->name}; + default: + GOOGLE_CHECK(false); + } + return {}; + } + + std::pair<const void*, int> parent_number_key() const { + switch (type()) { + case FIELD: + return {field_descriptor()->containing_type(), + field_descriptor()->number()}; + case ENUM_VALUE: + return {enum_value_descriptor()->type(), + enum_value_descriptor()->number()}; + case QUERY_KEY: + return {query_key()->parent, query_key()->field_number}; + default: + GOOGLE_CHECK(false); + } + return {}; + } + + private: + const internal::SymbolBase* ptr_; +}; + +const FieldDescriptor::CppType + FieldDescriptor::kTypeToCppTypeMap[MAX_TYPE + 1] = { + static_cast<CppType>(0), // 0 is reserved for errors + + CPPTYPE_DOUBLE, // TYPE_DOUBLE + CPPTYPE_FLOAT, // TYPE_FLOAT + CPPTYPE_INT64, // TYPE_INT64 + CPPTYPE_UINT64, // TYPE_UINT64 + CPPTYPE_INT32, // TYPE_INT32 + CPPTYPE_UINT64, // TYPE_FIXED64 + CPPTYPE_UINT32, // TYPE_FIXED32 + CPPTYPE_BOOL, // TYPE_BOOL + CPPTYPE_STRING, // TYPE_STRING + CPPTYPE_MESSAGE, // TYPE_GROUP + CPPTYPE_MESSAGE, // TYPE_MESSAGE + CPPTYPE_STRING, // TYPE_BYTES + CPPTYPE_UINT32, // TYPE_UINT32 + CPPTYPE_ENUM, // TYPE_ENUM + CPPTYPE_INT32, // TYPE_SFIXED32 + CPPTYPE_INT64, // TYPE_SFIXED64 + CPPTYPE_INT32, // TYPE_SINT32 + CPPTYPE_INT64, // TYPE_SINT64 +}; + +const char* const FieldDescriptor::kTypeToName[MAX_TYPE + 1] = { + "ERROR", // 0 is reserved for errors + + "double", // TYPE_DOUBLE + "float", // TYPE_FLOAT + "int64", // TYPE_INT64 + "uint64", // TYPE_UINT64 + "int32", // TYPE_INT32 + "fixed64", // TYPE_FIXED64 + "fixed32", // TYPE_FIXED32 + "bool", // TYPE_BOOL + "string", // TYPE_STRING + "group", // TYPE_GROUP + "message", // TYPE_MESSAGE + "bytes", // TYPE_BYTES + "uint32", // TYPE_UINT32 + "enum", // TYPE_ENUM + "sfixed32", // TYPE_SFIXED32 + "sfixed64", // TYPE_SFIXED64 + "sint32", // TYPE_SINT32 + "sint64", // TYPE_SINT64 +}; + +const char* const FieldDescriptor::kCppTypeToName[MAX_CPPTYPE + 1] = { + "ERROR", // 0 is reserved for errors + + "int32", // CPPTYPE_INT32 + "int64", // CPPTYPE_INT64 + "uint32", // CPPTYPE_UINT32 + "uint64", // CPPTYPE_UINT64 + "double", // CPPTYPE_DOUBLE + "float", // CPPTYPE_FLOAT + "bool", // CPPTYPE_BOOL + "enum", // CPPTYPE_ENUM + "string", // CPPTYPE_STRING + "message", // CPPTYPE_MESSAGE +}; + +const char* const FieldDescriptor::kLabelToName[MAX_LABEL + 1] = { + "ERROR", // 0 is reserved for errors + + "optional", // LABEL_OPTIONAL + "required", // LABEL_REQUIRED + "repeated", // LABEL_REPEATED +}; + +const char* FileDescriptor::SyntaxName(FileDescriptor::Syntax syntax) { + switch (syntax) { + case SYNTAX_PROTO2: + return "proto2"; + case SYNTAX_PROTO3: + return "proto3"; + case SYNTAX_UNKNOWN: + return "unknown"; + } + GOOGLE_LOG(FATAL) << "can't reach here."; + return nullptr; +} + +static const char* const kNonLinkedWeakMessageReplacementName = "google.protobuf.Empty"; + +#if !defined(_MSC_VER) || (_MSC_VER >= 1900 && _MSC_VER < 1912) +const int FieldDescriptor::kMaxNumber; +const int FieldDescriptor::kFirstReservedNumber; +const int FieldDescriptor::kLastReservedNumber; +#endif + +namespace { + +// Note: I distrust ctype.h due to locales. +char ToUpper(char ch) { + return (ch >= 'a' && ch <= 'z') ? (ch - 'a' + 'A') : ch; +} + +char ToLower(char ch) { + return (ch >= 'A' && ch <= 'Z') ? (ch - 'A' + 'a') : ch; +} + +TProtoStringType ToCamelCase(const TProtoStringType& input, bool lower_first) { + bool capitalize_next = !lower_first; + TProtoStringType result; + result.reserve(input.size()); + + for (char character : input) { + if (character == '_') { + capitalize_next = true; + } else if (capitalize_next) { + result.push_back(ToUpper(character)); + capitalize_next = false; + } else { + result.push_back(character); + } + } + + // Lower-case the first letter. + if (lower_first && !result.empty()) { + result[0] = ToLower(result[0]); + } + + return result; +} + +TProtoStringType ToJsonName(const TProtoStringType& input) { + bool capitalize_next = false; + TProtoStringType result; + result.reserve(input.size()); + + for (char character : input) { + if (character == '_') { + capitalize_next = true; + } else if (capitalize_next) { + result.push_back(ToUpper(character)); + capitalize_next = false; + } else { + result.push_back(character); + } + } + + return result; +} + +TProtoStringType EnumValueToPascalCase(const TProtoStringType& input) { + bool next_upper = true; + TProtoStringType result; + result.reserve(input.size()); + + for (char character : input) { + if (character == '_') { + next_upper = true; + } else { + if (next_upper) { + result.push_back(ToUpper(character)); + } else { + result.push_back(ToLower(character)); + } + next_upper = false; + } + } + + return result; +} + +// Class to remove an enum prefix from enum values. +class PrefixRemover { + public: + PrefixRemover(StringPiece prefix) { + // Strip underscores and lower-case the prefix. + for (char character : prefix) { + if (character != '_') { + prefix_ += ascii_tolower(character); + } + } + } + + // Tries to remove the enum prefix from this enum value. + // If this is not possible, returns the input verbatim. + TProtoStringType MaybeRemove(StringPiece str) { + // We can't just lowercase and strip str and look for a prefix. + // We need to properly recognize the difference between: + // + // enum Foo { + // FOO_BAR_BAZ = 0; + // FOO_BARBAZ = 1; + // } + // + // This is acceptable (though perhaps not advisable) because even when + // we PascalCase, these two will still be distinct (BarBaz vs. Barbaz). + size_t i, j; + + // Skip past prefix_ in str if we can. + for (i = 0, j = 0; i < str.size() && j < prefix_.size(); i++) { + if (str[i] == '_') { + continue; + } + + if (ascii_tolower(str[i]) != prefix_[j++]) { + return TProtoStringType(str); + } + } + + // If we didn't make it through the prefix, we've failed to strip the + // prefix. + if (j < prefix_.size()) { + return TProtoStringType(str); + } + + // Skip underscores between prefix and further characters. + while (i < str.size() && str[i] == '_') { + i++; + } + + // Enum label can't be the empty string. + if (i == str.size()) { + return TProtoStringType(str); + } + + // We successfully stripped the prefix. + str.remove_prefix(i); + return TProtoStringType(str); + } + + private: + TProtoStringType prefix_; +}; + +// A DescriptorPool contains a bunch of hash-maps to implement the +// various Find*By*() methods. Since hashtable lookups are O(1), it's +// most efficient to construct a fixed set of large hash-maps used by +// all objects in the pool rather than construct one or more small +// hash-maps for each object. +// +// The keys to these hash-maps are (parent, name) or (parent, number) pairs. + +typedef std::pair<const void*, StringPiece> PointerStringPair; + +typedef std::pair<const Descriptor*, int> DescriptorIntPair; + +#define HASH_MAP std::unordered_map +#define HASH_SET std::unordered_set +#define HASH_FXN hash + +template <typename PairType> +struct PointerIntegerPairHash { + size_t operator()(const PairType& p) const { + static const size_t prime1 = 16777499; + static const size_t prime2 = 16777619; + return reinterpret_cast<size_t>(p.first) * prime1 ^ + static_cast<size_t>(p.second) * prime2; + } + +#ifdef _MSC_VER + // Used only by MSVC and platforms where hash_map is not available. + static const size_t bucket_size = 4; + static const size_t min_buckets = 8; +#endif + inline bool operator()(const PairType& a, const PairType& b) const { + return a < b; + } +}; + +struct PointerStringPairHash { + size_t operator()(const PointerStringPair& p) const { + static const size_t prime = 16777619; + hash<StringPiece> string_hash; + return reinterpret_cast<size_t>(p.first) * prime ^ + static_cast<size_t>(string_hash(p.second)); + } + +#ifdef _MSC_VER + // Used only by MSVC and platforms where hash_map is not available. + static const size_t bucket_size = 4; + static const size_t min_buckets = 8; +#endif + inline bool operator()(const PointerStringPair& a, + const PointerStringPair& b) const { + return a < b; + } +}; + + +struct SymbolByFullNameHash { + size_t operator()(Symbol s) const { + return HASH_FXN<StringPiece>{}(s.full_name()); + } +}; +struct SymbolByFullNameEq { + bool operator()(Symbol a, Symbol b) const { + return a.full_name() == b.full_name(); + } +}; +using SymbolsByNameSet = + HASH_SET<Symbol, SymbolByFullNameHash, SymbolByFullNameEq>; + +struct SymbolByParentHash { + size_t operator()(Symbol s) const { + return PointerStringPairHash{}(s.parent_name_key()); + } +}; +struct SymbolByParentEq { + bool operator()(Symbol a, Symbol b) const { + return a.parent_name_key() == b.parent_name_key(); + } +}; +using SymbolsByParentSet = + HASH_SET<Symbol, SymbolByParentHash, SymbolByParentEq>; + +typedef HASH_MAP<StringPiece, const FileDescriptor*, + HASH_FXN<StringPiece>> + FilesByNameMap; + +typedef HASH_MAP<PointerStringPair, const FieldDescriptor*, + PointerStringPairHash> + FieldsByNameMap; + +struct FieldsByNumberHash { + size_t operator()(Symbol s) const { + return PointerIntegerPairHash<std::pair<const void*, int>>{}( + s.parent_number_key()); + } +}; +struct FieldsByNumberEq { + bool operator()(Symbol a, Symbol b) const { + return a.parent_number_key() == b.parent_number_key(); + } +}; +using FieldsByNumberSet = + HASH_SET<Symbol, FieldsByNumberHash, FieldsByNumberEq>; +using EnumValuesByNumberSet = FieldsByNumberSet; + +// This is a map rather than a hash-map, since we use it to iterate +// through all the extensions that extend a given Descriptor, and an +// ordered data structure that implements lower_bound is convenient +// for that. +typedef std::map<DescriptorIntPair, const FieldDescriptor*> + ExtensionsGroupedByDescriptorMap; +typedef HASH_MAP<TProtoStringType, const SourceCodeInfo_Location*> + LocationsByPathMap; + +std::set<TProtoStringType>* NewAllowedProto3Extendee() { + auto allowed_proto3_extendees = new std::set<TProtoStringType>; + const char* kOptionNames[] = { + "FileOptions", "MessageOptions", "FieldOptions", "EnumOptions", + "EnumValueOptions", "ServiceOptions", "MethodOptions", "OneofOptions"}; + for (const char* option_name : kOptionNames) { + // descriptor.proto has a different package name in opensource. We allow + // both so the opensource protocol compiler can also compile internal + // proto3 files with custom options. See: b/27567912 + allowed_proto3_extendees->insert(TProtoStringType("google.protobuf.") + + option_name); + // Split the word to trick the opensource processing scripts so they + // will keep the original package name. + allowed_proto3_extendees->insert(TProtoStringType("proto") + "2." + option_name); + } + return allowed_proto3_extendees; +} + +// Checks whether the extendee type is allowed in proto3. +// Only extensions to descriptor options are allowed. We use name comparison +// instead of comparing the descriptor directly because the extensions may be +// defined in a different pool. +bool AllowedExtendeeInProto3(const TProtoStringType& name) { + static auto allowed_proto3_extendees = + internal::OnShutdownDelete(NewAllowedProto3Extendee()); + return allowed_proto3_extendees->find(name) != + allowed_proto3_extendees->end(); +} + +// This bump allocator arena is optimized for the use case of this file. It is +// mostly optimized for memory usage, since these objects are expected to live +// for the entirety of the program. +// +// Some differences from other arenas: +// - It has a fixed number of non-trivial types it can hold. This allows +// tracking the allocations with a single byte. In contrast, google::protobuf::Arena +// uses 16 bytes per non-trivial object created. +// - It has some extra metadata for rollbacks. This is necessary for +// implementing the API below. This metadata is flushed at the end and would +// not cause persistent memory usage. +// - It tries to squeeze every byte of out the blocks. If an allocation is too +// large for the current block we move the block to a secondary area where we +// can still use it for smaller objects. This complicates rollback logic but +// makes it much more memory efficient. +// +// The allocation strategy is as follows: +// - Memory is allocated from the front, with a forced 8 byte alignment. +// - Metadata is allocated from the back, one byte per element. +// - The metadata encodes one of two things: +// * For types we want to track, the index into KnownTypes. +// * For raw memory blocks, the size of the block (in 8 byte increments +// to allow for a larger limit). +// - When the raw data is too large to represent in the metadata byte, we +// allocate this memory separately in the heap and store an OutOfLineAlloc +// object instead. These come from large array allocations and alike. +// +// Blocks are kept in 3 areas: +// - `current_` is the one we are currently allocating from. When we need to +// allocate a block that doesn't fit there, we make a new block and move the +// old `current_` to one of the areas below. +// - Blocks that have no more usable space left (ie less than 9 bytes) are +// stored in `full_blocks_`. +// - Blocks that have some usable space are categorized in +// `small_size_blocks_` depending on how much space they have left. +// See `kSmallSizes` to see which sizes we track. +// +class TableArena { + public: + // Allocate a block on `n` bytes, with no destructor information saved. + void* AllocateMemory(arc_ui32 n) { + arc_ui32 tag = SizeToRawTag(n) + kFirstRawTag; + if (tag > 255) { + // We can't fit the size, use an OutOfLineAlloc. + return Create<OutOfLineAlloc>(OutOfLineAlloc{::operator new(n), n})->ptr; + } + + return AllocRawInternal(n, static_cast<Tag>(tag)); + } + + // Allocate and construct an element of type `T` as if by + // `T(std::forward<Args>(args...))`. + // The object is registered for destruction, if its destructor is not trivial. + template <typename T, typename... Args> + T* Create(Args&&... args) { + static_assert(alignof(T) <= 8, ""); + return ::new (AllocRawInternal(sizeof(T), TypeTag<T>(KnownTypes{}))) + T(std::forward<Args>(args)...); + } + + TableArena() {} + + TableArena(const TableArena&) = delete; + TableArena& operator=(const TableArena&) = delete; + + ~TableArena() { + // Uncomment this to debug usage statistics of the arena blocks. + // PrintUsageInfo(); + + for (Block* list : GetLists()) { + while (list != nullptr) { + Block* b = list; + list = list->next; + b->VisitBlock(DestroyVisitor{}); + b->Destroy(); + } + } + } + + + // This function exists for debugging only. + // It can be called from the destructor to dump some info in the tests to + // inspect the usage of the arena. + void PrintUsageInfo() const { + const auto print_histogram = [](Block* b, int size) { + std::map<arc_ui32, arc_ui32> unused_space_count; + int count = 0; + for (; b != nullptr; b = b->next) { + ++unused_space_count[b->space_left()]; + ++count; + } + if (size > 0) { + fprintf(stderr, " Blocks `At least %d`", size); + } else { + fprintf(stderr, " Blocks `full`"); + } + fprintf(stderr, ": %d blocks.\n", count); + for (auto p : unused_space_count) { + fprintf(stderr, " space=%4u, count=%3u\n", p.first, p.second); + } + }; + + fprintf(stderr, "TableArena unused space histogram:\n"); + fprintf(stderr, " Current: %u\n", + current_ != nullptr ? current_->space_left() : 0); + print_histogram(full_blocks_, 0); + for (size_t i = 0; i < kSmallSizes.size(); ++i) { + print_histogram(small_size_blocks_[i], kSmallSizes[i]); + } + } + + // Current allocation count. + // This can be used for checkpointing. + size_t num_allocations() const { return num_allocations_; } + + // Rollback the latest allocations until we reach back to `checkpoint` + // num_allocations. + void RollbackTo(size_t checkpoint) { + while (num_allocations_ > checkpoint) { + GOOGLE_DCHECK(!rollback_info_.empty()); + auto& info = rollback_info_.back(); + Block* b = info.block; + + VisitAlloc(b->data(), &b->start_offset, &b->end_offset, DestroyVisitor{}, + KnownTypes{}); + if (--info.count == 0) { + rollback_info_.pop_back(); + } + --num_allocations_; + } + + // Reconstruct the lists and destroy empty blocks. + auto lists = GetLists(); + current_ = full_blocks_ = nullptr; + small_size_blocks_.fill(nullptr); + + for (Block* list : lists) { + while (list != nullptr) { + Block* b = list; + list = list->next; + + if (b->start_offset == 0) { + // This is empty, free it. + b->Destroy(); + } else { + RelocateToUsedList(b); + } + } + } + } + + // Clear all rollback information. Reduces memory usage. + // Trying to rollback past num_allocations() is now impossible. + void ClearRollbackData() { + rollback_info_.clear(); + rollback_info_.shrink_to_fit(); + } + + private: + static constexpr size_t RoundUp(size_t n) { return (n + 7) & ~7; } + + using Tag = unsigned char; + + void* AllocRawInternal(arc_ui32 size, Tag tag) { + GOOGLE_DCHECK_GT(size, 0); + size = RoundUp(size); + + Block* to_relocate = nullptr; + Block* to_use = nullptr; + + for (size_t i = 0; i < kSmallSizes.size(); ++i) { + if (small_size_blocks_[i] != nullptr && size <= kSmallSizes[i]) { + to_use = to_relocate = PopBlock(small_size_blocks_[i]); + break; + } + } + + if (to_relocate != nullptr) { + // We found one in the loop. + } else if (current_ != nullptr && size + 1 <= current_->space_left()) { + to_use = current_; + } else { + // No space left anywhere, make a new block. + to_relocate = current_; + // For now we hardcode the size to one page. Note that the maximum we can + // allocate in the block according to the limits of Tag is less than 2k, + // so this can fit anything that Tag can represent. + constexpr size_t kBlockSize = 4096; + to_use = current_ = ::new (::operator new(kBlockSize)) Block(kBlockSize); + GOOGLE_DCHECK_GE(current_->space_left(), size + 1); + } + + ++num_allocations_; + if (!rollback_info_.empty() && rollback_info_.back().block == to_use) { + ++rollback_info_.back().count; + } else { + rollback_info_.push_back({to_use, 1}); + } + + void* p = to_use->Allocate(size, tag); + if (to_relocate != nullptr) { + RelocateToUsedList(to_relocate); + } + return p; + } + + static void OperatorDelete(void* p, size_t s) { +#if defined(__GXX_DELETE_WITH_SIZE__) || defined(__cpp_sized_deallocation) + ::operator delete(p, s); +#else + ::operator delete(p); +#endif + } + + struct OutOfLineAlloc { + void* ptr; + arc_ui32 size; + }; + + template <typename... T> + struct TypeList { + static constexpr Tag kSize = static_cast<Tag>(sizeof...(T)); + }; + + template <typename T, typename Visitor> + static void RunVisitor(char* p, uint16_t* start, Visitor visit) { + *start -= RoundUp(sizeof(T)); + visit(reinterpret_cast<T*>(p + *start)); + } + + // Visit the allocation at the passed location. + // It updates start/end to be after the visited object. + // This allows visiting a whole block by calling the function in a loop. + template <typename Visitor, typename... T> + static void VisitAlloc(char* p, uint16_t* start, uint16_t* end, Visitor visit, + TypeList<T...>) { + const Tag tag = static_cast<Tag>(p[*end]); + if (tag >= kFirstRawTag) { + // Raw memory. Skip it. + *start -= TagToSize(tag); + } else { + using F = void (*)(char*, uint16_t*, Visitor); + static constexpr F kFuncs[] = {&RunVisitor<T, Visitor>...}; + kFuncs[tag](p, start, visit); + } + ++*end; + } + + template <typename U, typename... Ts> + static constexpr Tag TypeTag(TypeList<U, Ts...>) { + return 0; + } + + template < + typename U, typename T, typename... Ts, + typename = typename std::enable_if<!std::is_same<U, T>::value>::type> + static constexpr Tag TypeTag(TypeList<T, Ts...>) { + return 1 + TypeTag<U>(TypeList<Ts...>{}); + } + + template <typename U> + static constexpr Tag TypeTag(TypeList<>) { + static_assert(std::is_trivially_destructible<U>::value, ""); + return SizeToRawTag(sizeof(U)); + } + + using KnownTypes = + TypeList<OutOfLineAlloc, TProtoStringType, + // For name arrays + std::array<TProtoStringType, 2>, std::array<TProtoStringType, 3>, + std::array<TProtoStringType, 4>, std::array<TProtoStringType, 5>, + FileDescriptorTables, SourceCodeInfo, FileOptions, + MessageOptions, FieldOptions, ExtensionRangeOptions, + OneofOptions, EnumOptions, EnumValueOptions, ServiceOptions, + MethodOptions>; + static constexpr Tag kFirstRawTag = KnownTypes::kSize; + + + struct DestroyVisitor { + template <typename T> + void operator()(T* p) { + p->~T(); + } + void operator()(OutOfLineAlloc* p) { OperatorDelete(p->ptr, p->size); } + }; + + static arc_ui32 SizeToRawTag(size_t n) { return (RoundUp(n) / 8) - 1; } + + static arc_ui32 TagToSize(Tag tag) { + GOOGLE_DCHECK_GE(tag, kFirstRawTag); + return static_cast<arc_ui32>(tag - kFirstRawTag + 1) * 8; + } + + struct Block { + uint16_t start_offset; + uint16_t end_offset; + uint16_t capacity; + Block* next; + + // `allocated_size` is the total size of the memory block allocated. + // The `Block` structure is constructed at the start and the rest of the + // memory is used as the payload of the `Block`. + explicit Block(arc_ui32 allocated_size) { + start_offset = 0; + end_offset = capacity = + reinterpret_cast<char*>(this) + allocated_size - data(); + next = nullptr; + } + + char* data() { + return reinterpret_cast<char*>(this) + RoundUp(sizeof(Block)); + } + + arc_ui32 memory_used() { + return data() + capacity - reinterpret_cast<char*>(this); + } + arc_ui32 space_left() const { return end_offset - start_offset; } + + void* Allocate(arc_ui32 n, Tag tag) { + GOOGLE_DCHECK_LE(n + 1, space_left()); + void* p = data() + start_offset; + start_offset += n; + data()[--end_offset] = tag; + return p; + } + + void Destroy() { OperatorDelete(this, memory_used()); } + + void PrependTo(Block*& list) { + next = list; + list = this; + } + + template <typename Visitor> + void VisitBlock(Visitor visit) { + for (uint16_t s = start_offset, e = end_offset; s != 0;) { + VisitAlloc(data(), &s, &e, visit, KnownTypes{}); + } + } + }; + + Block* PopBlock(Block*& list) { + Block* res = list; + list = list->next; + return res; + } + + void RelocateToUsedList(Block* to_relocate) { + if (current_ == nullptr) { + current_ = to_relocate; + current_->next = nullptr; + return; + } else if (current_->space_left() < to_relocate->space_left()) { + std::swap(current_, to_relocate); + current_->next = nullptr; + } + + for (int i = kSmallSizes.size(); --i >= 0;) { + if (to_relocate->space_left() >= 1 + kSmallSizes[i]) { + to_relocate->PrependTo(small_size_blocks_[i]); + return; + } + } + + to_relocate->PrependTo(full_blocks_); + } + + static constexpr std::array<uint8_t, 6> kSmallSizes = { + {// Sizes for pointer arrays. + 8, 16, 24, 32, + // Sizes for string arrays (for descriptor names). + // The most common array sizes are 2 and 3. + 2 * sizeof(TProtoStringType), 3 * sizeof(TProtoStringType)}}; + + // Helper function to iterate all lists. + std::array<Block*, 2 + kSmallSizes.size()> GetLists() const { + std::array<Block*, 2 + kSmallSizes.size()> res; + res[0] = current_; + res[1] = full_blocks_; + std::copy(small_size_blocks_.begin(), small_size_blocks_.end(), &res[2]); + return res; + } + + Block* current_ = nullptr; + std::array<Block*, kSmallSizes.size()> small_size_blocks_ = {{}}; + Block* full_blocks_ = nullptr; + + size_t num_allocations_ = 0; + struct RollbackInfo { + Block* block; + size_t count; + }; + std::vector<RollbackInfo> rollback_info_; +}; + +constexpr std::array<uint8_t, 6> TableArena::kSmallSizes; + +} // anonymous namespace + +// =================================================================== +// DescriptorPool::Tables + +class DescriptorPool::Tables { + public: + Tables(); + ~Tables(); + + // Record the current state of the tables to the stack of checkpoints. + // Each call to AddCheckpoint() must be paired with exactly one call to either + // ClearLastCheckpoint() or RollbackToLastCheckpoint(). + // + // This is used when building files, since some kinds of validation errors + // cannot be detected until the file's descriptors have already been added to + // the tables. + // + // This supports recursive checkpoints, since building a file may trigger + // recursive building of other files. Note that recursive checkpoints are not + // normally necessary; explicit dependencies are built prior to checkpointing. + // So although we recursively build transitive imports, there is at most one + // checkpoint in the stack during dependency building. + // + // Recursive checkpoints only arise during cross-linking of the descriptors. + // Symbol references must be resolved, via DescriptorBuilder::FindSymbol and + // friends. If the pending file references an unknown symbol + // (e.g., it is not defined in the pending file's explicit dependencies), and + // the pool is using a fallback database, and that database contains a file + // defining that symbol, and that file has not yet been built by the pool, + // the pool builds the file during cross-linking, leading to another + // checkpoint. + void AddCheckpoint(); + + // Mark the last checkpoint as having cleared successfully, removing it from + // the stack. If the stack is empty, all pending symbols will be committed. + // + // Note that this does not guarantee that the symbols added since the last + // checkpoint won't be rolled back: if a checkpoint gets rolled back, + // everything past that point gets rolled back, including symbols added after + // checkpoints that were pushed onto the stack after it and marked as cleared. + void ClearLastCheckpoint(); + + // Roll back the Tables to the state of the checkpoint at the top of the + // stack, removing everything that was added after that point. + void RollbackToLastCheckpoint(); + + // The stack of files which are currently being built. Used to detect + // cyclic dependencies when loading files from a DescriptorDatabase. Not + // used when fallback_database_ == nullptr. + std::vector<TProtoStringType> pending_files_; + + // A set of files which we have tried to load from the fallback database + // and encountered errors. We will not attempt to load them again during + // execution of the current public API call, but for compatibility with + // legacy clients, this is cleared at the beginning of each public API call. + // Not used when fallback_database_ == nullptr. + HASH_SET<TProtoStringType> known_bad_files_; + + // A set of symbols which we have tried to load from the fallback database + // and encountered errors. We will not attempt to load them again during + // execution of the current public API call, but for compatibility with + // legacy clients, this is cleared at the beginning of each public API call. + HASH_SET<TProtoStringType> known_bad_symbols_; + + // The set of descriptors for which we've already loaded the full + // set of extensions numbers from fallback_database_. + HASH_SET<const Descriptor*> extensions_loaded_from_db_; + + // Maps type name to Descriptor::WellKnownType. This is logically global + // and const, but we make it a member here to simplify its construction and + // destruction. This only has 20-ish entries and is one per DescriptorPool, + // so the overhead is small. + HASH_MAP<TProtoStringType, Descriptor::WellKnownType> well_known_types_; + + // ----------------------------------------------------------------- + // Finding items. + + // Find symbols. This returns a null Symbol (symbol.IsNull() is true) + // if not found. + inline Symbol FindSymbol(StringPiece key) const; + + // This implements the body of DescriptorPool::Find*ByName(). It should + // really be a private method of DescriptorPool, but that would require + // declaring Symbol in descriptor.h, which would drag all kinds of other + // stuff into the header. Yay C++. + Symbol FindByNameHelper(const DescriptorPool* pool, StringPiece name); + + // These return nullptr if not found. + inline const FileDescriptor* FindFile(StringPiece key) const; + inline const FieldDescriptor* FindExtension(const Descriptor* extendee, + int number) const; + inline void FindAllExtensions(const Descriptor* extendee, + std::vector<const FieldDescriptor*>* out) const; + + // ----------------------------------------------------------------- + // Adding items. + + // These add items to the corresponding tables. They return false if + // the key already exists in the table. For AddSymbol(), the string passed + // in must be one that was constructed using AllocateString(), as it will + // be used as a key in the symbols_by_name_ map without copying. + bool AddSymbol(const TProtoStringType& full_name, Symbol symbol); + bool AddFile(const FileDescriptor* file); + bool AddExtension(const FieldDescriptor* field); + + // ----------------------------------------------------------------- + // Allocating memory. + + // Allocate an object which will be reclaimed when the pool is + // destroyed. Note that the object's destructor will never be called, + // so its fields must be plain old data (primitive data types and + // pointers). All of the descriptor types are such objects. + template <typename Type> + Type* Allocate(); + + // Allocate an array of objects which will be reclaimed when the + // pool in destroyed. Again, destructors are never called. + template <typename Type> + Type* AllocateArray(int count); + + // Allocate a string which will be destroyed when the pool is destroyed. + // The string is initialized to the given value for convenience. + const TProtoStringType* AllocateString(StringPiece value); + + // Copy the input into a NUL terminated string whose lifetime is managed by + // the pool. + const char* Strdup(StringPiece value); + + // Allocates an array of strings which will be destroyed when the pool is + // destroyed. The array is initialized with the input values. + template <typename... In> + const TProtoStringType* AllocateStringArray(In&&... values); + + struct FieldNamesResult { + TProtoStringType* array; + int lowercase_index; + int camelcase_index; + int json_index; + }; + // Allocate all 5 names of the field: + // name, full name, lowercase, camelcase and json. + // This function will dedup the strings when possible. + // The resulting array contains `name` at index 0, `full_name` at index 1 and + // the other 3 indices are specified in the result. + FieldNamesResult AllocateFieldNames(const TProtoStringType& name, + const TProtoStringType& scope, + const TProtoStringType* opt_json_name); + + // Create an object that will be deleted when the pool is destroyed. + // The object is value initialized, and its destructor will be called if + // non-trivial. + template <typename Type> + Type* Create(); + + // Allocate a protocol message object. Some older versions of GCC have + // trouble understanding explicit template instantiations in some cases, so + // in those cases we have to pass a dummy pointer of the right type as the + // parameter instead of specifying the type explicitly. + template <typename Type> + Type* AllocateMessage(Type* dummy = nullptr); + + // Allocate a FileDescriptorTables object. + FileDescriptorTables* AllocateFileTables(); + + private: + // All other memory allocated in the pool. Must be first as other objects can + // point into these. + TableArena arena_; + + SymbolsByNameSet symbols_by_name_; + FilesByNameMap files_by_name_; + ExtensionsGroupedByDescriptorMap extensions_; + + struct CheckPoint { + explicit CheckPoint(const Tables* tables) + : arena_before_checkpoint(tables->arena_.num_allocations()), + pending_symbols_before_checkpoint( + tables->symbols_after_checkpoint_.size()), + pending_files_before_checkpoint( + tables->files_after_checkpoint_.size()), + pending_extensions_before_checkpoint( + tables->extensions_after_checkpoint_.size()) {} + int arena_before_checkpoint; + int pending_symbols_before_checkpoint; + int pending_files_before_checkpoint; + int pending_extensions_before_checkpoint; + }; + std::vector<CheckPoint> checkpoints_; + std::vector<const char*> symbols_after_checkpoint_; + std::vector<const char*> files_after_checkpoint_; + std::vector<DescriptorIntPair> extensions_after_checkpoint_; + + // Allocate some bytes which will be reclaimed when the pool is + // destroyed. + void* AllocateBytes(int size); +}; + +// Contains tables specific to a particular file. These tables are not +// modified once the file has been constructed, so they need not be +// protected by a mutex. This makes operations that depend only on the +// contents of a single file -- e.g. Descriptor::FindFieldByName() -- +// lock-free. +// +// For historical reasons, the definitions of the methods of +// FileDescriptorTables and DescriptorPool::Tables are interleaved below. +// These used to be a single class. +class FileDescriptorTables { + public: + FileDescriptorTables(); + ~FileDescriptorTables(); + + // Empty table, used with placeholder files. + inline static const FileDescriptorTables& GetEmptyInstance(); + + // ----------------------------------------------------------------- + // Finding items. + + // Returns a null Symbol (symbol.IsNull() is true) if not found. + inline Symbol FindNestedSymbol(const void* parent, + StringPiece name) const; + + // These return nullptr if not found. + inline const FieldDescriptor* FindFieldByNumber(const Descriptor* parent, + int number) const; + inline const FieldDescriptor* FindFieldByLowercaseName( + const void* parent, StringPiece lowercase_name) const; + inline const FieldDescriptor* FindFieldByCamelcaseName( + const void* parent, StringPiece camelcase_name) const; + inline const EnumValueDescriptor* FindEnumValueByNumber( + const EnumDescriptor* parent, int number) const; + // This creates a new EnumValueDescriptor if not found, in a thread-safe way. + inline const EnumValueDescriptor* FindEnumValueByNumberCreatingIfUnknown( + const EnumDescriptor* parent, int number) const; + + // ----------------------------------------------------------------- + // Adding items. + + // These add items to the corresponding tables. They return false if + // the key already exists in the table. For AddAliasUnderParent(), the + // string passed in must be one that was constructed using AllocateString(), + // as it will be used as a key in the symbols_by_parent_ map without copying. + bool AddAliasUnderParent(const void* parent, const TProtoStringType& name, + Symbol symbol); + bool AddFieldByNumber(FieldDescriptor* field); + bool AddEnumValueByNumber(EnumValueDescriptor* value); + + // Adds the field to the lowercase_name and camelcase_name maps. Never + // fails because we allow duplicates; the first field by the name wins. + void AddFieldByStylizedNames(const FieldDescriptor* field); + + // Populates p->first->locations_by_path_ from p->second. + // Unusual signature dictated by internal::call_once. + static void BuildLocationsByPath( + std::pair<const FileDescriptorTables*, const SourceCodeInfo*>* p); + + // Returns the location denoted by the specified path through info, + // or nullptr if not found. + // The value of info must be that of the corresponding FileDescriptor. + // (Conceptually a pure function, but stateful as an optimisation.) + const SourceCodeInfo_Location* GetSourceLocation( + const std::vector<int>& path, const SourceCodeInfo* info) const; + + // Must be called after BuildFileImpl(), even if the build failed and + // we are going to roll back to the last checkpoint. + void FinalizeTables(); + + private: + const void* FindParentForFieldsByMap(const FieldDescriptor* field) const; + static void FieldsByLowercaseNamesLazyInitStatic( + const FileDescriptorTables* tables); + void FieldsByLowercaseNamesLazyInitInternal() const; + static void FieldsByCamelcaseNamesLazyInitStatic( + const FileDescriptorTables* tables); + void FieldsByCamelcaseNamesLazyInitInternal() const; + + SymbolsByParentSet symbols_by_parent_; + mutable FieldsByNameMap fields_by_lowercase_name_; + std::unique_ptr<FieldsByNameMap> fields_by_lowercase_name_tmp_; + mutable internal::once_flag fields_by_lowercase_name_once_; + mutable FieldsByNameMap fields_by_camelcase_name_; + std::unique_ptr<FieldsByNameMap> fields_by_camelcase_name_tmp_; + mutable internal::once_flag fields_by_camelcase_name_once_; + FieldsByNumberSet fields_by_number_; // Not including extensions. + EnumValuesByNumberSet enum_values_by_number_; + mutable EnumValuesByNumberSet unknown_enum_values_by_number_ + PROTOBUF_GUARDED_BY(unknown_enum_values_mu_); + + // Populated on first request to save space, hence constness games. + mutable internal::once_flag locations_by_path_once_; + mutable LocationsByPathMap locations_by_path_; + + // Mutex to protect the unknown-enum-value map due to dynamic + // EnumValueDescriptor creation on unknown values. + mutable internal::WrappedMutex unknown_enum_values_mu_; +}; + +DescriptorPool::Tables::Tables() { + well_known_types_.insert({ + {"google.protobuf.DoubleValue", Descriptor::WELLKNOWNTYPE_DOUBLEVALUE}, + {"google.protobuf.FloatValue", Descriptor::WELLKNOWNTYPE_FLOATVALUE}, + {"google.protobuf.Int64Value", Descriptor::WELLKNOWNTYPE_INT64VALUE}, + {"google.protobuf.UInt64Value", Descriptor::WELLKNOWNTYPE_UINT64VALUE}, + {"google.protobuf.Int32Value", Descriptor::WELLKNOWNTYPE_INT32VALUE}, + {"google.protobuf.UInt32Value", Descriptor::WELLKNOWNTYPE_UINT32VALUE}, + {"google.protobuf.StringValue", Descriptor::WELLKNOWNTYPE_STRINGVALUE}, + {"google.protobuf.BytesValue", Descriptor::WELLKNOWNTYPE_BYTESVALUE}, + {"google.protobuf.BoolValue", Descriptor::WELLKNOWNTYPE_BOOLVALUE}, + {"google.protobuf.Any", Descriptor::WELLKNOWNTYPE_ANY}, + {"google.protobuf.FieldMask", Descriptor::WELLKNOWNTYPE_FIELDMASK}, + {"google.protobuf.Duration", Descriptor::WELLKNOWNTYPE_DURATION}, + {"google.protobuf.Timestamp", Descriptor::WELLKNOWNTYPE_TIMESTAMP}, + {"google.protobuf.Value", Descriptor::WELLKNOWNTYPE_VALUE}, + {"google.protobuf.ListValue", Descriptor::WELLKNOWNTYPE_LISTVALUE}, + {"google.protobuf.Struct", Descriptor::WELLKNOWNTYPE_STRUCT}, + }); +} + +DescriptorPool::Tables::~Tables() { GOOGLE_DCHECK(checkpoints_.empty()); } + +FileDescriptorTables::FileDescriptorTables() + : fields_by_lowercase_name_tmp_(new FieldsByNameMap()), + fields_by_camelcase_name_tmp_(new FieldsByNameMap()) {} + +FileDescriptorTables::~FileDescriptorTables() {} + +inline const FileDescriptorTables& FileDescriptorTables::GetEmptyInstance() { + static auto file_descriptor_tables = + internal::OnShutdownDelete(new FileDescriptorTables()); + return *file_descriptor_tables; +} + +void DescriptorPool::Tables::AddCheckpoint() { + checkpoints_.push_back(CheckPoint(this)); +} + +void DescriptorPool::Tables::ClearLastCheckpoint() { + GOOGLE_DCHECK(!checkpoints_.empty()); + checkpoints_.pop_back(); + if (checkpoints_.empty()) { + // All checkpoints have been cleared: we can now commit all of the pending + // data. + symbols_after_checkpoint_.clear(); + files_after_checkpoint_.clear(); + extensions_after_checkpoint_.clear(); + arena_.ClearRollbackData(); + } +} + +void DescriptorPool::Tables::RollbackToLastCheckpoint() { + GOOGLE_DCHECK(!checkpoints_.empty()); + const CheckPoint& checkpoint = checkpoints_.back(); + + for (size_t i = checkpoint.pending_symbols_before_checkpoint; + i < symbols_after_checkpoint_.size(); i++) { + Symbol::QueryKey name; + name.name = symbols_after_checkpoint_[i]; + symbols_by_name_.erase(Symbol(&name)); + } + for (size_t i = checkpoint.pending_files_before_checkpoint; + i < files_after_checkpoint_.size(); i++) { + files_by_name_.erase(files_after_checkpoint_[i]); + } + for (size_t i = checkpoint.pending_extensions_before_checkpoint; + i < extensions_after_checkpoint_.size(); i++) { + extensions_.erase(extensions_after_checkpoint_[i]); + } + + symbols_after_checkpoint_.resize( + checkpoint.pending_symbols_before_checkpoint); + files_after_checkpoint_.resize(checkpoint.pending_files_before_checkpoint); + extensions_after_checkpoint_.resize( + checkpoint.pending_extensions_before_checkpoint); + + arena_.RollbackTo(checkpoint.arena_before_checkpoint); + checkpoints_.pop_back(); +} + +// ------------------------------------------------------------------- + +inline Symbol DescriptorPool::Tables::FindSymbol(StringPiece key) const { + Symbol::QueryKey name; + name.name = key; + auto it = symbols_by_name_.find(Symbol(&name)); + return it == symbols_by_name_.end() ? Symbol() : *it; +} + +inline Symbol FileDescriptorTables::FindNestedSymbol( + const void* parent, StringPiece name) const { + Symbol::QueryKey query; + query.name = name; + query.parent = parent; + auto it = symbols_by_parent_.find(Symbol(&query)); + return it == symbols_by_parent_.end() ? Symbol() : *it; +} + +Symbol DescriptorPool::Tables::FindByNameHelper(const DescriptorPool* pool, + StringPiece name) { + if (pool->mutex_ != nullptr) { + // Fast path: the Symbol is already cached. This is just a hash lookup. + ReaderMutexLock lock(pool->mutex_); + if (known_bad_symbols_.empty() && known_bad_files_.empty()) { + Symbol result = FindSymbol(name); + if (!result.IsNull()) return result; + } + } + MutexLockMaybe lock(pool->mutex_); + if (pool->fallback_database_ != nullptr) { + known_bad_symbols_.clear(); + known_bad_files_.clear(); + } + Symbol result = FindSymbol(name); + + if (result.IsNull() && pool->underlay_ != nullptr) { + // Symbol not found; check the underlay. + result = pool->underlay_->tables_->FindByNameHelper(pool->underlay_, name); + } + + if (result.IsNull()) { + // Symbol still not found, so check fallback database. + if (pool->TryFindSymbolInFallbackDatabase(name)) { + result = FindSymbol(name); + } + } + + return result; +} + +inline const FileDescriptor* DescriptorPool::Tables::FindFile( + StringPiece key) const { + return FindPtrOrNull(files_by_name_, key); +} + +inline const FieldDescriptor* FileDescriptorTables::FindFieldByNumber( + const Descriptor* parent, int number) const { + // If `number` is within the sequential range, just index into the parent + // without doing a table lookup. + if (parent != nullptr && // + 1 <= number && number <= parent->sequential_field_limit_) { + return parent->field(number - 1); + } + + Symbol::QueryKey query; + query.parent = parent; + query.field_number = number; + + auto it = fields_by_number_.find(Symbol(&query)); + return it == fields_by_number_.end() ? nullptr : it->field_descriptor(); +} + +const void* FileDescriptorTables::FindParentForFieldsByMap( + const FieldDescriptor* field) const { + if (field->is_extension()) { + if (field->extension_scope() == nullptr) { + return field->file(); + } else { + return field->extension_scope(); + } + } else { + return field->containing_type(); + } +} + +void FileDescriptorTables::FieldsByLowercaseNamesLazyInitStatic( + const FileDescriptorTables* tables) { + tables->FieldsByLowercaseNamesLazyInitInternal(); +} + +void FileDescriptorTables::FieldsByLowercaseNamesLazyInitInternal() const { + for (Symbol symbol : symbols_by_parent_) { + const FieldDescriptor* field = symbol.field_descriptor(); + if (!field) continue; + PointerStringPair lowercase_key(FindParentForFieldsByMap(field), + field->lowercase_name().c_str()); + InsertIfNotPresent(&fields_by_lowercase_name_, lowercase_key, field); + } +} + +inline const FieldDescriptor* FileDescriptorTables::FindFieldByLowercaseName( + const void* parent, StringPiece lowercase_name) const { + internal::call_once( + fields_by_lowercase_name_once_, + &FileDescriptorTables::FieldsByLowercaseNamesLazyInitStatic, this); + return FindPtrOrNull(fields_by_lowercase_name_, + PointerStringPair(parent, lowercase_name)); +} + +void FileDescriptorTables::FieldsByCamelcaseNamesLazyInitStatic( + const FileDescriptorTables* tables) { + tables->FieldsByCamelcaseNamesLazyInitInternal(); +} + +void FileDescriptorTables::FieldsByCamelcaseNamesLazyInitInternal() const { + for (Symbol symbol : symbols_by_parent_) { + const FieldDescriptor* field = symbol.field_descriptor(); + if (!field) continue; + PointerStringPair camelcase_key(FindParentForFieldsByMap(field), + field->camelcase_name().c_str()); + InsertIfNotPresent(&fields_by_camelcase_name_, camelcase_key, field); + } +} + +inline const FieldDescriptor* FileDescriptorTables::FindFieldByCamelcaseName( + const void* parent, StringPiece camelcase_name) const { + internal::call_once( + fields_by_camelcase_name_once_, + FileDescriptorTables::FieldsByCamelcaseNamesLazyInitStatic, this); + return FindPtrOrNull(fields_by_camelcase_name_, + PointerStringPair(parent, camelcase_name)); +} + +inline const EnumValueDescriptor* FileDescriptorTables::FindEnumValueByNumber( + const EnumDescriptor* parent, int number) const { + // If `number` is within the sequential range, just index into the parent + // without doing a table lookup. + const int base = parent->value(0)->number(); + if (base <= number && + number <= static_cast<arc_i64>(base) + parent->sequential_value_limit_) { + return parent->value(number - base); + } + + Symbol::QueryKey query; + query.parent = parent; + query.field_number = number; + + auto it = enum_values_by_number_.find(Symbol(&query)); + return it == enum_values_by_number_.end() ? nullptr + : it->enum_value_descriptor(); +} + +inline const EnumValueDescriptor* +FileDescriptorTables::FindEnumValueByNumberCreatingIfUnknown( + const EnumDescriptor* parent, int number) const { + // First try, with map of compiled-in values. + { + const auto* value = FindEnumValueByNumber(parent, number); + if (value != nullptr) { + return value; + } + } + + Symbol::QueryKey query; + query.parent = parent; + query.field_number = number; + + // Second try, with reader lock held on unknown enum values: common case. + { + ReaderMutexLock l(&unknown_enum_values_mu_); + auto it = unknown_enum_values_by_number_.find(Symbol(&query)); + if (it != unknown_enum_values_by_number_.end() && + it->enum_value_descriptor() != nullptr) { + return it->enum_value_descriptor(); + } + } + // If not found, try again with writer lock held, and create new descriptor if + // necessary. + { + WriterMutexLock l(&unknown_enum_values_mu_); + auto it = unknown_enum_values_by_number_.find(Symbol(&query)); + if (it != unknown_enum_values_by_number_.end() && + it->enum_value_descriptor() != nullptr) { + return it->enum_value_descriptor(); + } + + // Create an EnumValueDescriptor dynamically. We don't insert it into the + // EnumDescriptor (it's not a part of the enum as originally defined), but + // we do insert it into the table so that we can return the same pointer + // later. + TProtoStringType enum_value_name = StringPrintf("UNKNOWN_ENUM_VALUE_%s_%d", + parent->name().c_str(), number); + auto* pool = DescriptorPool::generated_pool(); + auto* tables = const_cast<DescriptorPool::Tables*>(pool->tables_.get()); + EnumValueDescriptor* result; + { + // Must lock the pool because we will do allocations in the shared arena. + MutexLockMaybe l2(pool->mutex_); + result = tables->Allocate<EnumValueDescriptor>(); + result->all_names_ = tables->AllocateStringArray( + enum_value_name, + StrCat(parent->full_name(), ".", enum_value_name)); + } + result->number_ = number; + result->type_ = parent; + result->options_ = &EnumValueOptions::default_instance(); + unknown_enum_values_by_number_.insert(Symbol::EnumValue(result, 0)); + return result; + } +} + +inline const FieldDescriptor* DescriptorPool::Tables::FindExtension( + const Descriptor* extendee, int number) const { + return FindPtrOrNull(extensions_, std::make_pair(extendee, number)); +} + +inline void DescriptorPool::Tables::FindAllExtensions( + const Descriptor* extendee, + std::vector<const FieldDescriptor*>* out) const { + ExtensionsGroupedByDescriptorMap::const_iterator it = + extensions_.lower_bound(std::make_pair(extendee, 0)); + for (; it != extensions_.end() && it->first.first == extendee; ++it) { + out->push_back(it->second); + } +} + +// ------------------------------------------------------------------- + +bool DescriptorPool::Tables::AddSymbol(const TProtoStringType& full_name, + Symbol symbol) { + GOOGLE_DCHECK_EQ(full_name, symbol.full_name()); + if (symbols_by_name_.insert(symbol).second) { + symbols_after_checkpoint_.push_back(full_name.c_str()); + return true; + } else { + return false; + } +} + +bool FileDescriptorTables::AddAliasUnderParent(const void* parent, + const TProtoStringType& name, + Symbol symbol) { + GOOGLE_DCHECK_EQ(name, symbol.parent_name_key().second); + GOOGLE_DCHECK_EQ(parent, symbol.parent_name_key().first); + return symbols_by_parent_.insert(symbol).second; +} + +bool DescriptorPool::Tables::AddFile(const FileDescriptor* file) { + if (InsertIfNotPresent(&files_by_name_, file->name(), file)) { + files_after_checkpoint_.push_back(file->name().c_str()); + return true; + } else { + return false; + } +} + +void FileDescriptorTables::FinalizeTables() { + // Clean up the temporary maps used by AddFieldByStylizedNames(). + fields_by_lowercase_name_tmp_ = nullptr; + fields_by_camelcase_name_tmp_ = nullptr; +} + +void FileDescriptorTables::AddFieldByStylizedNames( + const FieldDescriptor* field) { + const void* parent = FindParentForFieldsByMap(field); + + // We want fields_by_{lower,camel}case_name_ to be lazily built, but + // cross-link order determines which entry will be present in the case of a + // conflict. So we use the temporary maps that get destroyed after + // BuildFileImpl() to detect the conflicts, and only store the conflicts in + // the map that will persist. We will then lazily populate the rest of the + // entries from fields_by_number_. + + PointerStringPair lowercase_key(parent, field->lowercase_name().c_str()); + if (!InsertIfNotPresent(fields_by_lowercase_name_tmp_.get(), + lowercase_key, field)) { + InsertIfNotPresent( + &fields_by_lowercase_name_, lowercase_key, + FindPtrOrNull(*fields_by_lowercase_name_tmp_, lowercase_key)); + } + + PointerStringPair camelcase_key(parent, field->camelcase_name().c_str()); + if (!InsertIfNotPresent(fields_by_camelcase_name_tmp_.get(), + camelcase_key, field)) { + InsertIfNotPresent( + &fields_by_camelcase_name_, camelcase_key, + FindPtrOrNull(*fields_by_camelcase_name_tmp_, camelcase_key)); + } +} + +bool FileDescriptorTables::AddFieldByNumber(FieldDescriptor* field) { + // Skip fields that are at the start of the sequence. + if (field->containing_type() != nullptr && field->number() >= 1 && + field->number() <= field->containing_type()->sequential_field_limit_) { + if (field->is_extension()) { + // Conflicts with the field that already exists in the sequential range. + return false; + } + // Only return true if the field at that index matches. Otherwise it + // conflicts with the existing field in the sequential range. + return field->containing_type()->field(field->number() - 1) == field; + } + + return fields_by_number_.insert(Symbol(field)).second; +} + +bool FileDescriptorTables::AddEnumValueByNumber(EnumValueDescriptor* value) { + // Skip values that are at the start of the sequence. + const int base = value->type()->value(0)->number(); + if (base <= value->number() && + value->number() <= + static_cast<arc_i64>(base) + value->type()->sequential_value_limit_) + return true; + return enum_values_by_number_.insert(Symbol::EnumValue(value, 0)).second; +} + +bool DescriptorPool::Tables::AddExtension(const FieldDescriptor* field) { + DescriptorIntPair key(field->containing_type(), field->number()); + if (InsertIfNotPresent(&extensions_, key, field)) { + extensions_after_checkpoint_.push_back(key); + return true; + } else { + return false; + } +} + +// ------------------------------------------------------------------- + +template <typename Type> +Type* DescriptorPool::Tables::Allocate() { + return reinterpret_cast<Type*>(AllocateBytes(sizeof(Type))); +} + +template <typename Type> +Type* DescriptorPool::Tables::AllocateArray(int count) { + return reinterpret_cast<Type*>(AllocateBytes(sizeof(Type) * count)); +} + +const TProtoStringType* DescriptorPool::Tables::AllocateString( + StringPiece value) { + return arena_.Create<TProtoStringType>(value); +} + +const char* DescriptorPool::Tables::Strdup(StringPiece value) { + char* p = AllocateArray<char>(static_cast<int>(value.size() + 1)); + memcpy(p, value.data(), value.size()); + p[value.size()] = 0; + return p; +} + +template <typename... In> +const TProtoStringType* DescriptorPool::Tables::AllocateStringArray(In&&... values) { + auto& array = *arena_.Create<std::array<TProtoStringType, sizeof...(In)>>(); + array = {{TProtoStringType(std::forward<In>(values))...}}; + return array.data(); +} + +DescriptorPool::Tables::FieldNamesResult +DescriptorPool::Tables::AllocateFieldNames(const TProtoStringType& name, + const TProtoStringType& scope, + const TProtoStringType* opt_json_name) { + TProtoStringType lowercase_name = name; + LowerString(&lowercase_name); + + TProtoStringType camelcase_name = ToCamelCase(name, /* lower_first = */ true); + TProtoStringType json_name; + if (opt_json_name != nullptr) { + json_name = *opt_json_name; + } else { + json_name = ToJsonName(name); + } + + const bool lower_eq_name = lowercase_name == name; + const bool camel_eq_name = camelcase_name == name; + const bool json_eq_name = json_name == name; + const bool json_eq_camel = json_name == camelcase_name; + + const int total_count = 2 + (lower_eq_name ? 0 : 1) + + (camel_eq_name ? 0 : 1) + + (json_eq_name || json_eq_camel ? 0 : 1); + FieldNamesResult result{nullptr, 0, 0, 0}; + // We use std::array to allow handling of the destruction of the strings. + switch (total_count) { + case 2: + result.array = arena_.Create<std::array<TProtoStringType, 2>>()->data(); + break; + case 3: + result.array = arena_.Create<std::array<TProtoStringType, 3>>()->data(); + break; + case 4: + result.array = arena_.Create<std::array<TProtoStringType, 4>>()->data(); + break; + case 5: + result.array = arena_.Create<std::array<TProtoStringType, 5>>()->data(); + break; + } + + result.array[0] = name; + if (scope.empty()) { + result.array[1] = name; + } else { + result.array[1] = StrCat(scope, ".", name); + } + int index = 2; + if (lower_eq_name) { + result.lowercase_index = 0; + } else { + result.lowercase_index = index; + result.array[index++] = std::move(lowercase_name); + } + + if (camel_eq_name) { + result.camelcase_index = 0; + } else { + result.camelcase_index = index; + result.array[index++] = std::move(camelcase_name); + } + + if (json_eq_name) { + result.json_index = 0; + } else if (json_eq_camel) { + result.json_index = result.camelcase_index; + } else { + result.json_index = index; + result.array[index] = std::move(json_name); + } + + return result; +} + +template <typename Type> +Type* DescriptorPool::Tables::Create() { + return arena_.Create<Type>(); +} + +template <typename Type> +Type* DescriptorPool::Tables::AllocateMessage(Type* /* dummy */) { + return arena_.Create<Type>(); +} + +FileDescriptorTables* DescriptorPool::Tables::AllocateFileTables() { + return arena_.Create<FileDescriptorTables>(); +} + +void* DescriptorPool::Tables::AllocateBytes(int size) { + if (size == 0) return nullptr; + return arena_.AllocateMemory(size); +} + +void FileDescriptorTables::BuildLocationsByPath( + std::pair<const FileDescriptorTables*, const SourceCodeInfo*>* p) { + for (int i = 0, len = p->second->location_size(); i < len; ++i) { + const SourceCodeInfo_Location* loc = &p->second->location().Get(i); + p->first->locations_by_path_[Join(loc->path(), ",")] = loc; + } +} + +const SourceCodeInfo_Location* FileDescriptorTables::GetSourceLocation( + const std::vector<int>& path, const SourceCodeInfo* info) const { + std::pair<const FileDescriptorTables*, const SourceCodeInfo*> p( + std::make_pair(this, info)); + internal::call_once(locations_by_path_once_, + FileDescriptorTables::BuildLocationsByPath, &p); + return FindPtrOrNull(locations_by_path_, Join(path, ",")); +} + +// =================================================================== +// DescriptorPool + +DescriptorPool::ErrorCollector::~ErrorCollector() {} + +DescriptorPool::DescriptorPool() + : mutex_(nullptr), + fallback_database_(nullptr), + default_error_collector_(nullptr), + underlay_(nullptr), + tables_(new Tables), + enforce_dependencies_(true), + lazily_build_dependencies_(false), + allow_unknown_(false), + enforce_weak_(false), + disallow_enforce_utf8_(false) {} + +DescriptorPool::DescriptorPool(DescriptorDatabase* fallback_database, + ErrorCollector* error_collector) + : mutex_(new internal::WrappedMutex), + fallback_database_(fallback_database), + default_error_collector_(error_collector), + underlay_(nullptr), + tables_(new Tables), + enforce_dependencies_(true), + lazily_build_dependencies_(false), + allow_unknown_(false), + enforce_weak_(false), + disallow_enforce_utf8_(false) {} + +DescriptorPool::DescriptorPool(const DescriptorPool* underlay) + : mutex_(nullptr), + fallback_database_(nullptr), + default_error_collector_(nullptr), + underlay_(underlay), + tables_(new Tables), + enforce_dependencies_(true), + lazily_build_dependencies_(false), + allow_unknown_(false), + enforce_weak_(false), + disallow_enforce_utf8_(false) {} + +DescriptorPool::~DescriptorPool() { + if (mutex_ != nullptr) delete mutex_; +} + +// DescriptorPool::BuildFile() defined later. +// DescriptorPool::BuildFileCollectingErrors() defined later. + +void DescriptorPool::InternalDontEnforceDependencies() { + enforce_dependencies_ = false; +} + +void DescriptorPool::AddUnusedImportTrackFile(ConstStringParam file_name, + bool is_error) { + unused_import_track_files_[TProtoStringType(file_name)] = is_error; +} + +void DescriptorPool::ClearUnusedImportTrackFiles() { + unused_import_track_files_.clear(); +} + +bool DescriptorPool::InternalIsFileLoaded(ConstStringParam filename) const { + MutexLockMaybe lock(mutex_); + return tables_->FindFile(filename) != nullptr; +} + +// generated_pool ==================================================== + +namespace { + + +EncodedDescriptorDatabase* GeneratedDatabase() { + static auto generated_database = + internal::OnShutdownDelete(new EncodedDescriptorDatabase()); + return generated_database; +} + +DescriptorPool* NewGeneratedPool() { + auto generated_pool = new DescriptorPool(GeneratedDatabase()); + generated_pool->InternalSetLazilyBuildDependencies(); + return generated_pool; +} + +} // anonymous namespace + +DescriptorDatabase* DescriptorPool::internal_generated_database() { + return GeneratedDatabase(); +} + +DescriptorPool* DescriptorPool::internal_generated_pool() { + static DescriptorPool* generated_pool = + internal::OnShutdownDelete(NewGeneratedPool()); + return generated_pool; +} + +const DescriptorPool* DescriptorPool::generated_pool() { + const DescriptorPool* pool = internal_generated_pool(); + // Ensure that descriptor.proto has been registered in the generated pool. + DescriptorProto::descriptor(); + return pool; +} + + +void DescriptorPool::InternalAddGeneratedFile( + const void* encoded_file_descriptor, int size) { + // So, this function is called in the process of initializing the + // descriptors for generated proto classes. Each generated .pb.cc file + // has an internal procedure called AddDescriptors() which is called at + // process startup, and that function calls this one in order to register + // the raw bytes of the FileDescriptorProto representing the file. + // + // We do not actually construct the descriptor objects right away. We just + // hang on to the bytes until they are actually needed. We actually construct + // the descriptor the first time one of the following things happens: + // * Someone calls a method like descriptor(), GetDescriptor(), or + // GetReflection() on the generated types, which requires returning the + // descriptor or an object based on it. + // * Someone looks up the descriptor in DescriptorPool::generated_pool(). + // + // Once one of these happens, the DescriptorPool actually parses the + // FileDescriptorProto and generates a FileDescriptor (and all its children) + // based on it. + // + // Note that FileDescriptorProto is itself a generated protocol message. + // Therefore, when we parse one, we have to be very careful to avoid using + // any descriptor-based operations, since this might cause infinite recursion + // or deadlock. + GOOGLE_CHECK(GeneratedDatabase()->Add(encoded_file_descriptor, size)); +} + + +// Find*By* methods ================================================== + +// TODO(kenton): There's a lot of repeated code here, but I'm not sure if +// there's any good way to factor it out. Think about this some time when +// there's nothing more important to do (read: never). + +const FileDescriptor* DescriptorPool::FindFileByName( + ConstStringParam name) const { + MutexLockMaybe lock(mutex_); + if (fallback_database_ != nullptr) { + tables_->known_bad_symbols_.clear(); + tables_->known_bad_files_.clear(); + } + const FileDescriptor* result = tables_->FindFile(name); + if (result != nullptr) return result; + if (underlay_ != nullptr) { + result = underlay_->FindFileByName(name); + if (result != nullptr) return result; + } + if (TryFindFileInFallbackDatabase(name)) { + result = tables_->FindFile(name); + if (result != nullptr) return result; + } + return nullptr; +} + +const FileDescriptor* DescriptorPool::FindFileContainingSymbol( + ConstStringParam symbol_name) const { + MutexLockMaybe lock(mutex_); + if (fallback_database_ != nullptr) { + tables_->known_bad_symbols_.clear(); + tables_->known_bad_files_.clear(); + } + Symbol result = tables_->FindSymbol(symbol_name); + if (!result.IsNull()) return result.GetFile(); + if (underlay_ != nullptr) { + const FileDescriptor* file_result = + underlay_->FindFileContainingSymbol(symbol_name); + if (file_result != nullptr) return file_result; + } + if (TryFindSymbolInFallbackDatabase(symbol_name)) { + result = tables_->FindSymbol(symbol_name); + if (!result.IsNull()) return result.GetFile(); + } + return nullptr; +} + +const Descriptor* DescriptorPool::FindMessageTypeByName( + ConstStringParam name) const { + return tables_->FindByNameHelper(this, name).descriptor(); +} + +const FieldDescriptor* DescriptorPool::FindFieldByName( + ConstStringParam name) const { + if (const FieldDescriptor* field = + tables_->FindByNameHelper(this, name).field_descriptor()) { + if (!field->is_extension()) { + return field; + } + } + return nullptr; +} + +const FieldDescriptor* DescriptorPool::FindExtensionByName( + ConstStringParam name) const { + if (const FieldDescriptor* field = + tables_->FindByNameHelper(this, name).field_descriptor()) { + if (field->is_extension()) { + return field; + } + } + return nullptr; +} + +const OneofDescriptor* DescriptorPool::FindOneofByName( + ConstStringParam name) const { + return tables_->FindByNameHelper(this, name).oneof_descriptor(); +} + +const EnumDescriptor* DescriptorPool::FindEnumTypeByName( + ConstStringParam name) const { + return tables_->FindByNameHelper(this, name).enum_descriptor(); +} + +const EnumValueDescriptor* DescriptorPool::FindEnumValueByName( + ConstStringParam name) const { + return tables_->FindByNameHelper(this, name).enum_value_descriptor(); +} + +const ServiceDescriptor* DescriptorPool::FindServiceByName( + ConstStringParam name) const { + return tables_->FindByNameHelper(this, name).service_descriptor(); +} + +const MethodDescriptor* DescriptorPool::FindMethodByName( + ConstStringParam name) const { + return tables_->FindByNameHelper(this, name).method_descriptor(); +} + +const FieldDescriptor* DescriptorPool::FindExtensionByNumber( + const Descriptor* extendee, int number) const { + if (extendee->extension_range_count() == 0) return nullptr; + // A faster path to reduce lock contention in finding extensions, assuming + // most extensions will be cache hit. + if (mutex_ != nullptr) { + ReaderMutexLock lock(mutex_); + const FieldDescriptor* result = tables_->FindExtension(extendee, number); + if (result != nullptr) { + return result; + } + } + MutexLockMaybe lock(mutex_); + if (fallback_database_ != nullptr) { + tables_->known_bad_symbols_.clear(); + tables_->known_bad_files_.clear(); + } + const FieldDescriptor* result = tables_->FindExtension(extendee, number); + if (result != nullptr) { + return result; + } + if (underlay_ != nullptr) { + result = underlay_->FindExtensionByNumber(extendee, number); + if (result != nullptr) return result; + } + if (TryFindExtensionInFallbackDatabase(extendee, number)) { + result = tables_->FindExtension(extendee, number); + if (result != nullptr) { + return result; + } + } + return nullptr; +} + +const FieldDescriptor* DescriptorPool::InternalFindExtensionByNumberNoLock( + const Descriptor* extendee, int number) const { + if (extendee->extension_range_count() == 0) return nullptr; + + const FieldDescriptor* result = tables_->FindExtension(extendee, number); + if (result != nullptr) { + return result; + } + + if (underlay_ != nullptr) { + result = underlay_->InternalFindExtensionByNumberNoLock(extendee, number); + if (result != nullptr) return result; + } + + return nullptr; +} + +const FieldDescriptor* DescriptorPool::FindExtensionByPrintableName( + const Descriptor* extendee, ConstStringParam printable_name) const { + if (extendee->extension_range_count() == 0) return nullptr; + const FieldDescriptor* result = FindExtensionByName(printable_name); + if (result != nullptr && result->containing_type() == extendee) { + return result; + } + if (extendee->options().message_set_wire_format()) { + // MessageSet extensions may be identified by type name. + const Descriptor* type = FindMessageTypeByName(printable_name); + if (type != nullptr) { + // Look for a matching extension in the foreign type's scope. + const int type_extension_count = type->extension_count(); + for (int i = 0; i < type_extension_count; i++) { + const FieldDescriptor* extension = type->extension(i); + if (extension->containing_type() == extendee && + extension->type() == FieldDescriptor::TYPE_MESSAGE && + extension->is_optional() && extension->message_type() == type) { + // Found it. + return extension; + } + } + } + } + return nullptr; +} + +void DescriptorPool::FindAllExtensions( + const Descriptor* extendee, + std::vector<const FieldDescriptor*>* out) const { + MutexLockMaybe lock(mutex_); + if (fallback_database_ != nullptr) { + tables_->known_bad_symbols_.clear(); + tables_->known_bad_files_.clear(); + } + + // Initialize tables_->extensions_ from the fallback database first + // (but do this only once per descriptor). + if (fallback_database_ != nullptr && + tables_->extensions_loaded_from_db_.count(extendee) == 0) { + std::vector<int> numbers; + if (fallback_database_->FindAllExtensionNumbers(extendee->full_name(), + &numbers)) { + for (int number : numbers) { + if (tables_->FindExtension(extendee, number) == nullptr) { + TryFindExtensionInFallbackDatabase(extendee, number); + } + } + tables_->extensions_loaded_from_db_.insert(extendee); + } + } + + tables_->FindAllExtensions(extendee, out); + if (underlay_ != nullptr) { + underlay_->FindAllExtensions(extendee, out); + } +} + + +// ------------------------------------------------------------------- + +const FieldDescriptor* Descriptor::FindFieldByNumber(int key) const { + const FieldDescriptor* result = file()->tables_->FindFieldByNumber(this, key); + if (result == nullptr || result->is_extension()) { + return nullptr; + } else { + return result; + } +} + +const FieldDescriptor* Descriptor::FindFieldByLowercaseName( + ConstStringParam key) const { + const FieldDescriptor* result = + file()->tables_->FindFieldByLowercaseName(this, key); + if (result == nullptr || result->is_extension()) { + return nullptr; + } else { + return result; + } +} + +const FieldDescriptor* Descriptor::FindFieldByCamelcaseName( + ConstStringParam key) const { + const FieldDescriptor* result = + file()->tables_->FindFieldByCamelcaseName(this, key); + if (result == nullptr || result->is_extension()) { + return nullptr; + } else { + return result; + } +} + +const FieldDescriptor* Descriptor::FindFieldByName(ConstStringParam key) const { + const FieldDescriptor* field = + file()->tables_->FindNestedSymbol(this, key).field_descriptor(); + return field != nullptr && !field->is_extension() ? field : nullptr; +} + +const OneofDescriptor* Descriptor::FindOneofByName(ConstStringParam key) const { + return file()->tables_->FindNestedSymbol(this, key).oneof_descriptor(); +} + +const FieldDescriptor* Descriptor::FindExtensionByName( + ConstStringParam key) const { + const FieldDescriptor* field = + file()->tables_->FindNestedSymbol(this, key).field_descriptor(); + return field != nullptr && field->is_extension() ? field : nullptr; +} + +const FieldDescriptor* Descriptor::FindExtensionByLowercaseName( + ConstStringParam key) const { + const FieldDescriptor* result = + file()->tables_->FindFieldByLowercaseName(this, key); + if (result == nullptr || !result->is_extension()) { + return nullptr; + } else { + return result; + } +} + +const FieldDescriptor* Descriptor::FindExtensionByCamelcaseName( + ConstStringParam key) const { + const FieldDescriptor* result = + file()->tables_->FindFieldByCamelcaseName(this, key); + if (result == nullptr || !result->is_extension()) { + return nullptr; + } else { + return result; + } +} + +const Descriptor* Descriptor::FindNestedTypeByName(ConstStringParam key) const { + return file()->tables_->FindNestedSymbol(this, key).descriptor(); +} + +const EnumDescriptor* Descriptor::FindEnumTypeByName( + ConstStringParam key) const { + return file()->tables_->FindNestedSymbol(this, key).enum_descriptor(); +} + +const EnumValueDescriptor* Descriptor::FindEnumValueByName( + ConstStringParam key) const { + return file()->tables_->FindNestedSymbol(this, key).enum_value_descriptor(); +} + +const FieldDescriptor* Descriptor::map_key() const { + if (!options().map_entry()) return nullptr; + GOOGLE_DCHECK_EQ(field_count(), 2); + return field(0); +} + +const FieldDescriptor* Descriptor::map_value() const { + if (!options().map_entry()) return nullptr; + GOOGLE_DCHECK_EQ(field_count(), 2); + return field(1); +} + +const EnumValueDescriptor* EnumDescriptor::FindValueByName( + ConstStringParam key) const { + return file()->tables_->FindNestedSymbol(this, key).enum_value_descriptor(); +} + +const EnumValueDescriptor* EnumDescriptor::FindValueByNumber(int key) const { + return file()->tables_->FindEnumValueByNumber(this, key); +} + +const EnumValueDescriptor* EnumDescriptor::FindValueByNumberCreatingIfUnknown( + int key) const { + return file()->tables_->FindEnumValueByNumberCreatingIfUnknown(this, key); +} + +const MethodDescriptor* ServiceDescriptor::FindMethodByName( + ConstStringParam key) const { + return file()->tables_->FindNestedSymbol(this, key).method_descriptor(); +} + +const Descriptor* FileDescriptor::FindMessageTypeByName( + ConstStringParam key) const { + return tables_->FindNestedSymbol(this, key).descriptor(); +} + +const EnumDescriptor* FileDescriptor::FindEnumTypeByName( + ConstStringParam key) const { + return tables_->FindNestedSymbol(this, key).enum_descriptor(); +} + +const EnumValueDescriptor* FileDescriptor::FindEnumValueByName( + ConstStringParam key) const { + return tables_->FindNestedSymbol(this, key).enum_value_descriptor(); +} + +const ServiceDescriptor* FileDescriptor::FindServiceByName( + ConstStringParam key) const { + return tables_->FindNestedSymbol(this, key).service_descriptor(); +} + +const FieldDescriptor* FileDescriptor::FindExtensionByName( + ConstStringParam key) const { + const FieldDescriptor* field = + tables_->FindNestedSymbol(this, key).field_descriptor(); + return field != nullptr && field->is_extension() ? field : nullptr; +} + +const FieldDescriptor* FileDescriptor::FindExtensionByLowercaseName( + ConstStringParam key) const { + const FieldDescriptor* result = tables_->FindFieldByLowercaseName(this, key); + if (result == nullptr || !result->is_extension()) { + return nullptr; + } else { + return result; + } +} + +const FieldDescriptor* FileDescriptor::FindExtensionByCamelcaseName( + ConstStringParam key) const { + const FieldDescriptor* result = tables_->FindFieldByCamelcaseName(this, key); + if (result == nullptr || !result->is_extension()) { + return nullptr; + } else { + return result; + } +} + +void Descriptor::ExtensionRange::CopyTo( + DescriptorProto_ExtensionRange* proto) const { + proto->set_start(this->start); + proto->set_end(this->end); + if (options_ != &ExtensionRangeOptions::default_instance()) { + *proto->mutable_options() = *options_; + } +} + +const Descriptor::ExtensionRange* +Descriptor::FindExtensionRangeContainingNumber(int number) const { + // Linear search should be fine because we don't expect a message to have + // more than a couple extension ranges. + for (int i = 0; i < extension_range_count(); i++) { + if (number >= extension_range(i)->start && + number < extension_range(i)->end) { + return extension_range(i); + } + } + return nullptr; +} + +const Descriptor::ReservedRange* Descriptor::FindReservedRangeContainingNumber( + int number) const { + // TODO(chrisn): Consider a non-linear search. + for (int i = 0; i < reserved_range_count(); i++) { + if (number >= reserved_range(i)->start && number < reserved_range(i)->end) { + return reserved_range(i); + } + } + return nullptr; +} + +const EnumDescriptor::ReservedRange* +EnumDescriptor::FindReservedRangeContainingNumber(int number) const { + // TODO(chrisn): Consider a non-linear search. + for (int i = 0; i < reserved_range_count(); i++) { + if (number >= reserved_range(i)->start && + number <= reserved_range(i)->end) { + return reserved_range(i); + } + } + return nullptr; +} + +// ------------------------------------------------------------------- + +bool DescriptorPool::TryFindFileInFallbackDatabase( + StringPiece name) const { + if (fallback_database_ == nullptr) return false; + + auto name_string = TProtoStringType(name); + if (tables_->known_bad_files_.count(name_string) > 0) return false; + + FileDescriptorProto file_proto; + if (!fallback_database_->FindFileByName(name_string, &file_proto) || + BuildFileFromDatabase(file_proto) == nullptr) { + tables_->known_bad_files_.insert(std::move(name_string)); + return false; + } + return true; +} + +bool DescriptorPool::IsSubSymbolOfBuiltType(StringPiece name) const { + auto prefix = TProtoStringType(name); + for (;;) { + TProtoStringType::size_type dot_pos = prefix.find_last_of('.'); + if (dot_pos == TProtoStringType::npos) { + break; + } + prefix = prefix.substr(0, dot_pos); + Symbol symbol = tables_->FindSymbol(prefix); + // If the symbol type is anything other than PACKAGE, then its complete + // definition is already known. + if (!symbol.IsNull() && symbol.type() != Symbol::PACKAGE) { + return true; + } + } + if (underlay_ != nullptr) { + // Check to see if any prefix of this symbol exists in the underlay. + return underlay_->IsSubSymbolOfBuiltType(name); + } + return false; +} + +bool DescriptorPool::TryFindSymbolInFallbackDatabase( + StringPiece name) const { + if (fallback_database_ == nullptr) return false; + + auto name_string = TProtoStringType(name); + if (tables_->known_bad_symbols_.count(name_string) > 0) return false; + + FileDescriptorProto file_proto; + if ( // We skip looking in the fallback database if the name is a sub-symbol + // of any descriptor that already exists in the descriptor pool (except + // for package descriptors). This is valid because all symbols except + // for packages are defined in a single file, so if the symbol exists + // then we should already have its definition. + // + // The other reason to do this is to support "overriding" type + // definitions by merging two databases that define the same type. (Yes, + // people do this.) The main difficulty with making this work is that + // FindFileContainingSymbol() is allowed to return both false positives + // (e.g., SimpleDescriptorDatabase, UpgradedDescriptorDatabase) and + // false negatives (e.g. ProtoFileParser, SourceTreeDescriptorDatabase). + // When two such databases are merged, looking up a non-existent + // sub-symbol of a type that already exists in the descriptor pool can + // result in an attempt to load multiple definitions of the same type. + // The check below avoids this. + IsSubSymbolOfBuiltType(name) + + // Look up file containing this symbol in fallback database. + || !fallback_database_->FindFileContainingSymbol(name_string, &file_proto) + + // Check if we've already built this file. If so, it apparently doesn't + // contain the symbol we're looking for. Some DescriptorDatabases + // return false positives. + || tables_->FindFile(file_proto.name()) != nullptr + + // Build the file. + || BuildFileFromDatabase(file_proto) == nullptr) { + tables_->known_bad_symbols_.insert(std::move(name_string)); + return false; + } + + return true; +} + +bool DescriptorPool::TryFindExtensionInFallbackDatabase( + const Descriptor* containing_type, int field_number) const { + if (fallback_database_ == nullptr) return false; + + FileDescriptorProto file_proto; + if (!fallback_database_->FindFileContainingExtension( + containing_type->full_name(), field_number, &file_proto)) { + return false; + } + + if (tables_->FindFile(file_proto.name()) != nullptr) { + // We've already loaded this file, and it apparently doesn't contain the + // extension we're looking for. Some DescriptorDatabases return false + // positives. + return false; + } + + if (BuildFileFromDatabase(file_proto) == nullptr) { + return false; + } + + return true; +} + +// =================================================================== + +bool FieldDescriptor::is_map_message_type() const { + return type_descriptor_.message_type->options().map_entry(); +} + +TProtoStringType FieldDescriptor::DefaultValueAsString( + bool quote_string_type) const { + GOOGLE_CHECK(has_default_value()) << "No default value"; + switch (cpp_type()) { + case CPPTYPE_INT32: + return StrCat(default_value_arc_i32()); + case CPPTYPE_INT64: + return StrCat(default_value_arc_i64()); + case CPPTYPE_UINT32: + return StrCat(default_value_arc_ui32()); + case CPPTYPE_UINT64: + return StrCat(default_value_arc_ui64()); + case CPPTYPE_FLOAT: + return SimpleFtoa(default_value_float()); + case CPPTYPE_DOUBLE: + return SimpleDtoa(default_value_double()); + case CPPTYPE_BOOL: + return default_value_bool() ? "true" : "false"; + case CPPTYPE_STRING: + if (quote_string_type) { + return "\"" + CEscape(default_value_string()) + "\""; + } else { + if (type() == TYPE_BYTES) { + return CEscape(default_value_string()); + } else { + return default_value_string(); + } + } + case CPPTYPE_ENUM: + return default_value_enum()->name(); + case CPPTYPE_MESSAGE: + GOOGLE_LOG(DFATAL) << "Messages can't have default values!"; + break; + } + GOOGLE_LOG(FATAL) << "Can't get here: failed to get default value as string"; + return ""; +} + +// CopyTo methods ==================================================== + +void FileDescriptor::CopyTo(FileDescriptorProto* proto) const { + proto->set_name(name()); + if (!package().empty()) proto->set_package(package()); + // TODO(liujisi): Also populate when syntax="proto2". + if (syntax() == SYNTAX_PROTO3) proto->set_syntax(SyntaxName(syntax())); + + for (int i = 0; i < dependency_count(); i++) { + proto->add_dependency(dependency(i)->name()); + } + + for (int i = 0; i < public_dependency_count(); i++) { + proto->add_public_dependency(public_dependencies_[i]); + } + + for (int i = 0; i < weak_dependency_count(); i++) { + proto->add_weak_dependency(weak_dependencies_[i]); + } + + for (int i = 0; i < message_type_count(); i++) { + message_type(i)->CopyTo(proto->add_message_type()); + } + for (int i = 0; i < enum_type_count(); i++) { + enum_type(i)->CopyTo(proto->add_enum_type()); + } + for (int i = 0; i < service_count(); i++) { + service(i)->CopyTo(proto->add_service()); + } + for (int i = 0; i < extension_count(); i++) { + extension(i)->CopyTo(proto->add_extension()); + } + + if (&options() != &FileOptions::default_instance()) { + proto->mutable_options()->CopyFrom(options()); + } +} + +void FileDescriptor::CopyJsonNameTo(FileDescriptorProto* proto) const { + if (message_type_count() != proto->message_type_size() || + extension_count() != proto->extension_size()) { + GOOGLE_LOG(ERROR) << "Cannot copy json_name to a proto of a different size."; + return; + } + for (int i = 0; i < message_type_count(); i++) { + message_type(i)->CopyJsonNameTo(proto->mutable_message_type(i)); + } + for (int i = 0; i < extension_count(); i++) { + extension(i)->CopyJsonNameTo(proto->mutable_extension(i)); + } +} + +void FileDescriptor::CopySourceCodeInfoTo(FileDescriptorProto* proto) const { + if (source_code_info_ && + source_code_info_ != &SourceCodeInfo::default_instance()) { + proto->mutable_source_code_info()->CopyFrom(*source_code_info_); + } +} + +void Descriptor::CopyTo(DescriptorProto* proto) const { + proto->set_name(name()); + + for (int i = 0; i < field_count(); i++) { + field(i)->CopyTo(proto->add_field()); + } + for (int i = 0; i < oneof_decl_count(); i++) { + oneof_decl(i)->CopyTo(proto->add_oneof_decl()); + } + for (int i = 0; i < nested_type_count(); i++) { + nested_type(i)->CopyTo(proto->add_nested_type()); + } + for (int i = 0; i < enum_type_count(); i++) { + enum_type(i)->CopyTo(proto->add_enum_type()); + } + for (int i = 0; i < extension_range_count(); i++) { + extension_range(i)->CopyTo(proto->add_extension_range()); + } + for (int i = 0; i < extension_count(); i++) { + extension(i)->CopyTo(proto->add_extension()); + } + for (int i = 0; i < reserved_range_count(); i++) { + DescriptorProto::ReservedRange* range = proto->add_reserved_range(); + range->set_start(reserved_range(i)->start); + range->set_end(reserved_range(i)->end); + } + for (int i = 0; i < reserved_name_count(); i++) { + proto->add_reserved_name(reserved_name(i)); + } + + if (&options() != &MessageOptions::default_instance()) { + proto->mutable_options()->CopyFrom(options()); + } +} + +void Descriptor::CopyJsonNameTo(DescriptorProto* proto) const { + if (field_count() != proto->field_size() || + nested_type_count() != proto->nested_type_size() || + extension_count() != proto->extension_size()) { + GOOGLE_LOG(ERROR) << "Cannot copy json_name to a proto of a different size."; + return; + } + for (int i = 0; i < field_count(); i++) { + field(i)->CopyJsonNameTo(proto->mutable_field(i)); + } + for (int i = 0; i < nested_type_count(); i++) { + nested_type(i)->CopyJsonNameTo(proto->mutable_nested_type(i)); + } + for (int i = 0; i < extension_count(); i++) { + extension(i)->CopyJsonNameTo(proto->mutable_extension(i)); + } +} + +void FieldDescriptor::CopyTo(FieldDescriptorProto* proto) const { + proto->set_name(name()); + proto->set_number(number()); + if (has_json_name_) { + proto->set_json_name(json_name()); + } + if (proto3_optional_) { + proto->set_proto3_optional(true); + } + // Some compilers do not allow static_cast directly between two enum types, + // so we must cast to int first. + proto->set_label(static_cast<FieldDescriptorProto::Label>( + implicit_cast<int>(label()))); + proto->set_type(static_cast<FieldDescriptorProto::Type>( + implicit_cast<int>(type()))); + + if (is_extension()) { + if (!containing_type()->is_unqualified_placeholder_) { + proto->set_extendee("."); + } + proto->mutable_extendee()->append(containing_type()->full_name()); + } + + if (cpp_type() == CPPTYPE_MESSAGE) { + if (message_type()->is_placeholder_) { + // We don't actually know if the type is a message type. It could be + // an enum. + proto->clear_type(); + } + + if (!message_type()->is_unqualified_placeholder_) { + proto->set_type_name("."); + } + proto->mutable_type_name()->append(message_type()->full_name()); + } else if (cpp_type() == CPPTYPE_ENUM) { + if (!enum_type()->is_unqualified_placeholder_) { + proto->set_type_name("."); + } + proto->mutable_type_name()->append(enum_type()->full_name()); + } + + if (has_default_value()) { + proto->set_default_value(DefaultValueAsString(false)); + } + + if (containing_oneof() != nullptr && !is_extension()) { + proto->set_oneof_index(containing_oneof()->index()); + } + + if (&options() != &FieldOptions::default_instance()) { + proto->mutable_options()->CopyFrom(options()); + } +} + +void FieldDescriptor::CopyJsonNameTo(FieldDescriptorProto* proto) const { + proto->set_json_name(json_name()); +} + +void OneofDescriptor::CopyTo(OneofDescriptorProto* proto) const { + proto->set_name(name()); + if (&options() != &OneofOptions::default_instance()) { + proto->mutable_options()->CopyFrom(options()); + } +} + +void EnumDescriptor::CopyTo(EnumDescriptorProto* proto) const { + proto->set_name(name()); + + for (int i = 0; i < value_count(); i++) { + value(i)->CopyTo(proto->add_value()); + } + for (int i = 0; i < reserved_range_count(); i++) { + EnumDescriptorProto::EnumReservedRange* range = proto->add_reserved_range(); + range->set_start(reserved_range(i)->start); + range->set_end(reserved_range(i)->end); + } + for (int i = 0; i < reserved_name_count(); i++) { + proto->add_reserved_name(reserved_name(i)); + } + + if (&options() != &EnumOptions::default_instance()) { + proto->mutable_options()->CopyFrom(options()); + } +} + +void EnumValueDescriptor::CopyTo(EnumValueDescriptorProto* proto) const { + proto->set_name(name()); + proto->set_number(number()); + + if (&options() != &EnumValueOptions::default_instance()) { + proto->mutable_options()->CopyFrom(options()); + } +} + +void ServiceDescriptor::CopyTo(ServiceDescriptorProto* proto) const { + proto->set_name(name()); + + for (int i = 0; i < method_count(); i++) { + method(i)->CopyTo(proto->add_method()); + } + + if (&options() != &ServiceOptions::default_instance()) { + proto->mutable_options()->CopyFrom(options()); + } +} + +void MethodDescriptor::CopyTo(MethodDescriptorProto* proto) const { + proto->set_name(name()); + + if (!input_type()->is_unqualified_placeholder_) { + proto->set_input_type("."); + } + proto->mutable_input_type()->append(input_type()->full_name()); + + if (!output_type()->is_unqualified_placeholder_) { + proto->set_output_type("."); + } + proto->mutable_output_type()->append(output_type()->full_name()); + + if (&options() != &MethodOptions::default_instance()) { + proto->mutable_options()->CopyFrom(options()); + } + + if (client_streaming_) { + proto->set_client_streaming(true); + } + if (server_streaming_) { + proto->set_server_streaming(true); + } +} + +// DebugString methods =============================================== + +namespace { + +bool RetrieveOptionsAssumingRightPool( + int depth, const Message& options, + std::vector<TProtoStringType>* option_entries) { + option_entries->clear(); + const Reflection* reflection = options.GetReflection(); + std::vector<const FieldDescriptor*> fields; + reflection->ListFields(options, &fields); + for (const FieldDescriptor* field : fields) { + int count = 1; + bool repeated = false; + if (field->is_repeated()) { + count = reflection->FieldSize(options, field); + repeated = true; + } + for (int j = 0; j < count; j++) { + TProtoStringType fieldval; + if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) { + TProtoStringType tmp; + TextFormat::Printer printer; + printer.SetExpandAny(true); + printer.SetInitialIndentLevel(depth + 1); + printer.PrintFieldValueToString(options, field, repeated ? j : -1, + &tmp); + fieldval.append("{\n"); + fieldval.append(tmp); + fieldval.append(depth * 2, ' '); + fieldval.append("}"); + } else { + TextFormat::PrintFieldValueToString(options, field, repeated ? j : -1, + &fieldval); + } + TProtoStringType name; + if (field->is_extension()) { + name = "(." + field->full_name() + ")"; + } else { + name = field->name(); + } + option_entries->push_back(name + " = " + fieldval); + } + } + return !option_entries->empty(); +} + +// Used by each of the option formatters. +bool RetrieveOptions(int depth, const Message& options, + const DescriptorPool* pool, + std::vector<TProtoStringType>* option_entries) { + // When printing custom options for a descriptor, we must use an options + // message built on top of the same DescriptorPool where the descriptor + // is coming from. This is to ensure we are interpreting custom options + // against the right pool. + if (options.GetDescriptor()->file()->pool() == pool) { + return RetrieveOptionsAssumingRightPool(depth, options, option_entries); + } else { + const Descriptor* option_descriptor = + pool->FindMessageTypeByName(options.GetDescriptor()->full_name()); + if (option_descriptor == nullptr) { + // descriptor.proto is not in the pool. This means no custom options are + // used so we are safe to proceed with the compiled options message type. + return RetrieveOptionsAssumingRightPool(depth, options, option_entries); + } + DynamicMessageFactory factory; + std::unique_ptr<Message> dynamic_options( + factory.GetPrototype(option_descriptor)->New()); + TProtoStringType serialized = options.SerializeAsString(); + io::CodedInputStream input( + reinterpret_cast<const uint8_t*>(serialized.c_str()), + serialized.size()); + input.SetExtensionRegistry(pool, &factory); + if (dynamic_options->ParseFromCodedStream(&input)) { + return RetrieveOptionsAssumingRightPool(depth, *dynamic_options, + option_entries); + } else { + GOOGLE_LOG(ERROR) << "Found invalid proto option data for: " + << options.GetDescriptor()->full_name(); + return RetrieveOptionsAssumingRightPool(depth, options, option_entries); + } + } +} + +// Formats options that all appear together in brackets. Does not include +// brackets. +bool FormatBracketedOptions(int depth, const Message& options, + const DescriptorPool* pool, TProtoStringType* output) { + std::vector<TProtoStringType> all_options; + if (RetrieveOptions(depth, options, pool, &all_options)) { + output->append(Join(all_options, ", ")); + } + return !all_options.empty(); +} + +// Formats options one per line +bool FormatLineOptions(int depth, const Message& options, + const DescriptorPool* pool, TProtoStringType* output) { + TProtoStringType prefix(depth * 2, ' '); + std::vector<TProtoStringType> all_options; + if (RetrieveOptions(depth, options, pool, &all_options)) { + for (const TProtoStringType& option : all_options) { + strings::SubstituteAndAppend(output, "$0option $1;\n", prefix, option); + } + } + return !all_options.empty(); +} + +class SourceLocationCommentPrinter { + public: + template <typename DescType> + SourceLocationCommentPrinter(const DescType* desc, const TProtoStringType& prefix, + const DebugStringOptions& options) + : options_(options), prefix_(prefix) { + // Perform the SourceLocation lookup only if we're including user comments, + // because the lookup is fairly expensive. + have_source_loc_ = + options.include_comments && desc->GetSourceLocation(&source_loc_); + } + SourceLocationCommentPrinter(const FileDescriptor* file, + const std::vector<int>& path, + const TProtoStringType& prefix, + const DebugStringOptions& options) + : options_(options), prefix_(prefix) { + // Perform the SourceLocation lookup only if we're including user comments, + // because the lookup is fairly expensive. + have_source_loc_ = + options.include_comments && file->GetSourceLocation(path, &source_loc_); + } + void AddPreComment(TProtoStringType* output) { + if (have_source_loc_) { + // Detached leading comments. + for (const TProtoStringType& leading_detached_comment : + source_loc_.leading_detached_comments) { + *output += FormatComment(leading_detached_comment); + *output += "\n"; + } + // Attached leading comments. + if (!source_loc_.leading_comments.empty()) { + *output += FormatComment(source_loc_.leading_comments); + } + } + } + void AddPostComment(TProtoStringType* output) { + if (have_source_loc_ && source_loc_.trailing_comments.size() > 0) { + *output += FormatComment(source_loc_.trailing_comments); + } + } + + // Format comment such that each line becomes a full-line C++-style comment in + // the DebugString() output. + TProtoStringType FormatComment(const TProtoStringType& comment_text) { + TProtoStringType stripped_comment = comment_text; + StripWhitespace(&stripped_comment); + std::vector<TProtoStringType> lines = Split(stripped_comment, "\n"); + TProtoStringType output; + for (const TProtoStringType& line : lines) { + strings::SubstituteAndAppend(&output, "$0// $1\n", prefix_, line); + } + return output; + } + + private: + + bool have_source_loc_; + SourceLocation source_loc_; + DebugStringOptions options_; + TProtoStringType prefix_; +}; + +} // anonymous namespace + +TProtoStringType FileDescriptor::DebugString() const { + DebugStringOptions options; // default options + return DebugStringWithOptions(options); +} + +TProtoStringType FileDescriptor::DebugStringWithOptions( + const DebugStringOptions& debug_string_options) const { + TProtoStringType contents; + { + std::vector<int> path; + path.push_back(FileDescriptorProto::kSyntaxFieldNumber); + SourceLocationCommentPrinter syntax_comment(this, path, "", + debug_string_options); + syntax_comment.AddPreComment(&contents); + strings::SubstituteAndAppend(&contents, "syntax = \"$0\";\n\n", + SyntaxName(syntax())); + syntax_comment.AddPostComment(&contents); + } + + SourceLocationCommentPrinter comment_printer(this, "", debug_string_options); + comment_printer.AddPreComment(&contents); + + std::set<int> public_dependencies; + std::set<int> weak_dependencies; + public_dependencies.insert(public_dependencies_, + public_dependencies_ + public_dependency_count_); + weak_dependencies.insert(weak_dependencies_, + weak_dependencies_ + weak_dependency_count_); + + for (int i = 0; i < dependency_count(); i++) { + if (public_dependencies.count(i) > 0) { + strings::SubstituteAndAppend(&contents, "import public \"$0\";\n", + dependency(i)->name()); + } else if (weak_dependencies.count(i) > 0) { + strings::SubstituteAndAppend(&contents, "import weak \"$0\";\n", + dependency(i)->name()); + } else { + strings::SubstituteAndAppend(&contents, "import \"$0\";\n", + dependency(i)->name()); + } + } + + if (!package().empty()) { + std::vector<int> path; + path.push_back(FileDescriptorProto::kPackageFieldNumber); + SourceLocationCommentPrinter package_comment(this, path, "", + debug_string_options); + package_comment.AddPreComment(&contents); + strings::SubstituteAndAppend(&contents, "package $0;\n\n", package()); + package_comment.AddPostComment(&contents); + } + + if (FormatLineOptions(0, options(), pool(), &contents)) { + contents.append("\n"); // add some space if we had options + } + + for (int i = 0; i < enum_type_count(); i++) { + enum_type(i)->DebugString(0, &contents, debug_string_options); + contents.append("\n"); + } + + // Find all the 'group' type extensions; we will not output their nested + // definitions (those will be done with their group field descriptor). + std::set<const Descriptor*> groups; + for (int i = 0; i < extension_count(); i++) { + if (extension(i)->type() == FieldDescriptor::TYPE_GROUP) { + groups.insert(extension(i)->message_type()); + } + } + + for (int i = 0; i < message_type_count(); i++) { + if (groups.count(message_type(i)) == 0) { + message_type(i)->DebugString(0, &contents, debug_string_options, + /* include_opening_clause */ true); + contents.append("\n"); + } + } + + for (int i = 0; i < service_count(); i++) { + service(i)->DebugString(&contents, debug_string_options); + contents.append("\n"); + } + + const Descriptor* containing_type = nullptr; + for (int i = 0; i < extension_count(); i++) { + if (extension(i)->containing_type() != containing_type) { + if (i > 0) contents.append("}\n\n"); + containing_type = extension(i)->containing_type(); + strings::SubstituteAndAppend(&contents, "extend .$0 {\n", + containing_type->full_name()); + } + extension(i)->DebugString(1, &contents, debug_string_options); + } + if (extension_count() > 0) contents.append("}\n\n"); + + comment_printer.AddPostComment(&contents); + + return contents; +} + +TProtoStringType Descriptor::DebugString() const { + DebugStringOptions options; // default options + return DebugStringWithOptions(options); +} + +TProtoStringType Descriptor::DebugStringWithOptions( + const DebugStringOptions& options) const { + TProtoStringType contents; + DebugString(0, &contents, options, /* include_opening_clause */ true); + return contents; +} + +void Descriptor::DebugString(int depth, TProtoStringType* contents, + const DebugStringOptions& debug_string_options, + bool include_opening_clause) const { + if (options().map_entry()) { + // Do not generate debug string for auto-generated map-entry type. + return; + } + TProtoStringType prefix(depth * 2, ' '); + ++depth; + + SourceLocationCommentPrinter comment_printer(this, prefix, + debug_string_options); + comment_printer.AddPreComment(contents); + + if (include_opening_clause) { + strings::SubstituteAndAppend(contents, "$0message $1", prefix, name()); + } + contents->append(" {\n"); + + FormatLineOptions(depth, options(), file()->pool(), contents); + + // Find all the 'group' types for fields and extensions; we will not output + // their nested definitions (those will be done with their group field + // descriptor). + std::set<const Descriptor*> groups; + for (int i = 0; i < field_count(); i++) { + if (field(i)->type() == FieldDescriptor::TYPE_GROUP) { + groups.insert(field(i)->message_type()); + } + } + for (int i = 0; i < extension_count(); i++) { + if (extension(i)->type() == FieldDescriptor::TYPE_GROUP) { + groups.insert(extension(i)->message_type()); + } + } + + for (int i = 0; i < nested_type_count(); i++) { + if (groups.count(nested_type(i)) == 0) { + nested_type(i)->DebugString(depth, contents, debug_string_options, + /* include_opening_clause */ true); + } + } + for (int i = 0; i < enum_type_count(); i++) { + enum_type(i)->DebugString(depth, contents, debug_string_options); + } + for (int i = 0; i < field_count(); i++) { + if (field(i)->real_containing_oneof() == nullptr) { + field(i)->DebugString(depth, contents, debug_string_options); + } else if (field(i)->containing_oneof()->field(0) == field(i)) { + // This is the first field in this oneof, so print the whole oneof. + field(i)->containing_oneof()->DebugString(depth, contents, + debug_string_options); + } + } + + for (int i = 0; i < extension_range_count(); i++) { + strings::SubstituteAndAppend(contents, "$0 extensions $1 to $2;\n", prefix, + extension_range(i)->start, + extension_range(i)->end - 1); + } + + // Group extensions by what they extend, so they can be printed out together. + const Descriptor* containing_type = nullptr; + for (int i = 0; i < extension_count(); i++) { + if (extension(i)->containing_type() != containing_type) { + if (i > 0) strings::SubstituteAndAppend(contents, "$0 }\n", prefix); + containing_type = extension(i)->containing_type(); + strings::SubstituteAndAppend(contents, "$0 extend .$1 {\n", prefix, + containing_type->full_name()); + } + extension(i)->DebugString(depth + 1, contents, debug_string_options); + } + if (extension_count() > 0) + strings::SubstituteAndAppend(contents, "$0 }\n", prefix); + + if (reserved_range_count() > 0) { + strings::SubstituteAndAppend(contents, "$0 reserved ", prefix); + for (int i = 0; i < reserved_range_count(); i++) { + const Descriptor::ReservedRange* range = reserved_range(i); + if (range->end == range->start + 1) { + strings::SubstituteAndAppend(contents, "$0, ", range->start); + } else if (range->end > FieldDescriptor::kMaxNumber) { + strings::SubstituteAndAppend(contents, "$0 to max, ", range->start); + } else { + strings::SubstituteAndAppend(contents, "$0 to $1, ", range->start, + range->end - 1); + } + } + contents->replace(contents->size() - 2, 2, ";\n"); + } + + if (reserved_name_count() > 0) { + strings::SubstituteAndAppend(contents, "$0 reserved ", prefix); + for (int i = 0; i < reserved_name_count(); i++) { + strings::SubstituteAndAppend(contents, "\"$0\", ", + CEscape(reserved_name(i))); + } + contents->replace(contents->size() - 2, 2, ";\n"); + } + + strings::SubstituteAndAppend(contents, "$0}\n", prefix); + comment_printer.AddPostComment(contents); +} + +TProtoStringType FieldDescriptor::DebugString() const { + DebugStringOptions options; // default options + return DebugStringWithOptions(options); +} + +TProtoStringType FieldDescriptor::DebugStringWithOptions( + const DebugStringOptions& debug_string_options) const { + TProtoStringType contents; + int depth = 0; + if (is_extension()) { + strings::SubstituteAndAppend(&contents, "extend .$0 {\n", + containing_type()->full_name()); + depth = 1; + } + DebugString(depth, &contents, debug_string_options); + if (is_extension()) { + contents.append("}\n"); + } + return contents; +} + +// The field type string used in FieldDescriptor::DebugString() +TProtoStringType FieldDescriptor::FieldTypeNameDebugString() const { + switch (type()) { + case TYPE_MESSAGE: + return "." + message_type()->full_name(); + case TYPE_ENUM: + return "." + enum_type()->full_name(); + default: + return kTypeToName[type()]; + } +} + +void FieldDescriptor::DebugString( + int depth, TProtoStringType* contents, + const DebugStringOptions& debug_string_options) const { + TProtoStringType prefix(depth * 2, ' '); + TProtoStringType field_type; + + // Special case map fields. + if (is_map()) { + strings::SubstituteAndAppend( + &field_type, "map<$0, $1>", + message_type()->field(0)->FieldTypeNameDebugString(), + message_type()->field(1)->FieldTypeNameDebugString()); + } else { + field_type = FieldTypeNameDebugString(); + } + + TProtoStringType label = StrCat(kLabelToName[this->label()], " "); + + // Label is omitted for maps, oneof, and plain proto3 fields. + if (is_map() || real_containing_oneof() || + (is_optional() && !has_optional_keyword())) { + label.clear(); + } + + SourceLocationCommentPrinter comment_printer(this, prefix, + debug_string_options); + comment_printer.AddPreComment(contents); + + strings::SubstituteAndAppend( + contents, "$0$1$2 $3 = $4", prefix, label, field_type, + type() == TYPE_GROUP ? message_type()->name() : name(), number()); + + bool bracketed = false; + if (has_default_value()) { + bracketed = true; + strings::SubstituteAndAppend(contents, " [default = $0", + DefaultValueAsString(true)); + } + if (has_json_name_) { + if (!bracketed) { + bracketed = true; + contents->append(" ["); + } else { + contents->append(", "); + } + contents->append("json_name = \""); + contents->append(CEscape(json_name())); + contents->append("\""); + } + + TProtoStringType formatted_options; + if (FormatBracketedOptions(depth, options(), file()->pool(), + &formatted_options)) { + contents->append(bracketed ? ", " : " ["); + bracketed = true; + contents->append(formatted_options); + } + + if (bracketed) { + contents->append("]"); + } + + if (type() == TYPE_GROUP) { + if (debug_string_options.elide_group_body) { + contents->append(" { ... };\n"); + } else { + message_type()->DebugString(depth, contents, debug_string_options, + /* include_opening_clause */ false); + } + } else { + contents->append(";\n"); + } + + comment_printer.AddPostComment(contents); +} + +TProtoStringType OneofDescriptor::DebugString() const { + DebugStringOptions options; // default values + return DebugStringWithOptions(options); +} + +TProtoStringType OneofDescriptor::DebugStringWithOptions( + const DebugStringOptions& options) const { + TProtoStringType contents; + DebugString(0, &contents, options); + return contents; +} + +void OneofDescriptor::DebugString( + int depth, TProtoStringType* contents, + const DebugStringOptions& debug_string_options) const { + TProtoStringType prefix(depth * 2, ' '); + ++depth; + SourceLocationCommentPrinter comment_printer(this, prefix, + debug_string_options); + comment_printer.AddPreComment(contents); + strings::SubstituteAndAppend(contents, "$0oneof $1 {", prefix, name()); + + FormatLineOptions(depth, options(), containing_type()->file()->pool(), + contents); + + if (debug_string_options.elide_oneof_body) { + contents->append(" ... }\n"); + } else { + contents->append("\n"); + for (int i = 0; i < field_count(); i++) { + field(i)->DebugString(depth, contents, debug_string_options); + } + strings::SubstituteAndAppend(contents, "$0}\n", prefix); + } + comment_printer.AddPostComment(contents); +} + +TProtoStringType EnumDescriptor::DebugString() const { + DebugStringOptions options; // default values + return DebugStringWithOptions(options); +} + +TProtoStringType EnumDescriptor::DebugStringWithOptions( + const DebugStringOptions& options) const { + TProtoStringType contents; + DebugString(0, &contents, options); + return contents; +} + +void EnumDescriptor::DebugString( + int depth, TProtoStringType* contents, + const DebugStringOptions& debug_string_options) const { + TProtoStringType prefix(depth * 2, ' '); + ++depth; + + SourceLocationCommentPrinter comment_printer(this, prefix, + debug_string_options); + comment_printer.AddPreComment(contents); + + strings::SubstituteAndAppend(contents, "$0enum $1 {\n", prefix, name()); + + FormatLineOptions(depth, options(), file()->pool(), contents); + + for (int i = 0; i < value_count(); i++) { + value(i)->DebugString(depth, contents, debug_string_options); + } + + if (reserved_range_count() > 0) { + strings::SubstituteAndAppend(contents, "$0 reserved ", prefix); + for (int i = 0; i < reserved_range_count(); i++) { + const EnumDescriptor::ReservedRange* range = reserved_range(i); + if (range->end == range->start) { + strings::SubstituteAndAppend(contents, "$0, ", range->start); + } else if (range->end == INT_MAX) { + strings::SubstituteAndAppend(contents, "$0 to max, ", range->start); + } else { + strings::SubstituteAndAppend(contents, "$0 to $1, ", range->start, + range->end); + } + } + contents->replace(contents->size() - 2, 2, ";\n"); + } + + if (reserved_name_count() > 0) { + strings::SubstituteAndAppend(contents, "$0 reserved ", prefix); + for (int i = 0; i < reserved_name_count(); i++) { + strings::SubstituteAndAppend(contents, "\"$0\", ", + CEscape(reserved_name(i))); + } + contents->replace(contents->size() - 2, 2, ";\n"); + } + + strings::SubstituteAndAppend(contents, "$0}\n", prefix); + + comment_printer.AddPostComment(contents); +} + +TProtoStringType EnumValueDescriptor::DebugString() const { + DebugStringOptions options; // default values + return DebugStringWithOptions(options); +} + +TProtoStringType EnumValueDescriptor::DebugStringWithOptions( + const DebugStringOptions& options) const { + TProtoStringType contents; + DebugString(0, &contents, options); + return contents; +} + +void EnumValueDescriptor::DebugString( + int depth, TProtoStringType* contents, + const DebugStringOptions& debug_string_options) const { + TProtoStringType prefix(depth * 2, ' '); + + SourceLocationCommentPrinter comment_printer(this, prefix, + debug_string_options); + comment_printer.AddPreComment(contents); + + strings::SubstituteAndAppend(contents, "$0$1 = $2", prefix, name(), number()); + + TProtoStringType formatted_options; + if (FormatBracketedOptions(depth, options(), type()->file()->pool(), + &formatted_options)) { + strings::SubstituteAndAppend(contents, " [$0]", formatted_options); + } + contents->append(";\n"); + + comment_printer.AddPostComment(contents); +} + +TProtoStringType ServiceDescriptor::DebugString() const { + DebugStringOptions options; // default values + return DebugStringWithOptions(options); +} + +TProtoStringType ServiceDescriptor::DebugStringWithOptions( + const DebugStringOptions& options) const { + TProtoStringType contents; + DebugString(&contents, options); + return contents; +} + +void ServiceDescriptor::DebugString( + TProtoStringType* contents, + const DebugStringOptions& debug_string_options) const { + SourceLocationCommentPrinter comment_printer(this, /* prefix */ "", + debug_string_options); + comment_printer.AddPreComment(contents); + + strings::SubstituteAndAppend(contents, "service $0 {\n", name()); + + FormatLineOptions(1, options(), file()->pool(), contents); + + for (int i = 0; i < method_count(); i++) { + method(i)->DebugString(1, contents, debug_string_options); + } + + contents->append("}\n"); + + comment_printer.AddPostComment(contents); +} + +TProtoStringType MethodDescriptor::DebugString() const { + DebugStringOptions options; // default values + return DebugStringWithOptions(options); +} + +TProtoStringType MethodDescriptor::DebugStringWithOptions( + const DebugStringOptions& options) const { + TProtoStringType contents; + DebugString(0, &contents, options); + return contents; +} + +void MethodDescriptor::DebugString( + int depth, TProtoStringType* contents, + const DebugStringOptions& debug_string_options) const { + TProtoStringType prefix(depth * 2, ' '); + ++depth; + + SourceLocationCommentPrinter comment_printer(this, prefix, + debug_string_options); + comment_printer.AddPreComment(contents); + + strings::SubstituteAndAppend( + contents, "$0rpc $1($4.$2) returns ($5.$3)", prefix, name(), + input_type()->full_name(), output_type()->full_name(), + client_streaming() ? "stream " : "", server_streaming() ? "stream " : ""); + + TProtoStringType formatted_options; + if (FormatLineOptions(depth, options(), service()->file()->pool(), + &formatted_options)) { + strings::SubstituteAndAppend(contents, " {\n$0$1}\n", formatted_options, + prefix); + } else { + contents->append(";\n"); + } + + comment_printer.AddPostComment(contents); +} + + +// Location methods =============================================== + +bool FileDescriptor::GetSourceLocation(const std::vector<int>& path, + SourceLocation* out_location) const { + GOOGLE_CHECK(out_location != nullptr); + if (source_code_info_) { + if (const SourceCodeInfo_Location* loc = + tables_->GetSourceLocation(path, source_code_info_)) { + const RepeatedField<arc_i32>& span = loc->span(); + if (span.size() == 3 || span.size() == 4) { + out_location->start_line = span.Get(0); + out_location->start_column = span.Get(1); + out_location->end_line = span.Get(span.size() == 3 ? 0 : 2); + out_location->end_column = span.Get(span.size() - 1); + + out_location->leading_comments = loc->leading_comments(); + out_location->trailing_comments = loc->trailing_comments(); + out_location->leading_detached_comments.assign( + loc->leading_detached_comments().begin(), + loc->leading_detached_comments().end()); + return true; + } + } + } + return false; +} + +bool FileDescriptor::GetSourceLocation(SourceLocation* out_location) const { + std::vector<int> path; // empty path for root FileDescriptor + return GetSourceLocation(path, out_location); +} + +bool FieldDescriptor::is_packed() const { + if (!is_packable()) return false; + if (file_->syntax() == FileDescriptor::SYNTAX_PROTO2) { + return (options_ != nullptr) && options_->packed(); + } else { + return options_ == nullptr || !options_->has_packed() || options_->packed(); + } +} + +bool Descriptor::GetSourceLocation(SourceLocation* out_location) const { + std::vector<int> path; + GetLocationPath(&path); + return file()->GetSourceLocation(path, out_location); +} + +bool FieldDescriptor::GetSourceLocation(SourceLocation* out_location) const { + std::vector<int> path; + GetLocationPath(&path); + return file()->GetSourceLocation(path, out_location); +} + +bool OneofDescriptor::GetSourceLocation(SourceLocation* out_location) const { + std::vector<int> path; + GetLocationPath(&path); + return containing_type()->file()->GetSourceLocation(path, out_location); +} + +bool EnumDescriptor::GetSourceLocation(SourceLocation* out_location) const { + std::vector<int> path; + GetLocationPath(&path); + return file()->GetSourceLocation(path, out_location); +} + +bool MethodDescriptor::GetSourceLocation(SourceLocation* out_location) const { + std::vector<int> path; + GetLocationPath(&path); + return service()->file()->GetSourceLocation(path, out_location); +} + +bool ServiceDescriptor::GetSourceLocation(SourceLocation* out_location) const { + std::vector<int> path; + GetLocationPath(&path); + return file()->GetSourceLocation(path, out_location); +} + +bool EnumValueDescriptor::GetSourceLocation( + SourceLocation* out_location) const { + std::vector<int> path; + GetLocationPath(&path); + return type()->file()->GetSourceLocation(path, out_location); +} + +void Descriptor::GetLocationPath(std::vector<int>* output) const { + if (containing_type()) { + containing_type()->GetLocationPath(output); + output->push_back(DescriptorProto::kNestedTypeFieldNumber); + output->push_back(index()); + } else { + output->push_back(FileDescriptorProto::kMessageTypeFieldNumber); + output->push_back(index()); + } +} + +void FieldDescriptor::GetLocationPath(std::vector<int>* output) const { + if (is_extension()) { + if (extension_scope() == nullptr) { + output->push_back(FileDescriptorProto::kExtensionFieldNumber); + output->push_back(index()); + } else { + extension_scope()->GetLocationPath(output); + output->push_back(DescriptorProto::kExtensionFieldNumber); + output->push_back(index()); + } + } else { + containing_type()->GetLocationPath(output); + output->push_back(DescriptorProto::kFieldFieldNumber); + output->push_back(index()); + } +} + +void OneofDescriptor::GetLocationPath(std::vector<int>* output) const { + containing_type()->GetLocationPath(output); + output->push_back(DescriptorProto::kOneofDeclFieldNumber); + output->push_back(index()); +} + +void EnumDescriptor::GetLocationPath(std::vector<int>* output) const { + if (containing_type()) { + containing_type()->GetLocationPath(output); + output->push_back(DescriptorProto::kEnumTypeFieldNumber); + output->push_back(index()); + } else { + output->push_back(FileDescriptorProto::kEnumTypeFieldNumber); + output->push_back(index()); + } +} + +void EnumValueDescriptor::GetLocationPath(std::vector<int>* output) const { + type()->GetLocationPath(output); + output->push_back(EnumDescriptorProto::kValueFieldNumber); + output->push_back(index()); +} + +void ServiceDescriptor::GetLocationPath(std::vector<int>* output) const { + output->push_back(FileDescriptorProto::kServiceFieldNumber); + output->push_back(index()); +} + +void MethodDescriptor::GetLocationPath(std::vector<int>* output) const { + service()->GetLocationPath(output); + output->push_back(ServiceDescriptorProto::kMethodFieldNumber); + output->push_back(index()); +} + +// =================================================================== + +namespace { + +// Represents an options message to interpret. Extension names in the option +// name are resolved relative to name_scope. element_name and orig_opt are +// used only for error reporting (since the parser records locations against +// pointers in the original options, not the mutable copy). The Message must be +// one of the Options messages in descriptor.proto. +struct OptionsToInterpret { + OptionsToInterpret(const TProtoStringType& ns, const TProtoStringType& el, + const std::vector<int>& path, const Message* orig_opt, + Message* opt) + : name_scope(ns), + element_name(el), + element_path(path), + original_options(orig_opt), + options(opt) {} + TProtoStringType name_scope; + TProtoStringType element_name; + std::vector<int> element_path; + const Message* original_options; + Message* options; +}; + +} // namespace + +class DescriptorBuilder { + public: + DescriptorBuilder(const DescriptorPool* pool, DescriptorPool::Tables* tables, + DescriptorPool::ErrorCollector* error_collector); + ~DescriptorBuilder(); + + const FileDescriptor* BuildFile(const FileDescriptorProto& proto); + + private: + friend class OptionInterpreter; + + // Non-recursive part of BuildFile functionality. + FileDescriptor* BuildFileImpl(const FileDescriptorProto& proto); + + const DescriptorPool* pool_; + DescriptorPool::Tables* tables_; // for convenience + DescriptorPool::ErrorCollector* error_collector_; + + // As we build descriptors we store copies of the options messages in + // them. We put pointers to those copies in this vector, as we build, so we + // can later (after cross-linking) interpret those options. + std::vector<OptionsToInterpret> options_to_interpret_; + + bool had_errors_; + TProtoStringType filename_; + FileDescriptor* file_; + FileDescriptorTables* file_tables_; + std::set<const FileDescriptor*> dependencies_; + + // unused_dependency_ is used to record the unused imported files. + // Note: public import is not considered. + std::set<const FileDescriptor*> unused_dependency_; + + // If LookupSymbol() finds a symbol that is in a file which is not a declared + // dependency of this file, it will fail, but will set + // possible_undeclared_dependency_ to point at that file. This is only used + // by AddNotDefinedError() to report a more useful error message. + // possible_undeclared_dependency_name_ is the name of the symbol that was + // actually found in possible_undeclared_dependency_, which may be a parent + // of the symbol actually looked for. + const FileDescriptor* possible_undeclared_dependency_; + TProtoStringType possible_undeclared_dependency_name_; + + // If LookupSymbol() could resolve a symbol which is not defined, + // record the resolved name. This is only used by AddNotDefinedError() + // to report a more useful error message. + TProtoStringType undefine_resolved_name_; + + void AddError(const TProtoStringType& element_name, const Message& descriptor, + DescriptorPool::ErrorCollector::ErrorLocation location, + const TProtoStringType& error); + void AddError(const TProtoStringType& element_name, const Message& descriptor, + DescriptorPool::ErrorCollector::ErrorLocation location, + const char* error); + void AddRecursiveImportError(const FileDescriptorProto& proto, int from_here); + void AddTwiceListedError(const FileDescriptorProto& proto, int index); + void AddImportError(const FileDescriptorProto& proto, int index); + + // Adds an error indicating that undefined_symbol was not defined. Must + // only be called after LookupSymbol() fails. + void AddNotDefinedError( + const TProtoStringType& element_name, const Message& descriptor, + DescriptorPool::ErrorCollector::ErrorLocation location, + const TProtoStringType& undefined_symbol); + + void AddWarning(const TProtoStringType& element_name, const Message& descriptor, + DescriptorPool::ErrorCollector::ErrorLocation location, + const TProtoStringType& error); + + // Silly helper which determines if the given file is in the given package. + // I.e., either file->package() == package_name or file->package() is a + // nested package within package_name. + bool IsInPackage(const FileDescriptor* file, const TProtoStringType& package_name); + + // Helper function which finds all public dependencies of the given file, and + // stores the them in the dependencies_ set in the builder. + void RecordPublicDependencies(const FileDescriptor* file); + + // Like tables_->FindSymbol(), but additionally: + // - Search the pool's underlay if not found in tables_. + // - Insure that the resulting Symbol is from one of the file's declared + // dependencies. + Symbol FindSymbol(const TProtoStringType& name, bool build_it = true); + + // Like FindSymbol() but does not require that the symbol is in one of the + // file's declared dependencies. + Symbol FindSymbolNotEnforcingDeps(const TProtoStringType& name, + bool build_it = true); + + // This implements the body of FindSymbolNotEnforcingDeps(). + Symbol FindSymbolNotEnforcingDepsHelper(const DescriptorPool* pool, + const TProtoStringType& name, + bool build_it = true); + + // Like FindSymbol(), but looks up the name relative to some other symbol + // name. This first searches siblings of relative_to, then siblings of its + // parents, etc. For example, LookupSymbol("foo.bar", "baz.qux.corge") makes + // the following calls, returning the first non-null result: + // FindSymbol("baz.qux.foo.bar"), FindSymbol("baz.foo.bar"), + // FindSymbol("foo.bar"). If AllowUnknownDependencies() has been called + // on the DescriptorPool, this will generate a placeholder type if + // the name is not found (unless the name itself is malformed). The + // placeholder_type parameter indicates what kind of placeholder should be + // constructed in this case. The resolve_mode parameter determines whether + // any symbol is returned, or only symbols that are types. Note, however, + // that LookupSymbol may still return a non-type symbol in LOOKUP_TYPES mode, + // if it believes that's all it could refer to. The caller should always + // check that it receives the type of symbol it was expecting. + enum ResolveMode { LOOKUP_ALL, LOOKUP_TYPES }; + Symbol LookupSymbol(const TProtoStringType& name, const TProtoStringType& relative_to, + DescriptorPool::PlaceholderType placeholder_type = + DescriptorPool::PLACEHOLDER_MESSAGE, + ResolveMode resolve_mode = LOOKUP_ALL, + bool build_it = true); + + // Like LookupSymbol() but will not return a placeholder even if + // AllowUnknownDependencies() has been used. + Symbol LookupSymbolNoPlaceholder(const TProtoStringType& name, + const TProtoStringType& relative_to, + ResolveMode resolve_mode = LOOKUP_ALL, + bool build_it = true); + + // Calls tables_->AddSymbol() and records an error if it fails. Returns + // true if successful or false if failed, though most callers can ignore + // the return value since an error has already been recorded. + bool AddSymbol(const TProtoStringType& full_name, const void* parent, + const TProtoStringType& name, const Message& proto, Symbol symbol); + + // Like AddSymbol(), but succeeds if the symbol is already defined as long + // as the existing definition is also a package (because it's OK to define + // the same package in two different files). Also adds all parents of the + // package to the symbol table (e.g. AddPackage("foo.bar", ...) will add + // "foo.bar" and "foo" to the table). + void AddPackage(const TProtoStringType& name, const Message& proto, + FileDescriptor* file); + + // Checks that the symbol name contains only alphanumeric characters and + // underscores. Records an error otherwise. + void ValidateSymbolName(const TProtoStringType& name, const TProtoStringType& full_name, + const Message& proto); + + // Used by BUILD_ARRAY macro (below) to avoid having to have the type + // specified as a macro parameter. + template <typename Type> + inline void AllocateArray(int size, Type** output) { + *output = tables_->AllocateArray<Type>(size); + } + + // Allocates a copy of orig_options in tables_ and stores it in the + // descriptor. Remembers its uninterpreted options, to be interpreted + // later. DescriptorT must be one of the Descriptor messages from + // descriptor.proto. + template <class DescriptorT> + void AllocateOptions(const typename DescriptorT::OptionsType& orig_options, + DescriptorT* descriptor, int options_field_tag, + const TProtoStringType& option_name); + // Specialization for FileOptions. + void AllocateOptions(const FileOptions& orig_options, + FileDescriptor* descriptor); + + // Implementation for AllocateOptions(). Don't call this directly. + template <class DescriptorT> + void AllocateOptionsImpl( + const TProtoStringType& name_scope, const TProtoStringType& element_name, + const typename DescriptorT::OptionsType& orig_options, + DescriptorT* descriptor, const std::vector<int>& options_path, + const TProtoStringType& option_name); + + // Allocates an array of two strings, the first one is a copy of `proto_name`, + // and the second one is the full name. + // Full proto name is "scope.proto_name" if scope is non-empty and + // "proto_name" otherwise. + const TProtoStringType* AllocateNameStrings(const TProtoStringType& scope, + const TProtoStringType& proto_name); + + // These methods all have the same signature for the sake of the BUILD_ARRAY + // macro, below. + void BuildMessage(const DescriptorProto& proto, const Descriptor* parent, + Descriptor* result); + void BuildFieldOrExtension(const FieldDescriptorProto& proto, + Descriptor* parent, FieldDescriptor* result, + bool is_extension); + void BuildField(const FieldDescriptorProto& proto, Descriptor* parent, + FieldDescriptor* result) { + BuildFieldOrExtension(proto, parent, result, false); + } + void BuildExtension(const FieldDescriptorProto& proto, Descriptor* parent, + FieldDescriptor* result) { + BuildFieldOrExtension(proto, parent, result, true); + } + void BuildExtensionRange(const DescriptorProto::ExtensionRange& proto, + const Descriptor* parent, + Descriptor::ExtensionRange* result); + void BuildReservedRange(const DescriptorProto::ReservedRange& proto, + const Descriptor* parent, + Descriptor::ReservedRange* result); + void BuildReservedRange(const EnumDescriptorProto::EnumReservedRange& proto, + const EnumDescriptor* parent, + EnumDescriptor::ReservedRange* result); + void BuildOneof(const OneofDescriptorProto& proto, Descriptor* parent, + OneofDescriptor* result); + void CheckEnumValueUniqueness(const EnumDescriptorProto& proto, + const EnumDescriptor* result); + void BuildEnum(const EnumDescriptorProto& proto, const Descriptor* parent, + EnumDescriptor* result); + void BuildEnumValue(const EnumValueDescriptorProto& proto, + const EnumDescriptor* parent, + EnumValueDescriptor* result); + void BuildService(const ServiceDescriptorProto& proto, const void* dummy, + ServiceDescriptor* result); + void BuildMethod(const MethodDescriptorProto& proto, + const ServiceDescriptor* parent, MethodDescriptor* result); + + void LogUnusedDependency(const FileDescriptorProto& proto, + const FileDescriptor* result); + + // Must be run only after building. + // + // NOTE: Options will not be available during cross-linking, as they + // have not yet been interpreted. Defer any handling of options to the + // Validate*Options methods. + void CrossLinkFile(FileDescriptor* file, const FileDescriptorProto& proto); + void CrossLinkMessage(Descriptor* message, const DescriptorProto& proto); + void CrossLinkField(FieldDescriptor* field, + const FieldDescriptorProto& proto); + void CrossLinkExtensionRange(Descriptor::ExtensionRange* range, + const DescriptorProto::ExtensionRange& proto); + void CrossLinkEnum(EnumDescriptor* enum_type, + const EnumDescriptorProto& proto); + void CrossLinkEnumValue(EnumValueDescriptor* enum_value, + const EnumValueDescriptorProto& proto); + void CrossLinkService(ServiceDescriptor* service, + const ServiceDescriptorProto& proto); + void CrossLinkMethod(MethodDescriptor* method, + const MethodDescriptorProto& proto); + + // Must be run only after cross-linking. + void InterpretOptions(); + + // A helper class for interpreting options. + class OptionInterpreter { + public: + // Creates an interpreter that operates in the context of the pool of the + // specified builder, which must not be nullptr. We don't take ownership of + // the builder. + explicit OptionInterpreter(DescriptorBuilder* builder); + + ~OptionInterpreter(); + + // Interprets the uninterpreted options in the specified Options message. + // On error, calls AddError() on the underlying builder and returns false. + // Otherwise returns true. + bool InterpretOptions(OptionsToInterpret* options_to_interpret); + + // Updates the given source code info by re-writing uninterpreted option + // locations to refer to the corresponding interpreted option. + void UpdateSourceCodeInfo(SourceCodeInfo* info); + + class AggregateOptionFinder; + + private: + // Interprets uninterpreted_option_ on the specified message, which + // must be the mutable copy of the original options message to which + // uninterpreted_option_ belongs. The given src_path is the source + // location path to the uninterpreted option, and options_path is the + // source location path to the options message. The location paths are + // recorded and then used in UpdateSourceCodeInfo. + bool InterpretSingleOption(Message* options, + const std::vector<int>& src_path, + const std::vector<int>& options_path); + + // Adds the uninterpreted_option to the given options message verbatim. + // Used when AllowUnknownDependencies() is in effect and we can't find + // the option's definition. + void AddWithoutInterpreting(const UninterpretedOption& uninterpreted_option, + Message* options); + + // A recursive helper function that drills into the intermediate fields + // in unknown_fields to check if field innermost_field is set on the + // innermost message. Returns false and sets an error if so. + bool ExamineIfOptionIsSet( + std::vector<const FieldDescriptor*>::const_iterator + intermediate_fields_iter, + std::vector<const FieldDescriptor*>::const_iterator + intermediate_fields_end, + const FieldDescriptor* innermost_field, + const TProtoStringType& debug_msg_name, + const UnknownFieldSet& unknown_fields); + + // Validates the value for the option field of the currently interpreted + // option and then sets it on the unknown_field. + bool SetOptionValue(const FieldDescriptor* option_field, + UnknownFieldSet* unknown_fields); + + // Parses an aggregate value for a CPPTYPE_MESSAGE option and + // saves it into *unknown_fields. + bool SetAggregateOption(const FieldDescriptor* option_field, + UnknownFieldSet* unknown_fields); + + // Convenience functions to set an int field the right way, depending on + // its wire type (a single int CppType can represent multiple wire types). + void SetInt32(int number, arc_i32 value, FieldDescriptor::Type type, + UnknownFieldSet* unknown_fields); + void SetInt64(int number, arc_i64 value, FieldDescriptor::Type type, + UnknownFieldSet* unknown_fields); + void SetUInt32(int number, arc_ui32 value, FieldDescriptor::Type type, + UnknownFieldSet* unknown_fields); + void SetUInt64(int number, arc_ui64 value, FieldDescriptor::Type type, + UnknownFieldSet* unknown_fields); + + // A helper function that adds an error at the specified location of the + // option we're currently interpreting, and returns false. + bool AddOptionError(DescriptorPool::ErrorCollector::ErrorLocation location, + const TProtoStringType& msg) { + builder_->AddError(options_to_interpret_->element_name, + *uninterpreted_option_, location, msg); + return false; + } + + // A helper function that adds an error at the location of the option name + // and returns false. + bool AddNameError(const TProtoStringType& msg) { +#ifdef PROTOBUF_INTERNAL_IGNORE_FIELD_NAME_ERRORS_ + return true; +#else // PROTOBUF_INTERNAL_IGNORE_FIELD_NAME_ERRORS_ + return AddOptionError(DescriptorPool::ErrorCollector::OPTION_NAME, msg); +#endif // PROTOBUF_INTERNAL_IGNORE_FIELD_NAME_ERRORS_ + } + + // A helper function that adds an error at the location of the option name + // and returns false. + bool AddValueError(const TProtoStringType& msg) { + return AddOptionError(DescriptorPool::ErrorCollector::OPTION_VALUE, msg); + } + + // We interpret against this builder's pool. Is never nullptr. We don't own + // this pointer. + DescriptorBuilder* builder_; + + // The options we're currently interpreting, or nullptr if we're not in a + // call to InterpretOptions. + const OptionsToInterpret* options_to_interpret_; + + // The option we're currently interpreting within options_to_interpret_, or + // nullptr if we're not in a call to InterpretOptions(). This points to a + // submessage of the original option, not the mutable copy. Therefore we + // can use it to find locations recorded by the parser. + const UninterpretedOption* uninterpreted_option_; + + // This maps the element path of uninterpreted options to the element path + // of the resulting interpreted option. This is used to modify a file's + // source code info to account for option interpretation. + std::map<std::vector<int>, std::vector<int>> interpreted_paths_; + + // This maps the path to a repeated option field to the known number of + // elements the field contains. This is used to track the compute the + // index portion of the element path when interpreting a single option. + std::map<std::vector<int>, int> repeated_option_counts_; + + // Factory used to create the dynamic messages we need to parse + // any aggregate option values we encounter. + DynamicMessageFactory dynamic_factory_; + + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(OptionInterpreter); + }; + + // Work-around for broken compilers: According to the C++ standard, + // OptionInterpreter should have access to the private members of any class + // which has declared DescriptorBuilder as a friend. Unfortunately some old + // versions of GCC and other compilers do not implement this correctly. So, + // we have to have these intermediate methods to provide access. We also + // redundantly declare OptionInterpreter a friend just to make things extra + // clear for these bad compilers. + friend class OptionInterpreter; + friend class OptionInterpreter::AggregateOptionFinder; + + static inline bool get_allow_unknown(const DescriptorPool* pool) { + return pool->allow_unknown_; + } + static inline bool get_enforce_weak(const DescriptorPool* pool) { + return pool->enforce_weak_; + } + static inline bool get_is_placeholder(const Descriptor* descriptor) { + return descriptor != nullptr && descriptor->is_placeholder_; + } + static inline void assert_mutex_held(const DescriptorPool* pool) { + if (pool->mutex_ != nullptr) { + pool->mutex_->AssertHeld(); + } + } + + // Must be run only after options have been interpreted. + // + // NOTE: Validation code must only reference the options in the mutable + // descriptors, which are the ones that have been interpreted. The const + // proto references are passed in only so they can be provided to calls to + // AddError(). Do not look at their options, which have not been interpreted. + void ValidateFileOptions(FileDescriptor* file, + const FileDescriptorProto& proto); + void ValidateMessageOptions(Descriptor* message, + const DescriptorProto& proto); + void ValidateFieldOptions(FieldDescriptor* field, + const FieldDescriptorProto& proto); + void ValidateEnumOptions(EnumDescriptor* enm, + const EnumDescriptorProto& proto); + void ValidateEnumValueOptions(EnumValueDescriptor* enum_value, + const EnumValueDescriptorProto& proto); + void ValidateExtensionRangeOptions( + const TProtoStringType& full_name, Descriptor::ExtensionRange* extension_range, + const DescriptorProto_ExtensionRange& proto); + void ValidateServiceOptions(ServiceDescriptor* service, + const ServiceDescriptorProto& proto); + void ValidateMethodOptions(MethodDescriptor* method, + const MethodDescriptorProto& proto); + void ValidateProto3(FileDescriptor* file, const FileDescriptorProto& proto); + void ValidateProto3Message(Descriptor* message, const DescriptorProto& proto); + void ValidateProto3Field(FieldDescriptor* field, + const FieldDescriptorProto& proto); + void ValidateProto3Enum(EnumDescriptor* enm, + const EnumDescriptorProto& proto); + + // Returns true if the map entry message is compatible with the + // auto-generated entry message from map fields syntax. + bool ValidateMapEntry(FieldDescriptor* field, + const FieldDescriptorProto& proto); + + // Recursively detects naming conflicts with map entry types for a + // better error message. + void DetectMapConflicts(const Descriptor* message, + const DescriptorProto& proto); + + void ValidateJSType(FieldDescriptor* field, + const FieldDescriptorProto& proto); +}; + +const FileDescriptor* DescriptorPool::BuildFile( + const FileDescriptorProto& proto) { + GOOGLE_CHECK(fallback_database_ == nullptr) + << "Cannot call BuildFile on a DescriptorPool that uses a " + "DescriptorDatabase. You must instead find a way to get your file " + "into the underlying database."; + GOOGLE_CHECK(mutex_ == nullptr); // Implied by the above GOOGLE_CHECK. + tables_->known_bad_symbols_.clear(); + tables_->known_bad_files_.clear(); + return DescriptorBuilder(this, tables_.get(), nullptr).BuildFile(proto); +} + +const FileDescriptor* DescriptorPool::BuildFileCollectingErrors( + const FileDescriptorProto& proto, ErrorCollector* error_collector) { + GOOGLE_CHECK(fallback_database_ == nullptr) + << "Cannot call BuildFile on a DescriptorPool that uses a " + "DescriptorDatabase. You must instead find a way to get your file " + "into the underlying database."; + GOOGLE_CHECK(mutex_ == nullptr); // Implied by the above GOOGLE_CHECK. + tables_->known_bad_symbols_.clear(); + tables_->known_bad_files_.clear(); + return DescriptorBuilder(this, tables_.get(), error_collector) + .BuildFile(proto); +} + +const FileDescriptor* DescriptorPool::BuildFileFromDatabase( + const FileDescriptorProto& proto) const { + mutex_->AssertHeld(); + if (tables_->known_bad_files_.count(proto.name()) > 0) { + return nullptr; + } + const FileDescriptor* result = + DescriptorBuilder(this, tables_.get(), default_error_collector_) + .BuildFile(proto); + if (result == nullptr) { + tables_->known_bad_files_.insert(proto.name()); + } + return result; +} + +DescriptorBuilder::DescriptorBuilder( + const DescriptorPool* pool, DescriptorPool::Tables* tables, + DescriptorPool::ErrorCollector* error_collector) + : pool_(pool), + tables_(tables), + error_collector_(error_collector), + had_errors_(false), + possible_undeclared_dependency_(nullptr), + undefine_resolved_name_("") {} + +DescriptorBuilder::~DescriptorBuilder() {} + +void DescriptorBuilder::AddError( + const TProtoStringType& element_name, const Message& descriptor, + DescriptorPool::ErrorCollector::ErrorLocation location, + const TProtoStringType& error) { + if (error_collector_ == nullptr) { + if (!had_errors_) { + GOOGLE_LOG(ERROR) << "Invalid proto descriptor for file \"" << filename_ + << "\":"; + } + GOOGLE_LOG(ERROR) << " " << element_name << ": " << error; + } else { + error_collector_->AddError(filename_, element_name, &descriptor, location, + error); + } + had_errors_ = true; +} + +void DescriptorBuilder::AddError( + const TProtoStringType& element_name, const Message& descriptor, + DescriptorPool::ErrorCollector::ErrorLocation location, const char* error) { + AddError(element_name, descriptor, location, TProtoStringType(error)); +} + +void DescriptorBuilder::AddNotDefinedError( + const TProtoStringType& element_name, const Message& descriptor, + DescriptorPool::ErrorCollector::ErrorLocation location, + const TProtoStringType& undefined_symbol) { + if (possible_undeclared_dependency_ == nullptr && + undefine_resolved_name_.empty()) { + AddError(element_name, descriptor, location, + "\"" + undefined_symbol + "\" is not defined."); + } else { + if (possible_undeclared_dependency_ != nullptr) { + AddError(element_name, descriptor, location, + "\"" + possible_undeclared_dependency_name_ + + "\" seems to be defined in \"" + + possible_undeclared_dependency_->name() + + "\", which is not " + "imported by \"" + + filename_ + + "\". To use it here, please " + "add the necessary import."); + } + if (!undefine_resolved_name_.empty()) { + AddError(element_name, descriptor, location, + "\"" + undefined_symbol + "\" is resolved to \"" + + undefine_resolved_name_ + + "\", which is not defined. " + "The innermost scope is searched first in name resolution. " + "Consider using a leading '.'(i.e., \"." + + undefined_symbol + "\") to start from the outermost scope."); + } + } +} + +void DescriptorBuilder::AddWarning( + const TProtoStringType& element_name, const Message& descriptor, + DescriptorPool::ErrorCollector::ErrorLocation location, + const TProtoStringType& error) { + if (error_collector_ == nullptr) { + GOOGLE_LOG(WARNING) << filename_ << " " << element_name << ": " << error; + } else { + error_collector_->AddWarning(filename_, element_name, &descriptor, location, + error); + } +} + +bool DescriptorBuilder::IsInPackage(const FileDescriptor* file, + const TProtoStringType& package_name) { + return HasPrefixString(file->package(), package_name) && + (file->package().size() == package_name.size() || + file->package()[package_name.size()] == '.'); +} + +void DescriptorBuilder::RecordPublicDependencies(const FileDescriptor* file) { + if (file == nullptr || !dependencies_.insert(file).second) return; + for (int i = 0; file != nullptr && i < file->public_dependency_count(); i++) { + RecordPublicDependencies(file->public_dependency(i)); + } +} + +Symbol DescriptorBuilder::FindSymbolNotEnforcingDepsHelper( + const DescriptorPool* pool, const TProtoStringType& name, bool build_it) { + // If we are looking at an underlay, we must lock its mutex_, since we are + // accessing the underlay's tables_ directly. + MutexLockMaybe lock((pool == pool_) ? nullptr : pool->mutex_); + + Symbol result = pool->tables_->FindSymbol(name); + if (result.IsNull() && pool->underlay_ != nullptr) { + // Symbol not found; check the underlay. + result = FindSymbolNotEnforcingDepsHelper(pool->underlay_, name); + } + + if (result.IsNull()) { + // With lazily_build_dependencies_, a symbol lookup at cross link time is + // not guaranteed to be successful. In most cases, build_it will be false, + // which intentionally prevents us from building an import until it's + // actually needed. In some cases, like registering an extension, we want + // to build the file containing the symbol, and build_it will be set. + // Also, build_it will be true when !lazily_build_dependencies_, to provide + // better error reporting of missing dependencies. + if (build_it && pool->TryFindSymbolInFallbackDatabase(name)) { + result = pool->tables_->FindSymbol(name); + } + } + + return result; +} + +Symbol DescriptorBuilder::FindSymbolNotEnforcingDeps(const TProtoStringType& name, + bool build_it) { + Symbol result = FindSymbolNotEnforcingDepsHelper(pool_, name, build_it); + // Only find symbols which were defined in this file or one of its + // dependencies. + const FileDescriptor* file = result.GetFile(); + if (file == file_ || dependencies_.count(file) > 0) { + unused_dependency_.erase(file); + } + return result; +} + +Symbol DescriptorBuilder::FindSymbol(const TProtoStringType& name, bool build_it) { + Symbol result = FindSymbolNotEnforcingDeps(name, build_it); + + if (result.IsNull()) return result; + + if (!pool_->enforce_dependencies_) { + // Hack for CompilerUpgrader, and also used for lazily_build_dependencies_ + return result; + } + + // Only find symbols which were defined in this file or one of its + // dependencies. + const FileDescriptor* file = result.GetFile(); + if (file == file_ || dependencies_.count(file) > 0) { + return result; + } + + if (result.type() == Symbol::PACKAGE) { + // Arg, this is overcomplicated. The symbol is a package name. It could + // be that the package was defined in multiple files. result.GetFile() + // returns the first file we saw that used this package. We've determined + // that that file is not a direct dependency of the file we are currently + // building, but it could be that some other file which *is* a direct + // dependency also defines the same package. We can't really rule out this + // symbol unless none of the dependencies define it. + if (IsInPackage(file_, name)) return result; + for (std::set<const FileDescriptor*>::const_iterator it = + dependencies_.begin(); + it != dependencies_.end(); ++it) { + // Note: A dependency may be nullptr if it was not found or had errors. + if (*it != nullptr && IsInPackage(*it, name)) return result; + } + } + + possible_undeclared_dependency_ = file; + possible_undeclared_dependency_name_ = name; + return Symbol(); +} + +Symbol DescriptorBuilder::LookupSymbolNoPlaceholder( + const TProtoStringType& name, const TProtoStringType& relative_to, + ResolveMode resolve_mode, bool build_it) { + possible_undeclared_dependency_ = nullptr; + undefine_resolved_name_.clear(); + + if (!name.empty() && name[0] == '.') { + // Fully-qualified name. + return FindSymbol(name.substr(1), build_it); + } + + // If name is something like "Foo.Bar.baz", and symbols named "Foo" are + // defined in multiple parent scopes, we only want to find "Bar.baz" in the + // innermost one. E.g., the following should produce an error: + // message Bar { message Baz {} } + // message Foo { + // message Bar { + // } + // optional Bar.Baz baz = 1; + // } + // So, we look for just "Foo" first, then look for "Bar.baz" within it if + // found. + TProtoStringType::size_type name_dot_pos = name.find_first_of('.'); + TProtoStringType first_part_of_name; + if (name_dot_pos == TProtoStringType::npos) { + first_part_of_name = name; + } else { + first_part_of_name = name.substr(0, name_dot_pos); + } + + TProtoStringType scope_to_try(relative_to); + + while (true) { + // Chop off the last component of the scope. + TProtoStringType::size_type dot_pos = scope_to_try.find_last_of('.'); + if (dot_pos == TProtoStringType::npos) { + return FindSymbol(name, build_it); + } else { + scope_to_try.erase(dot_pos); + } + + // Append ".first_part_of_name" and try to find. + TProtoStringType::size_type old_size = scope_to_try.size(); + scope_to_try.append(1, '.'); + scope_to_try.append(first_part_of_name); + Symbol result = FindSymbol(scope_to_try, build_it); + if (!result.IsNull()) { + if (first_part_of_name.size() < name.size()) { + // name is a compound symbol, of which we only found the first part. + // Now try to look up the rest of it. + if (result.IsAggregate()) { + scope_to_try.append(name, first_part_of_name.size(), + name.size() - first_part_of_name.size()); + result = FindSymbol(scope_to_try, build_it); + if (result.IsNull()) { + undefine_resolved_name_ = scope_to_try; + } + return result; + } else { + // We found a symbol but it's not an aggregate. Continue the loop. + } + } else { + if (resolve_mode == LOOKUP_TYPES && !result.IsType()) { + // We found a symbol but it's not a type. Continue the loop. + } else { + return result; + } + } + } + + // Not found. Remove the name so we can try again. + scope_to_try.erase(old_size); + } +} + +Symbol DescriptorBuilder::LookupSymbol( + const TProtoStringType& name, const TProtoStringType& relative_to, + DescriptorPool::PlaceholderType placeholder_type, ResolveMode resolve_mode, + bool build_it) { + Symbol result = + LookupSymbolNoPlaceholder(name, relative_to, resolve_mode, build_it); + if (result.IsNull() && pool_->allow_unknown_) { + // Not found, but AllowUnknownDependencies() is enabled. Return a + // placeholder instead. + result = pool_->NewPlaceholderWithMutexHeld(name, placeholder_type); + } + return result; +} + +static bool ValidateQualifiedName(StringPiece name) { + bool last_was_period = false; + + for (char character : name) { + // I don't trust isalnum() due to locales. :( + if (('a' <= character && character <= 'z') || + ('A' <= character && character <= 'Z') || + ('0' <= character && character <= '9') || (character == '_')) { + last_was_period = false; + } else if (character == '.') { + if (last_was_period) return false; + last_was_period = true; + } else { + return false; + } + } + + return !name.empty() && !last_was_period; +} + +Symbol DescriptorPool::NewPlaceholder(StringPiece name, + PlaceholderType placeholder_type) const { + MutexLockMaybe lock(mutex_); + return NewPlaceholderWithMutexHeld(name, placeholder_type); +} + +Symbol DescriptorPool::NewPlaceholderWithMutexHeld( + StringPiece name, PlaceholderType placeholder_type) const { + if (mutex_) { + mutex_->AssertHeld(); + } + // Compute names. + StringPiece placeholder_full_name; + StringPiece placeholder_name; + const TProtoStringType* placeholder_package; + + if (!ValidateQualifiedName(name)) return Symbol(); + if (name[0] == '.') { + // Fully-qualified. + placeholder_full_name = name.substr(1); + } else { + placeholder_full_name = name; + } + + TProtoStringType::size_type dotpos = placeholder_full_name.find_last_of('.'); + if (dotpos != TProtoStringType::npos) { + placeholder_package = + tables_->AllocateString(placeholder_full_name.substr(0, dotpos)); + placeholder_name = placeholder_full_name.substr(dotpos + 1); + } else { + placeholder_package = &internal::GetEmptyString(); + placeholder_name = placeholder_full_name; + } + + // Create the placeholders. + FileDescriptor* placeholder_file = NewPlaceholderFileWithMutexHeld( + StrCat(placeholder_full_name, ".placeholder.proto")); + placeholder_file->package_ = placeholder_package; + + if (placeholder_type == PLACEHOLDER_ENUM) { + placeholder_file->enum_type_count_ = 1; + placeholder_file->enum_types_ = tables_->AllocateArray<EnumDescriptor>(1); + + EnumDescriptor* placeholder_enum = &placeholder_file->enum_types_[0]; + memset(static_cast<void*>(placeholder_enum), 0, sizeof(*placeholder_enum)); + + placeholder_enum->all_names_ = + tables_->AllocateStringArray(placeholder_name, placeholder_full_name); + placeholder_enum->file_ = placeholder_file; + placeholder_enum->options_ = &EnumOptions::default_instance(); + placeholder_enum->is_placeholder_ = true; + placeholder_enum->is_unqualified_placeholder_ = (name[0] != '.'); + + // Enums must have at least one value. + placeholder_enum->value_count_ = 1; + placeholder_enum->values_ = tables_->AllocateArray<EnumValueDescriptor>(1); + // Disable fast-path lookup for this enum. + placeholder_enum->sequential_value_limit_ = -1; + + EnumValueDescriptor* placeholder_value = &placeholder_enum->values_[0]; + memset(static_cast<void*>(placeholder_value), 0, + sizeof(*placeholder_value)); + + // Note that enum value names are siblings of their type, not children. + placeholder_value->all_names_ = tables_->AllocateStringArray( + "PLACEHOLDER_VALUE", placeholder_package->empty() + ? "PLACEHOLDER_VALUE" + : *placeholder_package + ".PLACEHOLDER_VALUE"); + + placeholder_value->number_ = 0; + placeholder_value->type_ = placeholder_enum; + placeholder_value->options_ = &EnumValueOptions::default_instance(); + + return Symbol(placeholder_enum); + } else { + placeholder_file->message_type_count_ = 1; + placeholder_file->message_types_ = tables_->AllocateArray<Descriptor>(1); + + Descriptor* placeholder_message = &placeholder_file->message_types_[0]; + memset(static_cast<void*>(placeholder_message), 0, + sizeof(*placeholder_message)); + + placeholder_message->all_names_ = + tables_->AllocateStringArray(placeholder_name, placeholder_full_name); + placeholder_message->file_ = placeholder_file; + placeholder_message->options_ = &MessageOptions::default_instance(); + placeholder_message->is_placeholder_ = true; + placeholder_message->is_unqualified_placeholder_ = (name[0] != '.'); + + if (placeholder_type == PLACEHOLDER_EXTENDABLE_MESSAGE) { + placeholder_message->extension_range_count_ = 1; + placeholder_message->extension_ranges_ = + tables_->AllocateArray<Descriptor::ExtensionRange>(1); + placeholder_message->extension_ranges_->start = 1; + // kMaxNumber + 1 because ExtensionRange::end is exclusive. + placeholder_message->extension_ranges_->end = + FieldDescriptor::kMaxNumber + 1; + placeholder_message->extension_ranges_->options_ = nullptr; + } + + return Symbol(placeholder_message); + } +} + +FileDescriptor* DescriptorPool::NewPlaceholderFile( + StringPiece name) const { + MutexLockMaybe lock(mutex_); + return NewPlaceholderFileWithMutexHeld(name); +} + +FileDescriptor* DescriptorPool::NewPlaceholderFileWithMutexHeld( + StringPiece name) const { + if (mutex_) { + mutex_->AssertHeld(); + } + FileDescriptor* placeholder = tables_->Allocate<FileDescriptor>(); + memset(static_cast<void*>(placeholder), 0, sizeof(*placeholder)); + + placeholder->name_ = tables_->AllocateString(name); + placeholder->package_ = &internal::GetEmptyString(); + placeholder->pool_ = this; + placeholder->options_ = &FileOptions::default_instance(); + placeholder->tables_ = &FileDescriptorTables::GetEmptyInstance(); + placeholder->source_code_info_ = &SourceCodeInfo::default_instance(); + placeholder->is_placeholder_ = true; + placeholder->syntax_ = FileDescriptor::SYNTAX_UNKNOWN; + placeholder->finished_building_ = true; + // All other fields are zero or nullptr. + + return placeholder; +} + +bool DescriptorBuilder::AddSymbol(const TProtoStringType& full_name, + const void* parent, const TProtoStringType& name, + const Message& proto, Symbol symbol) { + // If the caller passed nullptr for the parent, the symbol is at file scope. + // Use its file as the parent instead. + if (parent == nullptr) parent = file_; + + if (full_name.find('\0') != TProtoStringType::npos) { + AddError(full_name, proto, DescriptorPool::ErrorCollector::NAME, + "\"" + full_name + "\" contains null character."); + return false; + } + if (tables_->AddSymbol(full_name, symbol)) { + if (!file_tables_->AddAliasUnderParent(parent, name, symbol)) { + // This is only possible if there was already an error adding something of + // the same name. + if (!had_errors_) { + GOOGLE_LOG(DFATAL) << "\"" << full_name + << "\" not previously defined in " + "symbols_by_name_, but was defined in " + "symbols_by_parent_; this shouldn't be possible."; + } + return false; + } + return true; + } else { + const FileDescriptor* other_file = tables_->FindSymbol(full_name).GetFile(); + if (other_file == file_) { + TProtoStringType::size_type dot_pos = full_name.find_last_of('.'); + if (dot_pos == TProtoStringType::npos) { + AddError(full_name, proto, DescriptorPool::ErrorCollector::NAME, + "\"" + full_name + "\" is already defined."); + } else { + AddError(full_name, proto, DescriptorPool::ErrorCollector::NAME, + "\"" + full_name.substr(dot_pos + 1) + + "\" is already defined in \"" + + full_name.substr(0, dot_pos) + "\"."); + } + } else { + // Symbol seems to have been defined in a different file. + AddError(full_name, proto, DescriptorPool::ErrorCollector::NAME, + "\"" + full_name + "\" is already defined in file \"" + + (other_file == nullptr ? "null" : other_file->name()) + + "\"."); + } + return false; + } +} + +void DescriptorBuilder::AddPackage(const TProtoStringType& name, + const Message& proto, FileDescriptor* file) { + if (name.find('\0') != TProtoStringType::npos) { + AddError(name, proto, DescriptorPool::ErrorCollector::NAME, + "\"" + name + "\" contains null character."); + return; + } + + Symbol existing_symbol = tables_->FindSymbol(name); + // It's OK to redefine a package. + if (existing_symbol.IsNull()) { + auto* package = tables_->AllocateArray<Symbol::Package>(1); + // If the name is the package name, then it is already in the arena. + // If not, copy it there. It came from the call to AddPackage below. + package->name = + &name == &file->package() ? &name : tables_->AllocateString(name); + package->file = file; + tables_->AddSymbol(*package->name, Symbol(package)); + // Also add parent package, if any. + TProtoStringType::size_type dot_pos = name.find_last_of('.'); + if (dot_pos == TProtoStringType::npos) { + // No parents. + ValidateSymbolName(name, name, proto); + } else { + // Has parent. + AddPackage(name.substr(0, dot_pos), proto, file); + ValidateSymbolName(name.substr(dot_pos + 1), name, proto); + } + } else if (existing_symbol.type() != Symbol::PACKAGE) { + // Symbol seems to have been defined in a different file. + AddError(name, proto, DescriptorPool::ErrorCollector::NAME, + "\"" + name + + "\" is already defined (as something other than " + "a package) in file \"" + + existing_symbol.GetFile()->name() + "\"."); + } +} + +void DescriptorBuilder::ValidateSymbolName(const TProtoStringType& name, + const TProtoStringType& full_name, + const Message& proto) { + if (name.empty()) { + AddError(full_name, proto, DescriptorPool::ErrorCollector::NAME, + "Missing name."); + } else { + for (char character : name) { + // I don't trust isalnum() due to locales. :( + if ((character < 'a' || 'z' < character) && + (character < 'A' || 'Z' < character) && + (character < '0' || '9' < character) && (character != '_')) { + AddError(full_name, proto, DescriptorPool::ErrorCollector::NAME, + "\"" + name + "\" is not a valid identifier."); + } + } + } +} + +// ------------------------------------------------------------------- + +// This generic implementation is good for all descriptors except +// FileDescriptor. +template <class DescriptorT> +void DescriptorBuilder::AllocateOptions( + const typename DescriptorT::OptionsType& orig_options, + DescriptorT* descriptor, int options_field_tag, + const TProtoStringType& option_name) { + std::vector<int> options_path; + descriptor->GetLocationPath(&options_path); + options_path.push_back(options_field_tag); + AllocateOptionsImpl(descriptor->full_name(), descriptor->full_name(), + orig_options, descriptor, options_path, option_name); +} + +// We specialize for FileDescriptor. +void DescriptorBuilder::AllocateOptions(const FileOptions& orig_options, + FileDescriptor* descriptor) { + std::vector<int> options_path; + options_path.push_back(FileDescriptorProto::kOptionsFieldNumber); + // We add the dummy token so that LookupSymbol does the right thing. + AllocateOptionsImpl(descriptor->package() + ".dummy", descriptor->name(), + orig_options, descriptor, options_path, + "google.protobuf.FileOptions"); +} + +template <class DescriptorT> +void DescriptorBuilder::AllocateOptionsImpl( + const TProtoStringType& name_scope, const TProtoStringType& element_name, + const typename DescriptorT::OptionsType& orig_options, + DescriptorT* descriptor, const std::vector<int>& options_path, + const TProtoStringType& option_name) { + // We need to use a dummy pointer to work around a bug in older versions of + // GCC. Otherwise, the following two lines could be replaced with: + // typename DescriptorT::OptionsType* options = + // tables_->AllocateMessage<typename DescriptorT::OptionsType>(); + typename DescriptorT::OptionsType* const dummy = nullptr; + typename DescriptorT::OptionsType* options = tables_->AllocateMessage(dummy); + + if (!orig_options.IsInitialized()) { + AddError(name_scope + "." + element_name, orig_options, + DescriptorPool::ErrorCollector::OPTION_NAME, + "Uninterpreted option is missing name or value."); + return; + } + + // Avoid using MergeFrom()/CopyFrom() in this class to make it -fno-rtti + // friendly. Without RTTI, MergeFrom() and CopyFrom() will fallback to the + // reflection based method, which requires the Descriptor. However, we are in + // the middle of building the descriptors, thus the deadlock. + options->ParseFromString(orig_options.SerializeAsString()); + descriptor->options_ = options; + + // Don't add to options_to_interpret_ unless there were uninterpreted + // options. This not only avoids unnecessary work, but prevents a + // bootstrapping problem when building descriptors for descriptor.proto. + // descriptor.proto does not contain any uninterpreted options, but + // attempting to interpret options anyway will cause + // OptionsType::GetDescriptor() to be called which may then deadlock since + // we're still trying to build it. + if (options->uninterpreted_option_size() > 0) { + options_to_interpret_.push_back(OptionsToInterpret( + name_scope, element_name, options_path, &orig_options, options)); + } + + // If the custom option is in unknown fields, no need to interpret it. + // Remove the dependency file from unused_dependency. + const UnknownFieldSet& unknown_fields = orig_options.unknown_fields(); + if (!unknown_fields.empty()) { + // Can not use options->GetDescriptor() which may case deadlock. + Symbol msg_symbol = tables_->FindSymbol(option_name); + if (msg_symbol.type() == Symbol::MESSAGE) { + for (int i = 0; i < unknown_fields.field_count(); ++i) { + assert_mutex_held(pool_); + const FieldDescriptor* field = + pool_->InternalFindExtensionByNumberNoLock( + msg_symbol.descriptor(), unknown_fields.field(i).number()); + if (field) { + unused_dependency_.erase(field->file()); + } + } + } + } +} + +// A common pattern: We want to convert a repeated field in the descriptor +// to an array of values, calling some method to build each value. +#define BUILD_ARRAY(INPUT, OUTPUT, NAME, METHOD, PARENT) \ + OUTPUT->NAME##_count_ = INPUT.NAME##_size(); \ + AllocateArray(INPUT.NAME##_size(), &OUTPUT->NAME##s_); \ + for (int i = 0; i < INPUT.NAME##_size(); i++) { \ + METHOD(INPUT.NAME(i), PARENT, OUTPUT->NAME##s_ + i); \ + } + +void DescriptorBuilder::AddRecursiveImportError( + const FileDescriptorProto& proto, int from_here) { + TProtoStringType error_message("File recursively imports itself: "); + for (size_t i = from_here; i < tables_->pending_files_.size(); i++) { + error_message.append(tables_->pending_files_[i]); + error_message.append(" -> "); + } + error_message.append(proto.name()); + + if (static_cast<size_t>(from_here) < tables_->pending_files_.size() - 1) { + AddError(tables_->pending_files_[from_here + 1], proto, + DescriptorPool::ErrorCollector::IMPORT, error_message); + } else { + AddError(proto.name(), proto, DescriptorPool::ErrorCollector::IMPORT, + error_message); + } +} + +void DescriptorBuilder::AddTwiceListedError(const FileDescriptorProto& proto, + int index) { + AddError(proto.dependency(index), proto, + DescriptorPool::ErrorCollector::IMPORT, + "Import \"" + proto.dependency(index) + "\" was listed twice."); +} + +void DescriptorBuilder::AddImportError(const FileDescriptorProto& proto, + int index) { + TProtoStringType message; + if (pool_->fallback_database_ == nullptr) { + message = "Import \"" + proto.dependency(index) + "\" has not been loaded."; + } else { + message = "Import \"" + proto.dependency(index) + + "\" was not found or had errors."; + } + AddError(proto.dependency(index), proto, + DescriptorPool::ErrorCollector::IMPORT, message); +} + +static bool ExistingFileMatchesProto(const FileDescriptor* existing_file, + const FileDescriptorProto& proto) { + FileDescriptorProto existing_proto; + existing_file->CopyTo(&existing_proto); + // TODO(liujisi): Remove it when CopyTo supports copying syntax params when + // syntax="proto2". + if (existing_file->syntax() == FileDescriptor::SYNTAX_PROTO2 && + proto.has_syntax()) { + existing_proto.set_syntax( + existing_file->SyntaxName(existing_file->syntax())); + } + + return existing_proto.SerializeAsString() == proto.SerializeAsString(); +} + +const FileDescriptor* DescriptorBuilder::BuildFile( + const FileDescriptorProto& proto) { + filename_ = proto.name(); + + // Check if the file already exists and is identical to the one being built. + // Note: This only works if the input is canonical -- that is, it + // fully-qualifies all type names, has no UninterpretedOptions, etc. + // This is fine, because this idempotency "feature" really only exists to + // accommodate one hack in the proto1->proto2 migration layer. + const FileDescriptor* existing_file = tables_->FindFile(filename_); + if (existing_file != nullptr) { + // File already in pool. Compare the existing one to the input. + if (ExistingFileMatchesProto(existing_file, proto)) { + // They're identical. Return the existing descriptor. + return existing_file; + } + + // Not a match. The error will be detected and handled later. + } + + // Check to see if this file is already on the pending files list. + // TODO(kenton): Allow recursive imports? It may not work with some + // (most?) programming languages. E.g., in C++, a forward declaration + // of a type is not sufficient to allow it to be used even in a + // generated header file due to inlining. This could perhaps be + // worked around using tricks involving inserting #include statements + // mid-file, but that's pretty ugly, and I'm pretty sure there are + // some languages out there that do not allow recursive dependencies + // at all. + for (size_t i = 0; i < tables_->pending_files_.size(); i++) { + if (tables_->pending_files_[i] == proto.name()) { + AddRecursiveImportError(proto, i); + return nullptr; + } + } + + // If we have a fallback_database_, and we aren't doing lazy import building, + // attempt to load all dependencies now, before checkpointing tables_. This + // avoids confusion with recursive checkpoints. + if (!pool_->lazily_build_dependencies_) { + if (pool_->fallback_database_ != nullptr) { + tables_->pending_files_.push_back(proto.name()); + for (int i = 0; i < proto.dependency_size(); i++) { + if (tables_->FindFile(proto.dependency(i)) == nullptr && + (pool_->underlay_ == nullptr || + pool_->underlay_->FindFileByName(proto.dependency(i)) == + nullptr)) { + // We don't care what this returns since we'll find out below anyway. + pool_->TryFindFileInFallbackDatabase(proto.dependency(i)); + } + } + tables_->pending_files_.pop_back(); + } + } + + // Checkpoint the tables so that we can roll back if something goes wrong. + tables_->AddCheckpoint(); + + FileDescriptor* result = BuildFileImpl(proto); + + file_tables_->FinalizeTables(); + if (result) { + tables_->ClearLastCheckpoint(); + result->finished_building_ = true; + } else { + tables_->RollbackToLastCheckpoint(); + } + + return result; +} + +FileDescriptor* DescriptorBuilder::BuildFileImpl( + const FileDescriptorProto& proto) { + FileDescriptor* result = tables_->Allocate<FileDescriptor>(); + file_ = result; + + result->is_placeholder_ = false; + result->finished_building_ = false; + SourceCodeInfo* info = nullptr; + if (proto.has_source_code_info()) { + info = tables_->AllocateMessage<SourceCodeInfo>(); + info->CopyFrom(proto.source_code_info()); + result->source_code_info_ = info; + } else { + result->source_code_info_ = &SourceCodeInfo::default_instance(); + } + + file_tables_ = tables_->AllocateFileTables(); + file_->tables_ = file_tables_; + + if (!proto.has_name()) { + AddError("", proto, DescriptorPool::ErrorCollector::OTHER, + "Missing field: FileDescriptorProto.name."); + } + + // TODO(liujisi): Report error when the syntax is empty after all the protos + // have added the syntax statement. + if (proto.syntax().empty() || proto.syntax() == "proto2") { + file_->syntax_ = FileDescriptor::SYNTAX_PROTO2; + } else if (proto.syntax() == "proto3") { + file_->syntax_ = FileDescriptor::SYNTAX_PROTO3; + } else { + file_->syntax_ = FileDescriptor::SYNTAX_UNKNOWN; + AddError(proto.name(), proto, DescriptorPool::ErrorCollector::OTHER, + "Unrecognized syntax: " + proto.syntax()); + } + + result->name_ = tables_->AllocateString(proto.name()); + if (proto.has_package()) { + result->package_ = tables_->AllocateString(proto.package()); + } else { + // We cannot rely on proto.package() returning a valid string if + // proto.has_package() is false, because we might be running at static + // initialization time, in which case default values have not yet been + // initialized. + result->package_ = tables_->AllocateString(""); + } + result->pool_ = pool_; + + if (result->name().find('\0') != TProtoStringType::npos) { + AddError(result->name(), proto, DescriptorPool::ErrorCollector::NAME, + "\"" + result->name() + "\" contains null character."); + return nullptr; + } + + // Add to tables. + if (!tables_->AddFile(result)) { + AddError(proto.name(), proto, DescriptorPool::ErrorCollector::OTHER, + "A file with this name is already in the pool."); + // Bail out early so that if this is actually the exact same file, we + // don't end up reporting that every single symbol is already defined. + return nullptr; + } + if (!result->package().empty()) { + AddPackage(result->package(), proto, result); + } + + // Make sure all dependencies are loaded. + std::set<TProtoStringType> seen_dependencies; + result->dependency_count_ = proto.dependency_size(); + result->dependencies_ = + tables_->AllocateArray<const FileDescriptor*>(proto.dependency_size()); + result->dependencies_once_ = nullptr; + unused_dependency_.clear(); + std::set<int> weak_deps; + for (int i = 0; i < proto.weak_dependency_size(); ++i) { + weak_deps.insert(proto.weak_dependency(i)); + } + for (int i = 0; i < proto.dependency_size(); i++) { + if (!seen_dependencies.insert(proto.dependency(i)).second) { + AddTwiceListedError(proto, i); + } + + const FileDescriptor* dependency = tables_->FindFile(proto.dependency(i)); + if (dependency == nullptr && pool_->underlay_ != nullptr) { + dependency = pool_->underlay_->FindFileByName(proto.dependency(i)); + } + + if (dependency == result) { + // Recursive import. dependency/result is not fully initialized, and it's + // dangerous to try to do anything with it. The recursive import error + // will be detected and reported in DescriptorBuilder::BuildFile(). + return nullptr; + } + + if (dependency == nullptr) { + if (!pool_->lazily_build_dependencies_) { + if (pool_->allow_unknown_ || + (!pool_->enforce_weak_ && weak_deps.find(i) != weak_deps.end())) { + dependency = + pool_->NewPlaceholderFileWithMutexHeld(proto.dependency(i)); + } else { + AddImportError(proto, i); + } + } + } else { + // Add to unused_dependency_ to track unused imported files. + // Note: do not track unused imported files for public import. + if (pool_->enforce_dependencies_ && + (pool_->unused_import_track_files_.find(proto.name()) != + pool_->unused_import_track_files_.end()) && + (dependency->public_dependency_count() == 0)) { + unused_dependency_.insert(dependency); + } + } + + result->dependencies_[i] = dependency; + if (pool_->lazily_build_dependencies_ && !dependency) { + if (result->dependencies_once_ == nullptr) { + result->dependencies_once_ = + tables_->Create<FileDescriptor::LazyInitData>(); + result->dependencies_once_->dependencies_names = + tables_->AllocateArray<const char*>(proto.dependency_size()); + if (proto.dependency_size() > 0) { + std::fill_n(result->dependencies_once_->dependencies_names, + proto.dependency_size(), nullptr); + } + } + + result->dependencies_once_->dependencies_names[i] = + tables_->Strdup(proto.dependency(i)); + } + } + + // Check public dependencies. + int public_dependency_count = 0; + result->public_dependencies_ = + tables_->AllocateArray<int>(proto.public_dependency_size()); + for (int i = 0; i < proto.public_dependency_size(); i++) { + // Only put valid public dependency indexes. + int index = proto.public_dependency(i); + if (index >= 0 && index < proto.dependency_size()) { + result->public_dependencies_[public_dependency_count++] = index; + // Do not track unused imported files for public import. + // Calling dependency(i) builds that file when doing lazy imports, + // need to avoid doing this. Unused dependency detection isn't done + // when building lazily, anyways. + if (!pool_->lazily_build_dependencies_) { + unused_dependency_.erase(result->dependency(index)); + } + } else { + AddError(proto.name(), proto, DescriptorPool::ErrorCollector::OTHER, + "Invalid public dependency index."); + } + } + result->public_dependency_count_ = public_dependency_count; + + // Build dependency set + dependencies_.clear(); + // We don't/can't do proper dependency error checking when + // lazily_build_dependencies_, and calling dependency(i) will force + // a dependency to be built, which we don't want. + if (!pool_->lazily_build_dependencies_) { + for (int i = 0; i < result->dependency_count(); i++) { + RecordPublicDependencies(result->dependency(i)); + } + } + + // Check weak dependencies. + int weak_dependency_count = 0; + result->weak_dependencies_ = + tables_->AllocateArray<int>(proto.weak_dependency_size()); + for (int i = 0; i < proto.weak_dependency_size(); i++) { + int index = proto.weak_dependency(i); + if (index >= 0 && index < proto.dependency_size()) { + result->weak_dependencies_[weak_dependency_count++] = index; + } else { + AddError(proto.name(), proto, DescriptorPool::ErrorCollector::OTHER, + "Invalid weak dependency index."); + } + } + result->weak_dependency_count_ = weak_dependency_count; + + // Convert children. + BUILD_ARRAY(proto, result, message_type, BuildMessage, nullptr); + BUILD_ARRAY(proto, result, enum_type, BuildEnum, nullptr); + BUILD_ARRAY(proto, result, service, BuildService, nullptr); + BUILD_ARRAY(proto, result, extension, BuildExtension, nullptr); + + // Copy options. + result->options_ = nullptr; // Set to default_instance later if necessary. + if (proto.has_options()) { + AllocateOptions(proto.options(), result); + } + + // Note that the following steps must occur in exactly the specified order. + + // Cross-link. + CrossLinkFile(result, proto); + + // Interpret any remaining uninterpreted options gathered into + // options_to_interpret_ during descriptor building. Cross-linking has made + // extension options known, so all interpretations should now succeed. + if (!had_errors_) { + OptionInterpreter option_interpreter(this); + for (std::vector<OptionsToInterpret>::iterator iter = + options_to_interpret_.begin(); + iter != options_to_interpret_.end(); ++iter) { + option_interpreter.InterpretOptions(&(*iter)); + } + options_to_interpret_.clear(); + if (info != nullptr) { + option_interpreter.UpdateSourceCodeInfo(info); + } + } + + // Validate options. See comments at InternalSetLazilyBuildDependencies about + // error checking and lazy import building. + if (!had_errors_ && !pool_->lazily_build_dependencies_) { + ValidateFileOptions(result, proto); + } + + // Additional naming conflict check for map entry types. Only need to check + // this if there are already errors. + if (had_errors_) { + for (int i = 0; i < proto.message_type_size(); ++i) { + DetectMapConflicts(result->message_type(i), proto.message_type(i)); + } + } + + + // Again, see comments at InternalSetLazilyBuildDependencies about error + // checking. Also, don't log unused dependencies if there were previous + // errors, since the results might be inaccurate. + if (!had_errors_ && !unused_dependency_.empty() && + !pool_->lazily_build_dependencies_) { + LogUnusedDependency(proto, result); + } + + if (had_errors_) { + return nullptr; + } else { + return result; + } +} + + +const TProtoStringType* DescriptorBuilder::AllocateNameStrings( + const TProtoStringType& scope, const TProtoStringType& proto_name) { + if (scope.empty()) { + return tables_->AllocateStringArray(proto_name, proto_name); + } else { + return tables_->AllocateStringArray(proto_name, + StrCat(scope, ".", proto_name)); + } +} + +void DescriptorBuilder::BuildMessage(const DescriptorProto& proto, + const Descriptor* parent, + Descriptor* result) { + const TProtoStringType& scope = + (parent == nullptr) ? file_->package() : parent->full_name(); + result->all_names_ = AllocateNameStrings(scope, proto.name()); + ValidateSymbolName(proto.name(), result->full_name(), proto); + + result->file_ = file_; + result->containing_type_ = parent; + result->is_placeholder_ = false; + result->is_unqualified_placeholder_ = false; + result->well_known_type_ = Descriptor::WELLKNOWNTYPE_UNSPECIFIED; + + auto it = pool_->tables_->well_known_types_.find(result->full_name()); + if (it != pool_->tables_->well_known_types_.end()) { + result->well_known_type_ = it->second; + } + + // Calculate the continuous sequence of fields. + // These can be fast-path'd during lookup and don't need to be added to the + // tables. + // We use uint16_t to save space for sequential_field_limit_, so stop before + // overflowing it. Worst case, we are not taking full advantage on huge + // messages, but it is unlikely. + result->sequential_field_limit_ = 0; + for (int i = 0; i < std::numeric_limits<uint16_t>::max() && + i < proto.field_size() && proto.field(i).number() == i + 1; + ++i) { + result->sequential_field_limit_ = i + 1; + } + + // Build oneofs first so that fields and extension ranges can refer to them. + BUILD_ARRAY(proto, result, oneof_decl, BuildOneof, result); + BUILD_ARRAY(proto, result, field, BuildField, result); + BUILD_ARRAY(proto, result, nested_type, BuildMessage, result); + BUILD_ARRAY(proto, result, enum_type, BuildEnum, result); + BUILD_ARRAY(proto, result, extension_range, BuildExtensionRange, result); + BUILD_ARRAY(proto, result, extension, BuildExtension, result); + BUILD_ARRAY(proto, result, reserved_range, BuildReservedRange, result); + + // Copy reserved names. + int reserved_name_count = proto.reserved_name_size(); + result->reserved_name_count_ = reserved_name_count; + result->reserved_names_ = + tables_->AllocateArray<const TProtoStringType*>(reserved_name_count); + for (int i = 0; i < reserved_name_count; ++i) { + result->reserved_names_[i] = + tables_->AllocateString(proto.reserved_name(i)); + } + + // Copy options. + result->options_ = nullptr; // Set to default_instance later if necessary. + if (proto.has_options()) { + AllocateOptions(proto.options(), result, + DescriptorProto::kOptionsFieldNumber, + "google.protobuf.MessageOptions"); + } + + AddSymbol(result->full_name(), parent, result->name(), proto, Symbol(result)); + + for (int i = 0; i < proto.reserved_range_size(); i++) { + const DescriptorProto_ReservedRange& range1 = proto.reserved_range(i); + for (int j = i + 1; j < proto.reserved_range_size(); j++) { + const DescriptorProto_ReservedRange& range2 = proto.reserved_range(j); + if (range1.end() > range2.start() && range2.end() > range1.start()) { + AddError(result->full_name(), proto.reserved_range(i), + DescriptorPool::ErrorCollector::NUMBER, + strings::Substitute("Reserved range $0 to $1 overlaps with " + "already-defined range $2 to $3.", + range2.start(), range2.end() - 1, + range1.start(), range1.end() - 1)); + } + } + } + + HASH_SET<TProtoStringType> reserved_name_set; + for (int i = 0; i < proto.reserved_name_size(); i++) { + const TProtoStringType& name = proto.reserved_name(i); + if (reserved_name_set.find(name) == reserved_name_set.end()) { + reserved_name_set.insert(name); + } else { + AddError(name, proto, DescriptorPool::ErrorCollector::NAME, + strings::Substitute("Field name \"$0\" is reserved multiple times.", + name)); + } + } + + + for (int i = 0; i < result->field_count(); i++) { + const FieldDescriptor* field = result->field(i); + for (int j = 0; j < result->extension_range_count(); j++) { + const Descriptor::ExtensionRange* range = result->extension_range(j); + if (range->start <= field->number() && field->number() < range->end) { + AddError( + field->full_name(), proto.extension_range(j), + DescriptorPool::ErrorCollector::NUMBER, + strings::Substitute( + "Extension range $0 to $1 includes field \"$2\" ($3).", + range->start, range->end - 1, field->name(), field->number())); + } + } + for (int j = 0; j < result->reserved_range_count(); j++) { + const Descriptor::ReservedRange* range = result->reserved_range(j); + if (range->start <= field->number() && field->number() < range->end) { + AddError(field->full_name(), proto.reserved_range(j), + DescriptorPool::ErrorCollector::NUMBER, + strings::Substitute("Field \"$0\" uses reserved number $1.", + field->name(), field->number())); + } + } + if (reserved_name_set.find(field->name()) != reserved_name_set.end()) { + AddError( + field->full_name(), proto.field(i), + DescriptorPool::ErrorCollector::NAME, + strings::Substitute("Field name \"$0\" is reserved.", field->name())); + } + + } + + // Check that extension ranges don't overlap and don't include + // reserved field numbers or names. + for (int i = 0; i < result->extension_range_count(); i++) { + const Descriptor::ExtensionRange* range1 = result->extension_range(i); + for (int j = 0; j < result->reserved_range_count(); j++) { + const Descriptor::ReservedRange* range2 = result->reserved_range(j); + if (range1->end > range2->start && range2->end > range1->start) { + AddError(result->full_name(), proto.extension_range(i), + DescriptorPool::ErrorCollector::NUMBER, + strings::Substitute("Extension range $0 to $1 overlaps with " + "reserved range $2 to $3.", + range1->start, range1->end - 1, range2->start, + range2->end - 1)); + } + } + for (int j = i + 1; j < result->extension_range_count(); j++) { + const Descriptor::ExtensionRange* range2 = result->extension_range(j); + if (range1->end > range2->start && range2->end > range1->start) { + AddError(result->full_name(), proto.extension_range(i), + DescriptorPool::ErrorCollector::NUMBER, + strings::Substitute("Extension range $0 to $1 overlaps with " + "already-defined range $2 to $3.", + range2->start, range2->end - 1, range1->start, + range1->end - 1)); + } + } + } +} + +void DescriptorBuilder::BuildFieldOrExtension(const FieldDescriptorProto& proto, + Descriptor* parent, + FieldDescriptor* result, + bool is_extension) { + const TProtoStringType& scope = + (parent == nullptr) ? file_->package() : parent->full_name(); + + // We allocate all names in a single array, and dedup them. + // We remember the indices for the potentially deduped values. + auto all_names = tables_->AllocateFieldNames( + proto.name(), scope, + proto.has_json_name() ? &proto.json_name() : nullptr); + result->all_names_ = all_names.array; + result->lowercase_name_index_ = all_names.lowercase_index; + result->camelcase_name_index_ = all_names.camelcase_index; + result->json_name_index_ = all_names.json_index; + + ValidateSymbolName(proto.name(), result->full_name(), proto); + + result->file_ = file_; + result->number_ = proto.number(); + result->is_extension_ = is_extension; + result->is_oneof_ = false; + result->proto3_optional_ = proto.proto3_optional(); + + if (proto.proto3_optional() && + file_->syntax() != FileDescriptor::SYNTAX_PROTO3) { + AddError(result->full_name(), proto, DescriptorPool::ErrorCollector::TYPE, + "The [proto3_optional=true] option may only be set on proto3" + "fields, not " + + result->full_name()); + } + + result->has_json_name_ = proto.has_json_name(); + + // Some compilers do not allow static_cast directly between two enum types, + // so we must cast to int first. + result->type_ = static_cast<FieldDescriptor::Type>( + implicit_cast<int>(proto.type())); + result->label_ = static_cast<FieldDescriptor::Label>( + implicit_cast<int>(proto.label())); + + if (result->label_ == FieldDescriptor::LABEL_REQUIRED) { + // An extension cannot have a required field (b/13365836). + if (result->is_extension_) { + AddError(result->full_name(), proto, + // Error location `TYPE`: we would really like to indicate + // `LABEL`, but the `ErrorLocation` enum has no entry for this, + // and we don't necessarily know about all implementations of the + // `ErrorCollector` interface to extend them to handle the new + // error location type properly. + DescriptorPool::ErrorCollector::TYPE, + "The extension " + result->full_name() + " cannot be required."); + } + } + + // Some of these may be filled in when cross-linking. + result->containing_type_ = nullptr; + result->type_once_ = nullptr; + result->default_value_enum_ = nullptr; + + result->has_default_value_ = proto.has_default_value(); + if (proto.has_default_value() && result->is_repeated()) { + AddError(result->full_name(), proto, + DescriptorPool::ErrorCollector::DEFAULT_VALUE, + "Repeated fields can't have default values."); + } + + if (proto.has_type()) { + if (proto.has_default_value()) { + char* end_pos = nullptr; + switch (result->cpp_type()) { + case FieldDescriptor::CPPTYPE_INT32: + result->default_value_arc_i32_ = + strtol(proto.default_value().c_str(), &end_pos, 0); + break; + case FieldDescriptor::CPPTYPE_INT64: + result->default_value_arc_i64_ = + strto64(proto.default_value().c_str(), &end_pos, 0); + break; + case FieldDescriptor::CPPTYPE_UINT32: + result->default_value_arc_ui32_ = + strtoul(proto.default_value().c_str(), &end_pos, 0); + break; + case FieldDescriptor::CPPTYPE_UINT64: + result->default_value_arc_ui64_ = + strtou64(proto.default_value().c_str(), &end_pos, 0); + break; + case FieldDescriptor::CPPTYPE_FLOAT: + if (proto.default_value() == "inf") { + result->default_value_float_ = + std::numeric_limits<float>::infinity(); + } else if (proto.default_value() == "-inf") { + result->default_value_float_ = + -std::numeric_limits<float>::infinity(); + } else if (proto.default_value() == "nan") { + result->default_value_float_ = + std::numeric_limits<float>::quiet_NaN(); + } else { + result->default_value_float_ = io::SafeDoubleToFloat( + io::NoLocaleStrtod(proto.default_value().c_str(), &end_pos)); + } + break; + case FieldDescriptor::CPPTYPE_DOUBLE: + if (proto.default_value() == "inf") { + result->default_value_double_ = + std::numeric_limits<double>::infinity(); + } else if (proto.default_value() == "-inf") { + result->default_value_double_ = + -std::numeric_limits<double>::infinity(); + } else if (proto.default_value() == "nan") { + result->default_value_double_ = + std::numeric_limits<double>::quiet_NaN(); + } else { + result->default_value_double_ = + io::NoLocaleStrtod(proto.default_value().c_str(), &end_pos); + } + break; + case FieldDescriptor::CPPTYPE_BOOL: + if (proto.default_value() == "true") { + result->default_value_bool_ = true; + } else if (proto.default_value() == "false") { + result->default_value_bool_ = false; + } else { + AddError(result->full_name(), proto, + DescriptorPool::ErrorCollector::DEFAULT_VALUE, + "Boolean default must be true or false."); + } + break; + case FieldDescriptor::CPPTYPE_ENUM: + // This will be filled in when cross-linking. + result->default_value_enum_ = nullptr; + break; + case FieldDescriptor::CPPTYPE_STRING: + if (result->type() == FieldDescriptor::TYPE_BYTES) { + result->default_value_string_ = tables_->AllocateString( + UnescapeCEscapeString(proto.default_value())); + } else { + result->default_value_string_ = + tables_->AllocateString(proto.default_value()); + } + break; + case FieldDescriptor::CPPTYPE_MESSAGE: + AddError(result->full_name(), proto, + DescriptorPool::ErrorCollector::DEFAULT_VALUE, + "Messages can't have default values."); + result->has_default_value_ = false; + result->default_generated_instance_ = nullptr; + break; + } + + if (end_pos != nullptr) { + // end_pos is only set non-null by the parsers for numeric types, + // above. This checks that the default was non-empty and had no extra + // junk after the end of the number. + if (proto.default_value().empty() || *end_pos != '\0') { + AddError(result->full_name(), proto, + DescriptorPool::ErrorCollector::DEFAULT_VALUE, + "Couldn't parse default value \"" + proto.default_value() + + "\"."); + } + } + } else { + // No explicit default value + switch (result->cpp_type()) { + case FieldDescriptor::CPPTYPE_INT32: + result->default_value_arc_i32_ = 0; + break; + case FieldDescriptor::CPPTYPE_INT64: + result->default_value_arc_i64_ = 0; + break; + case FieldDescriptor::CPPTYPE_UINT32: + result->default_value_arc_ui32_ = 0; + break; + case FieldDescriptor::CPPTYPE_UINT64: + result->default_value_arc_ui64_ = 0; + break; + case FieldDescriptor::CPPTYPE_FLOAT: + result->default_value_float_ = 0.0f; + break; + case FieldDescriptor::CPPTYPE_DOUBLE: + result->default_value_double_ = 0.0; + break; + case FieldDescriptor::CPPTYPE_BOOL: + result->default_value_bool_ = false; + break; + case FieldDescriptor::CPPTYPE_ENUM: + // This will be filled in when cross-linking. + result->default_value_enum_ = nullptr; + break; + case FieldDescriptor::CPPTYPE_STRING: + result->default_value_string_ = &internal::GetEmptyString(); + break; + case FieldDescriptor::CPPTYPE_MESSAGE: + result->default_generated_instance_ = nullptr; + break; + } + } + } + + if (result->number() <= 0) { + AddError(result->full_name(), proto, DescriptorPool::ErrorCollector::NUMBER, + "Field numbers must be positive integers."); + } else if (!is_extension && result->number() > FieldDescriptor::kMaxNumber) { + // Only validate that the number is within the valid field range if it is + // not an extension. Since extension numbers are validated with the + // extendee's valid set of extension numbers, and those are in turn + // validated against the max allowed number, the check is unnecessary for + // extension fields. + // This avoids cross-linking issues that arise when attempting to check if + // the extendee is a message_set_wire_format message, which has a higher max + // on extension numbers. + AddError(result->full_name(), proto, DescriptorPool::ErrorCollector::NUMBER, + strings::Substitute("Field numbers cannot be greater than $0.", + FieldDescriptor::kMaxNumber)); + } else if (result->number() >= FieldDescriptor::kFirstReservedNumber && + result->number() <= FieldDescriptor::kLastReservedNumber) { + AddError(result->full_name(), proto, DescriptorPool::ErrorCollector::NUMBER, + strings::Substitute( + "Field numbers $0 through $1 are reserved for the protocol " + "buffer library implementation.", + FieldDescriptor::kFirstReservedNumber, + FieldDescriptor::kLastReservedNumber)); + } + + if (is_extension) { + if (!proto.has_extendee()) { + AddError(result->full_name(), proto, + DescriptorPool::ErrorCollector::EXTENDEE, + "FieldDescriptorProto.extendee not set for extension field."); + } + + result->scope_.extension_scope = parent; + + if (proto.has_oneof_index()) { + AddError(result->full_name(), proto, DescriptorPool::ErrorCollector::TYPE, + "FieldDescriptorProto.oneof_index should not be set for " + "extensions."); + } + } else { + if (proto.has_extendee()) { + AddError(result->full_name(), proto, + DescriptorPool::ErrorCollector::EXTENDEE, + "FieldDescriptorProto.extendee set for non-extension field."); + } + + result->containing_type_ = parent; + + if (proto.has_oneof_index()) { + if (proto.oneof_index() < 0 || + proto.oneof_index() >= parent->oneof_decl_count()) { + AddError(result->full_name(), proto, + DescriptorPool::ErrorCollector::TYPE, + strings::Substitute("FieldDescriptorProto.oneof_index $0 is " + "out of range for type \"$1\".", + proto.oneof_index(), parent->name())); + } else { + result->is_oneof_ = true; + result->scope_.containing_oneof = + parent->oneof_decl(proto.oneof_index()); + } + } + } + + // Copy options. + result->options_ = nullptr; // Set to default_instance later if necessary. + if (proto.has_options()) { + AllocateOptions(proto.options(), result, + FieldDescriptorProto::kOptionsFieldNumber, + "google.protobuf.FieldOptions"); + } + + + AddSymbol(result->full_name(), parent, result->name(), proto, Symbol(result)); +} + +void DescriptorBuilder::BuildExtensionRange( + const DescriptorProto::ExtensionRange& proto, const Descriptor* parent, + Descriptor::ExtensionRange* result) { + result->start = proto.start(); + result->end = proto.end(); + if (result->start <= 0) { + AddError(parent->full_name(), proto, DescriptorPool::ErrorCollector::NUMBER, + "Extension numbers must be positive integers."); + } + + // Checking of the upper bound of the extension range is deferred until after + // options interpreting. This allows messages with message_set_wire_format to + // have extensions beyond FieldDescriptor::kMaxNumber, since the extension + // numbers are actually used as int32s in the message_set_wire_format. + + if (result->start >= result->end) { + AddError(parent->full_name(), proto, DescriptorPool::ErrorCollector::NUMBER, + "Extension range end number must be greater than start number."); + } + + result->options_ = nullptr; // Set to default_instance later if necessary. + if (proto.has_options()) { + std::vector<int> options_path; + parent->GetLocationPath(&options_path); + options_path.push_back(DescriptorProto::kExtensionRangeFieldNumber); + // find index of this extension range in order to compute path + int index; + for (index = 0; parent->extension_ranges_ + index != result; index++) { + } + options_path.push_back(index); + options_path.push_back(DescriptorProto_ExtensionRange::kOptionsFieldNumber); + AllocateOptionsImpl(parent->full_name(), parent->full_name(), + proto.options(), result, options_path, + "google.protobuf.ExtensionRangeOptions"); + } +} + +void DescriptorBuilder::BuildReservedRange( + const DescriptorProto::ReservedRange& proto, const Descriptor* parent, + Descriptor::ReservedRange* result) { + result->start = proto.start(); + result->end = proto.end(); + if (result->start <= 0) { + AddError(parent->full_name(), proto, DescriptorPool::ErrorCollector::NUMBER, + "Reserved numbers must be positive integers."); + } +} + +void DescriptorBuilder::BuildReservedRange( + const EnumDescriptorProto::EnumReservedRange& proto, + const EnumDescriptor* parent, EnumDescriptor::ReservedRange* result) { + result->start = proto.start(); + result->end = proto.end(); + + if (result->start > result->end) { + AddError(parent->full_name(), proto, DescriptorPool::ErrorCollector::NUMBER, + "Reserved range end number must be greater than start number."); + } +} + +void DescriptorBuilder::BuildOneof(const OneofDescriptorProto& proto, + Descriptor* parent, + OneofDescriptor* result) { + result->all_names_ = AllocateNameStrings(parent->full_name(), proto.name()); + ValidateSymbolName(proto.name(), result->full_name(), proto); + + result->containing_type_ = parent; + + // We need to fill these in later. + result->field_count_ = 0; + result->fields_ = nullptr; + result->options_ = nullptr; + + // Copy options. + if (proto.has_options()) { + AllocateOptions(proto.options(), result, + OneofDescriptorProto::kOptionsFieldNumber, + "google.protobuf.OneofOptions"); + } + + AddSymbol(result->full_name(), parent, result->name(), proto, Symbol(result)); +} + +void DescriptorBuilder::CheckEnumValueUniqueness( + const EnumDescriptorProto& proto, const EnumDescriptor* result) { + + // Check that enum labels are still unique when we remove the enum prefix from + // values that have it. + // + // This will fail for something like: + // + // enum MyEnum { + // MY_ENUM_FOO = 0; + // FOO = 1; + // } + // + // By enforcing this reasonable constraint, we allow code generators to strip + // the prefix and/or PascalCase it without creating conflicts. This can lead + // to much nicer language-specific enums like: + // + // enum NameType { + // FirstName = 1, + // LastName = 2, + // } + // + // Instead of: + // + // enum NameType { + // NAME_TYPE_FIRST_NAME = 1, + // NAME_TYPE_LAST_NAME = 2, + // } + PrefixRemover remover(result->name()); + std::map<TProtoStringType, const EnumValueDescriptor*> values; + for (int i = 0; i < result->value_count(); i++) { + const EnumValueDescriptor* value = result->value(i); + TProtoStringType stripped = + EnumValueToPascalCase(remover.MaybeRemove(value->name())); + std::pair<std::map<TProtoStringType, const EnumValueDescriptor*>::iterator, bool> + insert_result = values.insert(std::make_pair(stripped, value)); + bool inserted = insert_result.second; + + // We don't throw the error if the two conflicting symbols are identical, or + // if they map to the same number. In the former case, the normal symbol + // duplication error will fire so we don't need to (and its error message + // will make more sense). We allow the latter case so users can create + // aliases which add or remove the prefix (code generators that do prefix + // stripping should de-dup the labels in this case). + if (!inserted && insert_result.first->second->name() != value->name() && + insert_result.first->second->number() != value->number()) { + TProtoStringType error_message = + "Enum name " + value->name() + " has the same name as " + + values[stripped]->name() + + " if you ignore case and strip out the enum name prefix (if any). " + "This is error-prone and can lead to undefined behavior. " + "Please avoid doing this. If you are using allow_alias, please " + "assign the same numeric value to both enums."; + // There are proto2 enums out there with conflicting names, so to preserve + // compatibility we issue only a warning for proto2. + if (result->file()->syntax() == FileDescriptor::SYNTAX_PROTO2) { + AddWarning(value->full_name(), proto.value(i), + DescriptorPool::ErrorCollector::NAME, error_message); + } else { + AddError(value->full_name(), proto.value(i), + DescriptorPool::ErrorCollector::NAME, error_message); + } + } + } +} + +void DescriptorBuilder::BuildEnum(const EnumDescriptorProto& proto, + const Descriptor* parent, + EnumDescriptor* result) { + const TProtoStringType& scope = + (parent == nullptr) ? file_->package() : parent->full_name(); + + result->all_names_ = AllocateNameStrings(scope, proto.name()); + ValidateSymbolName(proto.name(), result->full_name(), proto); + result->file_ = file_; + result->containing_type_ = parent; + result->is_placeholder_ = false; + result->is_unqualified_placeholder_ = false; + + if (proto.value_size() == 0) { + // We cannot allow enums with no values because this would mean there + // would be no valid default value for fields of this type. + AddError(result->full_name(), proto, DescriptorPool::ErrorCollector::NAME, + "Enums must contain at least one value."); + } + + // Calculate the continuous sequence of the labels. + // These can be fast-path'd during lookup and don't need to be added to the + // tables. + // We use uint16_t to save space for sequential_value_limit_, so stop before + // overflowing it. Worst case, we are not taking full advantage on huge + // enums, but it is unlikely. + for (int i = 0; + i < std::numeric_limits<uint16_t>::max() && i < proto.value_size() && + // We do the math in arc_i64 to avoid overflows. + proto.value(i).number() == + static_cast<arc_i64>(i) + proto.value(0).number(); + ++i) { + result->sequential_value_limit_ = i; + } + + BUILD_ARRAY(proto, result, value, BuildEnumValue, result); + BUILD_ARRAY(proto, result, reserved_range, BuildReservedRange, result); + + // Copy reserved names. + int reserved_name_count = proto.reserved_name_size(); + result->reserved_name_count_ = reserved_name_count; + result->reserved_names_ = + tables_->AllocateArray<const TProtoStringType*>(reserved_name_count); + for (int i = 0; i < reserved_name_count; ++i) { + result->reserved_names_[i] = + tables_->AllocateString(proto.reserved_name(i)); + } + + CheckEnumValueUniqueness(proto, result); + + // Copy options. + result->options_ = nullptr; // Set to default_instance later if necessary. + if (proto.has_options()) { + AllocateOptions(proto.options(), result, + EnumDescriptorProto::kOptionsFieldNumber, + "google.protobuf.EnumOptions"); + } + + AddSymbol(result->full_name(), parent, result->name(), proto, Symbol(result)); + + for (int i = 0; i < proto.reserved_range_size(); i++) { + const EnumDescriptorProto_EnumReservedRange& range1 = + proto.reserved_range(i); + for (int j = i + 1; j < proto.reserved_range_size(); j++) { + const EnumDescriptorProto_EnumReservedRange& range2 = + proto.reserved_range(j); + if (range1.end() >= range2.start() && range2.end() >= range1.start()) { + AddError(result->full_name(), proto.reserved_range(i), + DescriptorPool::ErrorCollector::NUMBER, + strings::Substitute("Reserved range $0 to $1 overlaps with " + "already-defined range $2 to $3.", + range2.start(), range2.end(), range1.start(), + range1.end())); + } + } + } + + HASH_SET<TProtoStringType> reserved_name_set; + for (int i = 0; i < proto.reserved_name_size(); i++) { + const TProtoStringType& name = proto.reserved_name(i); + if (reserved_name_set.find(name) == reserved_name_set.end()) { + reserved_name_set.insert(name); + } else { + AddError(name, proto, DescriptorPool::ErrorCollector::NAME, + strings::Substitute("Enum value \"$0\" is reserved multiple times.", + name)); + } + } + + for (int i = 0; i < result->value_count(); i++) { + const EnumValueDescriptor* value = result->value(i); + for (int j = 0; j < result->reserved_range_count(); j++) { + const EnumDescriptor::ReservedRange* range = result->reserved_range(j); + if (range->start <= value->number() && value->number() <= range->end) { + AddError(value->full_name(), proto.reserved_range(j), + DescriptorPool::ErrorCollector::NUMBER, + strings::Substitute("Enum value \"$0\" uses reserved number $1.", + value->name(), value->number())); + } + } + if (reserved_name_set.find(value->name()) != reserved_name_set.end()) { + AddError( + value->full_name(), proto.value(i), + DescriptorPool::ErrorCollector::NAME, + strings::Substitute("Enum value \"$0\" is reserved.", value->name())); + } + } +} + +void DescriptorBuilder::BuildEnumValue(const EnumValueDescriptorProto& proto, + const EnumDescriptor* parent, + EnumValueDescriptor* result) { + // Note: full_name for enum values is a sibling to the parent's name, not a + // child of it. + TProtoStringType full_name; + size_t scope_len = parent->full_name().size() - parent->name().size(); + full_name.reserve(scope_len + proto.name().size()); + full_name.append(parent->full_name().data(), scope_len); + full_name.append(proto.name()); + + result->all_names_ = + tables_->AllocateStringArray(proto.name(), std::move(full_name)); + result->number_ = proto.number(); + result->type_ = parent; + + ValidateSymbolName(proto.name(), result->full_name(), proto); + + // Copy options. + result->options_ = nullptr; // Set to default_instance later if necessary. + if (proto.has_options()) { + AllocateOptions(proto.options(), result, + EnumValueDescriptorProto::kOptionsFieldNumber, + "google.protobuf.EnumValueOptions"); + } + + // Again, enum values are weird because we makes them appear as siblings + // of the enum type instead of children of it. So, we use + // parent->containing_type() as the value's parent. + bool added_to_outer_scope = + AddSymbol(result->full_name(), parent->containing_type(), result->name(), + proto, Symbol::EnumValue(result, 0)); + + // However, we also want to be able to search for values within a single + // enum type, so we add it as a child of the enum type itself, too. + // Note: This could fail, but if it does, the error has already been + // reported by the above AddSymbol() call, so we ignore the return code. + bool added_to_inner_scope = file_tables_->AddAliasUnderParent( + parent, result->name(), Symbol::EnumValue(result, 1)); + + if (added_to_inner_scope && !added_to_outer_scope) { + // This value did not conflict with any values defined in the same enum, + // but it did conflict with some other symbol defined in the enum type's + // scope. Let's print an additional error to explain this. + TProtoStringType outer_scope; + if (parent->containing_type() == nullptr) { + outer_scope = file_->package(); + } else { + outer_scope = parent->containing_type()->full_name(); + } + + if (outer_scope.empty()) { + outer_scope = "the global scope"; + } else { + outer_scope = "\"" + outer_scope + "\""; + } + + AddError(result->full_name(), proto, DescriptorPool::ErrorCollector::NAME, + "Note that enum values use C++ scoping rules, meaning that " + "enum values are siblings of their type, not children of it. " + "Therefore, \"" + + result->name() + "\" must be unique within " + outer_scope + + ", not just within \"" + parent->name() + "\"."); + } + + // An enum is allowed to define two numbers that refer to the same value. + // FindValueByNumber() should return the first such value, so we simply + // ignore AddEnumValueByNumber()'s return code. + file_tables_->AddEnumValueByNumber(result); +} + +void DescriptorBuilder::BuildService(const ServiceDescriptorProto& proto, + const void* /* dummy */, + ServiceDescriptor* result) { + result->all_names_ = AllocateNameStrings(file_->package(), proto.name()); + result->file_ = file_; + ValidateSymbolName(proto.name(), result->full_name(), proto); + + BUILD_ARRAY(proto, result, method, BuildMethod, result); + + // Copy options. + result->options_ = nullptr; // Set to default_instance later if necessary. + if (proto.has_options()) { + AllocateOptions(proto.options(), result, + ServiceDescriptorProto::kOptionsFieldNumber, + "google.protobuf.ServiceOptions"); + } + + AddSymbol(result->full_name(), nullptr, result->name(), proto, + Symbol(result)); +} + +void DescriptorBuilder::BuildMethod(const MethodDescriptorProto& proto, + const ServiceDescriptor* parent, + MethodDescriptor* result) { + result->service_ = parent; + result->all_names_ = AllocateNameStrings(parent->full_name(), proto.name()); + + ValidateSymbolName(proto.name(), result->full_name(), proto); + + // These will be filled in when cross-linking. + result->input_type_.Init(); + result->output_type_.Init(); + + // Copy options. + result->options_ = nullptr; // Set to default_instance later if necessary. + if (proto.has_options()) { + AllocateOptions(proto.options(), result, + MethodDescriptorProto::kOptionsFieldNumber, + "google.protobuf.MethodOptions"); + } + + result->client_streaming_ = proto.client_streaming(); + result->server_streaming_ = proto.server_streaming(); + + AddSymbol(result->full_name(), parent, result->name(), proto, Symbol(result)); +} + +#undef BUILD_ARRAY + +// ------------------------------------------------------------------- + +void DescriptorBuilder::CrossLinkFile(FileDescriptor* file, + const FileDescriptorProto& proto) { + if (file->options_ == nullptr) { + file->options_ = &FileOptions::default_instance(); + } + + for (int i = 0; i < file->message_type_count(); i++) { + CrossLinkMessage(&file->message_types_[i], proto.message_type(i)); + } + + for (int i = 0; i < file->extension_count(); i++) { + CrossLinkField(&file->extensions_[i], proto.extension(i)); + } + + for (int i = 0; i < file->enum_type_count(); i++) { + CrossLinkEnum(&file->enum_types_[i], proto.enum_type(i)); + } + + for (int i = 0; i < file->service_count(); i++) { + CrossLinkService(&file->services_[i], proto.service(i)); + } +} + +void DescriptorBuilder::CrossLinkMessage(Descriptor* message, + const DescriptorProto& proto) { + if (message->options_ == nullptr) { + message->options_ = &MessageOptions::default_instance(); + } + + for (int i = 0; i < message->nested_type_count(); i++) { + CrossLinkMessage(&message->nested_types_[i], proto.nested_type(i)); + } + + for (int i = 0; i < message->enum_type_count(); i++) { + CrossLinkEnum(&message->enum_types_[i], proto.enum_type(i)); + } + + for (int i = 0; i < message->field_count(); i++) { + CrossLinkField(&message->fields_[i], proto.field(i)); + } + + for (int i = 0; i < message->extension_count(); i++) { + CrossLinkField(&message->extensions_[i], proto.extension(i)); + } + + for (int i = 0; i < message->extension_range_count(); i++) { + CrossLinkExtensionRange(&message->extension_ranges_[i], + proto.extension_range(i)); + } + + // Set up field array for each oneof. + + // First count the number of fields per oneof. + for (int i = 0; i < message->field_count(); i++) { + const OneofDescriptor* oneof_decl = message->field(i)->containing_oneof(); + if (oneof_decl != nullptr) { + // Make sure fields belonging to the same oneof are defined consecutively. + // This enables optimizations in codegens and reflection libraries to + // skip fields in the oneof group, as only one of the field can be set. + // Note that field_count() returns how many fields in this oneof we have + // seen so far. field_count() > 0 guarantees that i > 0, so field(i-1) is + // safe. + if (oneof_decl->field_count() > 0 && + message->field(i - 1)->containing_oneof() != oneof_decl) { + AddError(message->full_name() + "." + message->field(i - 1)->name(), + proto.field(i - 1), DescriptorPool::ErrorCollector::TYPE, + strings::Substitute( + "Fields in the same oneof must be defined consecutively. " + "\"$0\" cannot be defined before the completion of the " + "\"$1\" oneof definition.", + message->field(i - 1)->name(), oneof_decl->name())); + } + // Must go through oneof_decls_ array to get a non-const version of the + // OneofDescriptor. + auto& out_oneof_decl = message->oneof_decls_[oneof_decl->index()]; + if (out_oneof_decl.field_count_ == 0) { + out_oneof_decl.fields_ = message->field(i); + } + + if (!had_errors_) { + // Verify that they are contiguous. + // This is assumed by OneofDescriptor::field(i). + // But only if there are no errors. + GOOGLE_CHECK_EQ(out_oneof_decl.fields_ + out_oneof_decl.field_count_, + message->field(i)); + } + ++out_oneof_decl.field_count_; + } + } + + // Then verify the sizes. + for (int i = 0; i < message->oneof_decl_count(); i++) { + OneofDescriptor* oneof_decl = &message->oneof_decls_[i]; + + if (oneof_decl->field_count() == 0) { + AddError(message->full_name() + "." + oneof_decl->name(), + proto.oneof_decl(i), DescriptorPool::ErrorCollector::NAME, + "Oneof must have at least one field."); + } + + if (oneof_decl->options_ == nullptr) { + oneof_decl->options_ = &OneofOptions::default_instance(); + } + } + + for (int i = 0; i < message->field_count(); i++) { + const FieldDescriptor* field = message->field(i); + if (field->proto3_optional_) { + if (!field->containing_oneof() || + !field->containing_oneof()->is_synthetic()) { + AddError(message->full_name(), proto.field(i), + DescriptorPool::ErrorCollector::OTHER, + "Fields with proto3_optional set must be " + "a member of a one-field oneof"); + } + } + } + + // Synthetic oneofs must be last. + int first_synthetic = -1; + for (int i = 0; i < message->oneof_decl_count(); i++) { + const OneofDescriptor* oneof = message->oneof_decl(i); + if (oneof->is_synthetic()) { + if (first_synthetic == -1) { + first_synthetic = i; + } + } else { + if (first_synthetic != -1) { + AddError(message->full_name(), proto.oneof_decl(i), + DescriptorPool::ErrorCollector::OTHER, + "Synthetic oneofs must be after all other oneofs"); + } + } + } + + if (first_synthetic == -1) { + message->real_oneof_decl_count_ = message->oneof_decl_count_; + } else { + message->real_oneof_decl_count_ = first_synthetic; + } +} + +void DescriptorBuilder::CrossLinkExtensionRange( + Descriptor::ExtensionRange* range, + const DescriptorProto::ExtensionRange& /*proto*/) { + if (range->options_ == nullptr) { + range->options_ = &ExtensionRangeOptions::default_instance(); + } +} + +void DescriptorBuilder::CrossLinkField(FieldDescriptor* field, + const FieldDescriptorProto& proto) { + if (field->options_ == nullptr) { + field->options_ = &FieldOptions::default_instance(); + } + + // Add the field to the lowercase-name and camelcase-name tables. + file_tables_->AddFieldByStylizedNames(field); + + if (proto.has_extendee()) { + Symbol extendee = + LookupSymbol(proto.extendee(), field->full_name(), + DescriptorPool::PLACEHOLDER_EXTENDABLE_MESSAGE); + if (extendee.IsNull()) { + AddNotDefinedError(field->full_name(), proto, + DescriptorPool::ErrorCollector::EXTENDEE, + proto.extendee()); + return; + } else if (extendee.type() != Symbol::MESSAGE) { + AddError(field->full_name(), proto, + DescriptorPool::ErrorCollector::EXTENDEE, + "\"" + proto.extendee() + "\" is not a message type."); + return; + } + field->containing_type_ = extendee.descriptor(); + + const Descriptor::ExtensionRange* extension_range = + field->containing_type()->FindExtensionRangeContainingNumber( + field->number()); + + if (extension_range == nullptr) { + // Set of valid extension numbers for MessageSet is different (< 2^32) + // from other extendees (< 2^29). If unknown deps are allowed, we may not + // have that information, and wrongly deem the extension as invalid. + auto skip_check = get_allow_unknown(pool_) && + proto.extendee() == "google.protobuf.bridge.MessageSet"; + if (!skip_check) { + AddError(field->full_name(), proto, + DescriptorPool::ErrorCollector::NUMBER, + strings::Substitute("\"$0\" does not declare $1 as an " + "extension number.", + field->containing_type()->full_name(), + field->number())); + } + } + } + + if (field->containing_oneof() != nullptr) { + if (field->label() != FieldDescriptor::LABEL_OPTIONAL) { + // Note that this error will never happen when parsing .proto files. + // It can only happen if you manually construct a FileDescriptorProto + // that is incorrect. + AddError(field->full_name(), proto, DescriptorPool::ErrorCollector::NAME, + "Fields of oneofs must themselves have label LABEL_OPTIONAL."); + } + } + + if (proto.has_type_name()) { + // Assume we are expecting a message type unless the proto contains some + // evidence that it expects an enum type. This only makes a difference if + // we end up creating a placeholder. + bool expecting_enum = (proto.type() == FieldDescriptorProto::TYPE_ENUM) || + proto.has_default_value(); + + // In case of weak fields we force building the dependency. We need to know + // if the type exist or not. If it doesn't exist we substitute Empty which + // should only be done if the type can't be found in the generated pool. + // TODO(gerbens) Ideally we should query the database directly to check + // if weak fields exist or not so that we don't need to force building + // weak dependencies. However the name lookup rules for symbols are + // somewhat complicated, so I defer it too another CL. + bool is_weak = !pool_->enforce_weak_ && proto.options().weak(); + bool is_lazy = pool_->lazily_build_dependencies_ && !is_weak; + + Symbol type = + LookupSymbol(proto.type_name(), field->full_name(), + expecting_enum ? DescriptorPool::PLACEHOLDER_ENUM + : DescriptorPool::PLACEHOLDER_MESSAGE, + LOOKUP_TYPES, !is_lazy); + + if (type.IsNull()) { + if (is_lazy) { + // Save the symbol names for later for lookup, and allocate the once + // object needed for the accessors. + TProtoStringType name = proto.type_name(); + field->type_once_ = tables_->Create<internal::once_flag>(); + field->type_descriptor_.lazy_type_name = tables_->Strdup(name); + field->lazy_default_value_enum_name_ = + proto.has_default_value() ? tables_->Strdup(proto.default_value()) + : nullptr; + + // AddFieldByNumber and AddExtension are done later in this function, + // and can/must be done if the field type was not found. The related + // error checking is not necessary when in lazily_build_dependencies_ + // mode, and can't be done without building the type's descriptor, + // which we don't want to do. + file_tables_->AddFieldByNumber(field); + if (field->is_extension()) { + tables_->AddExtension(field); + } + return; + } else { + // If the type is a weak type, we change the type to a google.protobuf.Empty + // field. + if (is_weak) { + type = FindSymbol(kNonLinkedWeakMessageReplacementName); + } + if (type.IsNull()) { + AddNotDefinedError(field->full_name(), proto, + DescriptorPool::ErrorCollector::TYPE, + proto.type_name()); + return; + } + } + } + + if (!proto.has_type()) { + // Choose field type based on symbol. + if (type.type() == Symbol::MESSAGE) { + field->type_ = FieldDescriptor::TYPE_MESSAGE; + } else if (type.type() == Symbol::ENUM) { + field->type_ = FieldDescriptor::TYPE_ENUM; + } else { + AddError(field->full_name(), proto, + DescriptorPool::ErrorCollector::TYPE, + "\"" + proto.type_name() + "\" is not a type."); + return; + } + } + + if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) { + field->type_descriptor_.message_type = type.descriptor(); + if (field->type_descriptor_.message_type == nullptr) { + AddError(field->full_name(), proto, + DescriptorPool::ErrorCollector::TYPE, + "\"" + proto.type_name() + "\" is not a message type."); + return; + } + + if (field->has_default_value()) { + AddError(field->full_name(), proto, + DescriptorPool::ErrorCollector::DEFAULT_VALUE, + "Messages can't have default values."); + } + } else if (field->cpp_type() == FieldDescriptor::CPPTYPE_ENUM) { + field->type_descriptor_.enum_type = type.enum_descriptor(); + if (field->type_descriptor_.enum_type == nullptr) { + AddError(field->full_name(), proto, + DescriptorPool::ErrorCollector::TYPE, + "\"" + proto.type_name() + "\" is not an enum type."); + return; + } + + if (field->enum_type()->is_placeholder_) { + // We can't look up default values for placeholder types. We'll have + // to just drop them. + field->has_default_value_ = false; + } + + if (field->has_default_value()) { + // Ensure that the default value is an identifier. Parser cannot always + // verify this because it does not have complete type information. + // N.B. that this check yields better error messages but is not + // necessary for correctness (an enum symbol must be a valid identifier + // anyway), only for better errors. + if (!io::Tokenizer::IsIdentifier(proto.default_value())) { + AddError(field->full_name(), proto, + DescriptorPool::ErrorCollector::DEFAULT_VALUE, + "Default value for an enum field must be an identifier."); + } else { + // We can't just use field->enum_type()->FindValueByName() here + // because that locks the pool's mutex, which we have already locked + // at this point. + const EnumValueDescriptor* default_value = + LookupSymbolNoPlaceholder(proto.default_value(), + field->enum_type()->full_name()) + .enum_value_descriptor(); + + if (default_value != nullptr && + default_value->type() == field->enum_type()) { + field->default_value_enum_ = default_value; + } else { + AddError(field->full_name(), proto, + DescriptorPool::ErrorCollector::DEFAULT_VALUE, + "Enum type \"" + field->enum_type()->full_name() + + "\" has no value named \"" + proto.default_value() + + "\"."); + } + } + } else if (field->enum_type()->value_count() > 0) { + // All enums must have at least one value, or we would have reported + // an error elsewhere. We use the first defined value as the default + // if a default is not explicitly defined. + field->default_value_enum_ = field->enum_type()->value(0); + } + } else { + AddError(field->full_name(), proto, DescriptorPool::ErrorCollector::TYPE, + "Field with primitive type has type_name."); + } + } else { + if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE || + field->cpp_type() == FieldDescriptor::CPPTYPE_ENUM) { + AddError(field->full_name(), proto, DescriptorPool::ErrorCollector::TYPE, + "Field with message or enum type missing type_name."); + } + } + + // Add the field to the fields-by-number table. + // Note: We have to do this *after* cross-linking because extensions do not + // know their containing type until now. If we're in + // lazily_build_dependencies_ mode, we're guaranteed there's no errors, so no + // risk to calling containing_type() or other accessors that will build + // dependencies. + if (!file_tables_->AddFieldByNumber(field)) { + const FieldDescriptor* conflicting_field = file_tables_->FindFieldByNumber( + field->containing_type(), field->number()); + TProtoStringType containing_type_name = + field->containing_type() == nullptr + ? "unknown" + : field->containing_type()->full_name(); + if (field->is_extension()) { + AddError(field->full_name(), proto, + DescriptorPool::ErrorCollector::NUMBER, + strings::Substitute("Extension number $0 has already been used " + "in \"$1\" by extension \"$2\".", + field->number(), containing_type_name, + conflicting_field->full_name())); + } else { + AddError(field->full_name(), proto, + DescriptorPool::ErrorCollector::NUMBER, + strings::Substitute("Field number $0 has already been used in " + "\"$1\" by field \"$2\".", + field->number(), containing_type_name, + conflicting_field->name())); + } + } else { + if (field->is_extension()) { + if (!tables_->AddExtension(field)) { + const FieldDescriptor* conflicting_field = + tables_->FindExtension(field->containing_type(), field->number()); + TProtoStringType containing_type_name = + field->containing_type() == nullptr + ? "unknown" + : field->containing_type()->full_name(); + TProtoStringType error_msg = strings::Substitute( + "Extension number $0 has already been used in \"$1\" by extension " + "\"$2\" defined in $3.", + field->number(), containing_type_name, + conflicting_field->full_name(), conflicting_field->file()->name()); + // Conflicting extension numbers should be an error. However, before + // turning this into an error we need to fix all existing broken + // protos first. + // TODO(xiaofeng): Change this to an error. + AddWarning(field->full_name(), proto, + DescriptorPool::ErrorCollector::NUMBER, error_msg); + } + } + } +} + +void DescriptorBuilder::CrossLinkEnum(EnumDescriptor* enum_type, + const EnumDescriptorProto& proto) { + if (enum_type->options_ == nullptr) { + enum_type->options_ = &EnumOptions::default_instance(); + } + + for (int i = 0; i < enum_type->value_count(); i++) { + CrossLinkEnumValue(&enum_type->values_[i], proto.value(i)); + } +} + +void DescriptorBuilder::CrossLinkEnumValue( + EnumValueDescriptor* enum_value, + const EnumValueDescriptorProto& /* proto */) { + if (enum_value->options_ == nullptr) { + enum_value->options_ = &EnumValueOptions::default_instance(); + } +} + +void DescriptorBuilder::CrossLinkService(ServiceDescriptor* service, + const ServiceDescriptorProto& proto) { + if (service->options_ == nullptr) { + service->options_ = &ServiceOptions::default_instance(); + } + + for (int i = 0; i < service->method_count(); i++) { + CrossLinkMethod(&service->methods_[i], proto.method(i)); + } +} + +void DescriptorBuilder::CrossLinkMethod(MethodDescriptor* method, + const MethodDescriptorProto& proto) { + if (method->options_ == nullptr) { + method->options_ = &MethodOptions::default_instance(); + } + + Symbol input_type = + LookupSymbol(proto.input_type(), method->full_name(), + DescriptorPool::PLACEHOLDER_MESSAGE, LOOKUP_ALL, + !pool_->lazily_build_dependencies_); + if (input_type.IsNull()) { + if (!pool_->lazily_build_dependencies_) { + AddNotDefinedError(method->full_name(), proto, + DescriptorPool::ErrorCollector::INPUT_TYPE, + proto.input_type()); + } else { + method->input_type_.SetLazy(proto.input_type(), file_); + } + } else if (input_type.type() != Symbol::MESSAGE) { + AddError(method->full_name(), proto, + DescriptorPool::ErrorCollector::INPUT_TYPE, + "\"" + proto.input_type() + "\" is not a message type."); + } else { + method->input_type_.Set(input_type.descriptor()); + } + + Symbol output_type = + LookupSymbol(proto.output_type(), method->full_name(), + DescriptorPool::PLACEHOLDER_MESSAGE, LOOKUP_ALL, + !pool_->lazily_build_dependencies_); + if (output_type.IsNull()) { + if (!pool_->lazily_build_dependencies_) { + AddNotDefinedError(method->full_name(), proto, + DescriptorPool::ErrorCollector::OUTPUT_TYPE, + proto.output_type()); + } else { + method->output_type_.SetLazy(proto.output_type(), file_); + } + } else if (output_type.type() != Symbol::MESSAGE) { + AddError(method->full_name(), proto, + DescriptorPool::ErrorCollector::OUTPUT_TYPE, + "\"" + proto.output_type() + "\" is not a message type."); + } else { + method->output_type_.Set(output_type.descriptor()); + } +} + +// ------------------------------------------------------------------- + +#define VALIDATE_OPTIONS_FROM_ARRAY(descriptor, array_name, type) \ + for (int i = 0; i < descriptor->array_name##_count(); ++i) { \ + Validate##type##Options(descriptor->array_name##s_ + i, \ + proto.array_name(i)); \ + } + +// Determine if the file uses optimize_for = LITE_RUNTIME, being careful to +// avoid problems that exist at init time. +static bool IsLite(const FileDescriptor* file) { + // TODO(kenton): I don't even remember how many of these conditions are + // actually possible. I'm just being super-safe. + return file != nullptr && + &file->options() != &FileOptions::default_instance() && + file->options().optimize_for() == FileOptions::LITE_RUNTIME; +} + +void DescriptorBuilder::ValidateFileOptions(FileDescriptor* file, + const FileDescriptorProto& proto) { + VALIDATE_OPTIONS_FROM_ARRAY(file, message_type, Message); + VALIDATE_OPTIONS_FROM_ARRAY(file, enum_type, Enum); + VALIDATE_OPTIONS_FROM_ARRAY(file, service, Service); + VALIDATE_OPTIONS_FROM_ARRAY(file, extension, Field); + + // Lite files can only be imported by other Lite files. + if (!IsLite(file)) { + for (int i = 0; i < file->dependency_count(); i++) { + if (IsLite(file->dependency(i))) { + AddError( + file->dependency(i)->name(), proto, + DescriptorPool::ErrorCollector::IMPORT, + "Files that do not use optimize_for = LITE_RUNTIME cannot import " + "files which do use this option. This file is not lite, but it " + "imports \"" + + file->dependency(i)->name() + "\" which is."); + break; + } + } + } + if (file->syntax() == FileDescriptor::SYNTAX_PROTO3) { + ValidateProto3(file, proto); + } +} + +void DescriptorBuilder::ValidateProto3(FileDescriptor* file, + const FileDescriptorProto& proto) { + for (int i = 0; i < file->extension_count(); ++i) { + ValidateProto3Field(file->extensions_ + i, proto.extension(i)); + } + for (int i = 0; i < file->message_type_count(); ++i) { + ValidateProto3Message(file->message_types_ + i, proto.message_type(i)); + } + for (int i = 0; i < file->enum_type_count(); ++i) { + ValidateProto3Enum(file->enum_types_ + i, proto.enum_type(i)); + } +} + +static TProtoStringType ToLowercaseWithoutUnderscores(const TProtoStringType& name) { + TProtoStringType result; + for (char character : name) { + if (character != '_') { + if (character >= 'A' && character <= 'Z') { + result.push_back(character - 'A' + 'a'); + } else { + result.push_back(character); + } + } + } + return result; +} + +void DescriptorBuilder::ValidateProto3Message(Descriptor* message, + const DescriptorProto& proto) { + for (int i = 0; i < message->nested_type_count(); ++i) { + ValidateProto3Message(message->nested_types_ + i, proto.nested_type(i)); + } + for (int i = 0; i < message->enum_type_count(); ++i) { + ValidateProto3Enum(message->enum_types_ + i, proto.enum_type(i)); + } + for (int i = 0; i < message->field_count(); ++i) { + ValidateProto3Field(message->fields_ + i, proto.field(i)); + } + for (int i = 0; i < message->extension_count(); ++i) { + ValidateProto3Field(message->extensions_ + i, proto.extension(i)); + } + if (message->extension_range_count() > 0) { + AddError(message->full_name(), proto.extension_range(0), + DescriptorPool::ErrorCollector::NUMBER, + "Extension ranges are not allowed in proto3."); + } + if (message->options().message_set_wire_format()) { + // Using MessageSet doesn't make sense since we disallow extensions. + AddError(message->full_name(), proto, DescriptorPool::ErrorCollector::NAME, + "MessageSet is not supported in proto3."); + } + + // In proto3, we reject field names if they conflict in camelCase. + // Note that we currently enforce a stricter rule: Field names must be + // unique after being converted to lowercase with underscores removed. + std::map<TProtoStringType, const FieldDescriptor*> name_to_field; + for (int i = 0; i < message->field_count(); ++i) { + TProtoStringType lowercase_name = + ToLowercaseWithoutUnderscores(message->field(i)->name()); + if (name_to_field.find(lowercase_name) != name_to_field.end()) { + AddError(message->full_name(), proto.field(i), + DescriptorPool::ErrorCollector::NAME, + "The JSON camel-case name of field \"" + + message->field(i)->name() + "\" conflicts with field \"" + + name_to_field[lowercase_name]->name() + "\". This is not " + + "allowed in proto3."); + } else { + name_to_field[lowercase_name] = message->field(i); + } + } +} + +void DescriptorBuilder::ValidateProto3Field(FieldDescriptor* field, + const FieldDescriptorProto& proto) { + if (field->is_extension() && + !AllowedExtendeeInProto3(field->containing_type()->full_name())) { + AddError(field->full_name(), proto, + DescriptorPool::ErrorCollector::EXTENDEE, + "Extensions in proto3 are only allowed for defining options."); + } + if (field->is_required()) { + AddError(field->full_name(), proto, DescriptorPool::ErrorCollector::TYPE, + "Required fields are not allowed in proto3."); + } + if (field->has_default_value()) { + AddError(field->full_name(), proto, + DescriptorPool::ErrorCollector::DEFAULT_VALUE, + "Explicit default values are not allowed in proto3."); + } + if (field->cpp_type() == FieldDescriptor::CPPTYPE_ENUM && + field->enum_type() && + field->enum_type()->file()->syntax() != FileDescriptor::SYNTAX_PROTO3 && + field->enum_type()->file()->syntax() != FileDescriptor::SYNTAX_UNKNOWN) { + // Proto3 messages can only use Proto3 enum types; otherwise we can't + // guarantee that the default value is zero. + AddError(field->full_name(), proto, DescriptorPool::ErrorCollector::TYPE, + "Enum type \"" + field->enum_type()->full_name() + + "\" is not a proto3 enum, but is used in \"" + + field->containing_type()->full_name() + + "\" which is a proto3 message type."); + } + if (field->type() == FieldDescriptor::TYPE_GROUP) { + AddError(field->full_name(), proto, DescriptorPool::ErrorCollector::TYPE, + "Groups are not supported in proto3 syntax."); + } +} + +void DescriptorBuilder::ValidateProto3Enum(EnumDescriptor* enm, + const EnumDescriptorProto& proto) { + if (enm->value_count() > 0 && enm->value(0)->number() != 0) { + AddError(enm->full_name(), proto.value(0), + DescriptorPool::ErrorCollector::NUMBER, + "The first enum value must be zero in proto3."); + } +} + +void DescriptorBuilder::ValidateMessageOptions(Descriptor* message, + const DescriptorProto& proto) { + VALIDATE_OPTIONS_FROM_ARRAY(message, field, Field); + VALIDATE_OPTIONS_FROM_ARRAY(message, nested_type, Message); + VALIDATE_OPTIONS_FROM_ARRAY(message, enum_type, Enum); + VALIDATE_OPTIONS_FROM_ARRAY(message, extension, Field); + + const arc_i64 max_extension_range = + static_cast<arc_i64>(message->options().message_set_wire_format() + ? std::numeric_limits<arc_i32>::max() + : FieldDescriptor::kMaxNumber); + for (int i = 0; i < message->extension_range_count(); ++i) { + if (message->extension_range(i)->end > max_extension_range + 1) { + AddError(message->full_name(), proto.extension_range(i), + DescriptorPool::ErrorCollector::NUMBER, + strings::Substitute("Extension numbers cannot be greater than $0.", + max_extension_range)); + } + + ValidateExtensionRangeOptions(message->full_name(), + message->extension_ranges_ + i, + proto.extension_range(i)); + } +} + + +void DescriptorBuilder::ValidateFieldOptions( + FieldDescriptor* field, const FieldDescriptorProto& proto) { + if (pool_->lazily_build_dependencies_ && (!field || !field->message_type())) { + return; + } + // Only message type fields may be lazy. + if (field->options().lazy()) { + if (field->type() != FieldDescriptor::TYPE_MESSAGE) { + AddError(field->full_name(), proto, DescriptorPool::ErrorCollector::TYPE, + "[lazy = true] can only be specified for submessage fields."); + } + } + + // Only repeated primitive fields may be packed. + if (field->options().packed() && !field->is_packable()) { + AddError( + field->full_name(), proto, DescriptorPool::ErrorCollector::TYPE, + "[packed = true] can only be specified for repeated primitive fields."); + } + + // Note: Default instance may not yet be initialized here, so we have to + // avoid reading from it. + if (field->containing_type_ != nullptr && + &field->containing_type()->options() != + &MessageOptions::default_instance() && + field->containing_type()->options().message_set_wire_format()) { + if (field->is_extension()) { + if (!field->is_optional() || + field->type() != FieldDescriptor::TYPE_MESSAGE) { + AddError(field->full_name(), proto, + DescriptorPool::ErrorCollector::TYPE, + "Extensions of MessageSets must be optional messages."); + } + } else { + AddError(field->full_name(), proto, DescriptorPool::ErrorCollector::NAME, + "MessageSets cannot have fields, only extensions."); + } + } + + // Lite extensions can only be of Lite types. + if (IsLite(field->file()) && field->containing_type_ != nullptr && + !IsLite(field->containing_type()->file())) { + AddError(field->full_name(), proto, + DescriptorPool::ErrorCollector::EXTENDEE, + "Extensions to non-lite types can only be declared in non-lite " + "files. Note that you cannot extend a non-lite type to contain " + "a lite type, but the reverse is allowed."); + } + + // Validate map types. + if (field->is_map()) { + if (!ValidateMapEntry(field, proto)) { + AddError(field->full_name(), proto, DescriptorPool::ErrorCollector::TYPE, + "map_entry should not be set explicitly. Use map<KeyType, " + "ValueType> instead."); + } + } + + ValidateJSType(field, proto); + + // json_name option is not allowed on extension fields. Note that the + // json_name field in FieldDescriptorProto is always populated by protoc + // when it sends descriptor data to plugins (calculated from field name if + // the option is not explicitly set) so we can't rely on its presence to + // determine whether the json_name option is set on the field. Here we + // compare it against the default calculated json_name value and consider + // the option set if they are different. This won't catch the case when + // an user explicitly sets json_name to the default value, but should be + // good enough to catch common misuses. + if (field->is_extension() && + (field->has_json_name() && + field->json_name() != ToJsonName(field->name()))) { + AddError(field->full_name(), proto, + DescriptorPool::ErrorCollector::OPTION_NAME, + "option json_name is not allowed on extension fields."); + } + +} + +void DescriptorBuilder::ValidateEnumOptions(EnumDescriptor* enm, + const EnumDescriptorProto& proto) { + VALIDATE_OPTIONS_FROM_ARRAY(enm, value, EnumValue); + if (!enm->options().has_allow_alias() || !enm->options().allow_alias()) { + std::map<int, TProtoStringType> used_values; + for (int i = 0; i < enm->value_count(); ++i) { + const EnumValueDescriptor* enum_value = enm->value(i); + if (used_values.find(enum_value->number()) != used_values.end()) { + TProtoStringType error = + "\"" + enum_value->full_name() + + "\" uses the same enum value as \"" + + used_values[enum_value->number()] + + "\". If this is intended, set " + "'option allow_alias = true;' to the enum definition."; + if (!enm->options().allow_alias()) { + // Generate error if duplicated enum values are explicitly disallowed. + AddError(enm->full_name(), proto.value(i), + DescriptorPool::ErrorCollector::NUMBER, error); + } + } else { + used_values[enum_value->number()] = enum_value->full_name(); + } + } + } +} + +void DescriptorBuilder::ValidateEnumValueOptions( + EnumValueDescriptor* /* enum_value */, + const EnumValueDescriptorProto& /* proto */) { + // Nothing to do so far. +} + +void DescriptorBuilder::ValidateExtensionRangeOptions( + const TProtoStringType& full_name, Descriptor::ExtensionRange* extension_range, + const DescriptorProto_ExtensionRange& proto) { + (void)full_name; // Parameter is used by Google-internal code. + (void)extension_range; // Parameter is used by Google-internal code. +} + +void DescriptorBuilder::ValidateServiceOptions( + ServiceDescriptor* service, const ServiceDescriptorProto& proto) { + if (IsLite(service->file()) && + (service->file()->options().cc_generic_services() || + service->file()->options().java_generic_services())) { + AddError(service->full_name(), proto, DescriptorPool::ErrorCollector::NAME, + "Files with optimize_for = LITE_RUNTIME cannot define services " + "unless you set both options cc_generic_services and " + "java_generic_services to false."); + } + + VALIDATE_OPTIONS_FROM_ARRAY(service, method, Method); +} + +void DescriptorBuilder::ValidateMethodOptions( + MethodDescriptor* /* method */, const MethodDescriptorProto& /* proto */) { + // Nothing to do so far. +} + +bool DescriptorBuilder::ValidateMapEntry(FieldDescriptor* field, + const FieldDescriptorProto& proto) { + const Descriptor* message = field->message_type(); + if ( // Must not contain extensions, extension range or nested message or + // enums + message->extension_count() != 0 || + field->label() != FieldDescriptor::LABEL_REPEATED || + message->extension_range_count() != 0 || + message->nested_type_count() != 0 || message->enum_type_count() != 0 || + // Must contain exactly two fields + message->field_count() != 2 || + // Field name and message name must match + message->name() != ToCamelCase(field->name(), false) + "Entry" || + // Entry message must be in the same containing type of the field. + field->containing_type() != message->containing_type()) { + return false; + } + + const FieldDescriptor* key = message->map_key(); + const FieldDescriptor* value = message->map_value(); + if (key->label() != FieldDescriptor::LABEL_OPTIONAL || key->number() != 1 || + key->name() != "key") { + return false; + } + if (value->label() != FieldDescriptor::LABEL_OPTIONAL || + value->number() != 2 || value->name() != "value") { + return false; + } + + // Check key types are legal. + switch (key->type()) { + case FieldDescriptor::TYPE_ENUM: + AddError(field->full_name(), proto, DescriptorPool::ErrorCollector::TYPE, + "Key in map fields cannot be enum types."); + break; + case FieldDescriptor::TYPE_FLOAT: + case FieldDescriptor::TYPE_DOUBLE: + case FieldDescriptor::TYPE_MESSAGE: + case FieldDescriptor::TYPE_GROUP: + case FieldDescriptor::TYPE_BYTES: + AddError( + field->full_name(), proto, DescriptorPool::ErrorCollector::TYPE, + "Key in map fields cannot be float/double, bytes or message types."); + break; + case FieldDescriptor::TYPE_BOOL: + case FieldDescriptor::TYPE_INT32: + case FieldDescriptor::TYPE_INT64: + case FieldDescriptor::TYPE_SINT32: + case FieldDescriptor::TYPE_SINT64: + case FieldDescriptor::TYPE_STRING: + case FieldDescriptor::TYPE_UINT32: + case FieldDescriptor::TYPE_UINT64: + case FieldDescriptor::TYPE_FIXED32: + case FieldDescriptor::TYPE_FIXED64: + case FieldDescriptor::TYPE_SFIXED32: + case FieldDescriptor::TYPE_SFIXED64: + // Legal cases + break; + // Do not add a default, so that the compiler will complain when new types + // are added. + } + + if (value->type() == FieldDescriptor::TYPE_ENUM) { + if (value->enum_type()->value(0)->number() != 0) { + AddError(field->full_name(), proto, DescriptorPool::ErrorCollector::TYPE, + "Enum value in map must define 0 as the first value."); + } + } + + return true; +} + +void DescriptorBuilder::DetectMapConflicts(const Descriptor* message, + const DescriptorProto& proto) { + std::map<TProtoStringType, const Descriptor*> seen_types; + for (int i = 0; i < message->nested_type_count(); ++i) { + const Descriptor* nested = message->nested_type(i); + std::pair<std::map<TProtoStringType, const Descriptor*>::iterator, bool> result = + seen_types.insert(std::make_pair(nested->name(), nested)); + if (!result.second) { + if (result.first->second->options().map_entry() || + nested->options().map_entry()) { + AddError(message->full_name(), proto, + DescriptorPool::ErrorCollector::NAME, + "Expanded map entry type " + nested->name() + + " conflicts with an existing nested message type."); + } + } + // Recursively test on the nested types. + DetectMapConflicts(message->nested_type(i), proto.nested_type(i)); + } + // Check for conflicted field names. + for (int i = 0; i < message->field_count(); ++i) { + const FieldDescriptor* field = message->field(i); + std::map<TProtoStringType, const Descriptor*>::iterator iter = + seen_types.find(field->name()); + if (iter != seen_types.end() && iter->second->options().map_entry()) { + AddError(message->full_name(), proto, + DescriptorPool::ErrorCollector::NAME, + "Expanded map entry type " + iter->second->name() + + " conflicts with an existing field."); + } + } + // Check for conflicted enum names. + for (int i = 0; i < message->enum_type_count(); ++i) { + const EnumDescriptor* enum_desc = message->enum_type(i); + std::map<TProtoStringType, const Descriptor*>::iterator iter = + seen_types.find(enum_desc->name()); + if (iter != seen_types.end() && iter->second->options().map_entry()) { + AddError(message->full_name(), proto, + DescriptorPool::ErrorCollector::NAME, + "Expanded map entry type " + iter->second->name() + + " conflicts with an existing enum type."); + } + } + // Check for conflicted oneof names. + for (int i = 0; i < message->oneof_decl_count(); ++i) { + const OneofDescriptor* oneof_desc = message->oneof_decl(i); + std::map<TProtoStringType, const Descriptor*>::iterator iter = + seen_types.find(oneof_desc->name()); + if (iter != seen_types.end() && iter->second->options().map_entry()) { + AddError(message->full_name(), proto, + DescriptorPool::ErrorCollector::NAME, + "Expanded map entry type " + iter->second->name() + + " conflicts with an existing oneof type."); + } + } +} + +void DescriptorBuilder::ValidateJSType(FieldDescriptor* field, + const FieldDescriptorProto& proto) { + FieldOptions::JSType jstype = field->options().jstype(); + // The default is always acceptable. + if (jstype == FieldOptions::JS_NORMAL) { + return; + } + + switch (field->type()) { + // Integral 64-bit types may be represented as JavaScript numbers or + // strings. + case FieldDescriptor::TYPE_UINT64: + case FieldDescriptor::TYPE_INT64: + case FieldDescriptor::TYPE_SINT64: + case FieldDescriptor::TYPE_FIXED64: + case FieldDescriptor::TYPE_SFIXED64: + if (jstype == FieldOptions::JS_STRING || + jstype == FieldOptions::JS_NUMBER) { + return; + } + AddError(field->full_name(), proto, DescriptorPool::ErrorCollector::TYPE, + "Illegal jstype for int64, uint64, sint64, fixed64 " + "or sfixed64 field: " + + FieldOptions_JSType_descriptor()->value(jstype)->name()); + break; + + // No other types permit a jstype option. + default: + AddError(field->full_name(), proto, DescriptorPool::ErrorCollector::TYPE, + "jstype is only allowed on int64, uint64, sint64, fixed64 " + "or sfixed64 fields."); + break; + } +} + +#undef VALIDATE_OPTIONS_FROM_ARRAY + +// ------------------------------------------------------------------- + +DescriptorBuilder::OptionInterpreter::OptionInterpreter( + DescriptorBuilder* builder) + : builder_(builder) { + GOOGLE_CHECK(builder_); +} + +DescriptorBuilder::OptionInterpreter::~OptionInterpreter() {} + +bool DescriptorBuilder::OptionInterpreter::InterpretOptions( + OptionsToInterpret* options_to_interpret) { + // Note that these may be in different pools, so we can't use the same + // descriptor and reflection objects on both. + Message* options = options_to_interpret->options; + const Message* original_options = options_to_interpret->original_options; + + bool failed = false; + options_to_interpret_ = options_to_interpret; + + // Find the uninterpreted_option field in the mutable copy of the options + // and clear them, since we're about to interpret them. + const FieldDescriptor* uninterpreted_options_field = + options->GetDescriptor()->FindFieldByName("uninterpreted_option"); + GOOGLE_CHECK(uninterpreted_options_field != nullptr) + << "No field named \"uninterpreted_option\" in the Options proto."; + options->GetReflection()->ClearField(options, uninterpreted_options_field); + + std::vector<int> src_path = options_to_interpret->element_path; + src_path.push_back(uninterpreted_options_field->number()); + + // Find the uninterpreted_option field in the original options. + const FieldDescriptor* original_uninterpreted_options_field = + original_options->GetDescriptor()->FindFieldByName( + "uninterpreted_option"); + GOOGLE_CHECK(original_uninterpreted_options_field != nullptr) + << "No field named \"uninterpreted_option\" in the Options proto."; + + const int num_uninterpreted_options = + original_options->GetReflection()->FieldSize( + *original_options, original_uninterpreted_options_field); + for (int i = 0; i < num_uninterpreted_options; ++i) { + src_path.push_back(i); + uninterpreted_option_ = down_cast<const UninterpretedOption*>( + &original_options->GetReflection()->GetRepeatedMessage( + *original_options, original_uninterpreted_options_field, i)); + if (!InterpretSingleOption(options, src_path, + options_to_interpret->element_path)) { + // Error already added by InterpretSingleOption(). + failed = true; + break; + } + src_path.pop_back(); + } + // Reset these, so we don't have any dangling pointers. + uninterpreted_option_ = nullptr; + options_to_interpret_ = nullptr; + + if (!failed) { + // InterpretSingleOption() added the interpreted options in the + // UnknownFieldSet, in case the option isn't yet known to us. Now we + // serialize the options message and deserialize it back. That way, any + // option fields that we do happen to know about will get moved from the + // UnknownFieldSet into the real fields, and thus be available right away. + // If they are not known, that's OK too. They will get reparsed into the + // UnknownFieldSet and wait there until the message is parsed by something + // that does know about the options. + + // Keep the unparsed options around in case the reparsing fails. + std::unique_ptr<Message> unparsed_options(options->New()); + options->GetReflection()->Swap(unparsed_options.get(), options); + + TProtoStringType buf; + if (!unparsed_options->AppendToString(&buf) || + !options->ParseFromString(buf)) { + builder_->AddError( + options_to_interpret->element_name, *original_options, + DescriptorPool::ErrorCollector::OTHER, + "Some options could not be correctly parsed using the proto " + "descriptors compiled into this binary.\n" + "Unparsed options: " + + unparsed_options->ShortDebugString() + + "\n" + "Parsing attempt: " + + options->ShortDebugString()); + // Restore the unparsed options. + options->GetReflection()->Swap(unparsed_options.get(), options); + } + } + + return !failed; +} + +bool DescriptorBuilder::OptionInterpreter::InterpretSingleOption( + Message* options, const std::vector<int>& src_path, + const std::vector<int>& options_path) { + // First do some basic validation. + if (uninterpreted_option_->name_size() == 0) { + // This should never happen unless the parser has gone seriously awry or + // someone has manually created the uninterpreted option badly. + return AddNameError("Option must have a name."); + } + if (uninterpreted_option_->name(0).name_part() == "uninterpreted_option") { + return AddNameError( + "Option must not use reserved name " + "\"uninterpreted_option\"."); + } + + const Descriptor* options_descriptor = nullptr; + // Get the options message's descriptor from the builder's pool, so that we + // get the version that knows about any extension options declared in the file + // we're currently building. The descriptor should be there as long as the + // file we're building imported descriptor.proto. + + // Note that we use DescriptorBuilder::FindSymbolNotEnforcingDeps(), not + // DescriptorPool::FindMessageTypeByName() because we're already holding the + // pool's mutex, and the latter method locks it again. We don't use + // FindSymbol() because files that use custom options only need to depend on + // the file that defines the option, not descriptor.proto itself. + Symbol symbol = builder_->FindSymbolNotEnforcingDeps( + options->GetDescriptor()->full_name()); + options_descriptor = symbol.descriptor(); + if (options_descriptor == nullptr) { + // The options message's descriptor was not in the builder's pool, so use + // the standard version from the generated pool. We're not holding the + // generated pool's mutex, so we can search it the straightforward way. + options_descriptor = options->GetDescriptor(); + } + GOOGLE_CHECK(options_descriptor); + + // We iterate over the name parts to drill into the submessages until we find + // the leaf field for the option. As we drill down we remember the current + // submessage's descriptor in |descriptor| and the next field in that + // submessage in |field|. We also track the fields we're drilling down + // through in |intermediate_fields|. As we go, we reconstruct the full option + // name in |debug_msg_name|, for use in error messages. + const Descriptor* descriptor = options_descriptor; + const FieldDescriptor* field = nullptr; + std::vector<const FieldDescriptor*> intermediate_fields; + TProtoStringType debug_msg_name = ""; + + std::vector<int> dest_path = options_path; + + for (int i = 0; i < uninterpreted_option_->name_size(); ++i) { + builder_->undefine_resolved_name_.clear(); + const TProtoStringType& name_part = uninterpreted_option_->name(i).name_part(); + if (debug_msg_name.size() > 0) { + debug_msg_name += "."; + } + if (uninterpreted_option_->name(i).is_extension()) { + debug_msg_name += "(" + name_part + ")"; + // Search for the extension's descriptor as an extension in the builder's + // pool. Note that we use DescriptorBuilder::LookupSymbol(), not + // DescriptorPool::FindExtensionByName(), for two reasons: 1) It allows + // relative lookups, and 2) because we're already holding the pool's + // mutex, and the latter method locks it again. + symbol = + builder_->LookupSymbol(name_part, options_to_interpret_->name_scope); + field = symbol.field_descriptor(); + // If we don't find the field then the field's descriptor was not in the + // builder's pool, but there's no point in looking in the generated + // pool. We require that you import the file that defines any extensions + // you use, so they must be present in the builder's pool. + } else { + debug_msg_name += name_part; + // Search for the field's descriptor as a regular field. + field = descriptor->FindFieldByName(name_part); + } + + if (field == nullptr) { + if (get_allow_unknown(builder_->pool_)) { + // We can't find the option, but AllowUnknownDependencies() is enabled, + // so we will just leave it as uninterpreted. + AddWithoutInterpreting(*uninterpreted_option_, options); + return true; + } else if (!(builder_->undefine_resolved_name_).empty()) { + // Option is resolved to a name which is not defined. + return AddNameError( + "Option \"" + debug_msg_name + "\" is resolved to \"(" + + builder_->undefine_resolved_name_ + + ")\", which is not defined. The innermost scope is searched first " + "in name resolution. Consider using a leading '.'(i.e., \"(." + + debug_msg_name.substr(1) + + "\") to start from the outermost scope."); + } else { + return AddNameError( + "Option \"" + debug_msg_name + + "\" unknown. Ensure that your proto" + + " definition file imports the proto which defines the option."); + } + } else if (field->containing_type() != descriptor) { + if (get_is_placeholder(field->containing_type())) { + // The field is an extension of a placeholder type, so we can't + // reliably verify whether it is a valid extension to use here (e.g. + // we don't know if it is an extension of the correct *Options message, + // or if it has a valid field number, etc.). Just leave it as + // uninterpreted instead. + AddWithoutInterpreting(*uninterpreted_option_, options); + return true; + } else { + // This can only happen if, due to some insane misconfiguration of the + // pools, we find the options message in one pool but the field in + // another. This would probably imply a hefty bug somewhere. + return AddNameError("Option field \"" + debug_msg_name + + "\" is not a field or extension of message \"" + + descriptor->name() + "\"."); + } + } else { + // accumulate field numbers to form path to interpreted option + dest_path.push_back(field->number()); + + if (i < uninterpreted_option_->name_size() - 1) { + if (field->cpp_type() != FieldDescriptor::CPPTYPE_MESSAGE) { + return AddNameError("Option \"" + debug_msg_name + + "\" is an atomic type, not a message."); + } else if (field->is_repeated()) { + return AddNameError("Option field \"" + debug_msg_name + + "\" is a repeated message. Repeated message " + "options must be initialized using an " + "aggregate value."); + } else { + // Drill down into the submessage. + intermediate_fields.push_back(field); + descriptor = field->message_type(); + } + } + } + } + + // We've found the leaf field. Now we use UnknownFieldSets to set its value + // on the options message. We do so because the message may not yet know + // about its extension fields, so we may not be able to set the fields + // directly. But the UnknownFieldSets will serialize to the same wire-format + // message, so reading that message back in once the extension fields are + // known will populate them correctly. + + // First see if the option is already set. + if (!field->is_repeated() && + !ExamineIfOptionIsSet( + intermediate_fields.begin(), intermediate_fields.end(), field, + debug_msg_name, + options->GetReflection()->GetUnknownFields(*options))) { + return false; // ExamineIfOptionIsSet() already added the error. + } + + // First set the value on the UnknownFieldSet corresponding to the + // innermost message. + std::unique_ptr<UnknownFieldSet> unknown_fields(new UnknownFieldSet()); + if (!SetOptionValue(field, unknown_fields.get())) { + return false; // SetOptionValue() already added the error. + } + + // Now wrap the UnknownFieldSet with UnknownFieldSets corresponding to all + // the intermediate messages. + for (std::vector<const FieldDescriptor*>::reverse_iterator iter = + intermediate_fields.rbegin(); + iter != intermediate_fields.rend(); ++iter) { + std::unique_ptr<UnknownFieldSet> parent_unknown_fields( + new UnknownFieldSet()); + switch ((*iter)->type()) { + case FieldDescriptor::TYPE_MESSAGE: { + io::StringOutputStream outstr( + parent_unknown_fields->AddLengthDelimited((*iter)->number())); + io::CodedOutputStream out(&outstr); + internal::WireFormat::SerializeUnknownFields(*unknown_fields, &out); + GOOGLE_CHECK(!out.HadError()) + << "Unexpected failure while serializing option submessage " + << debug_msg_name << "\"."; + break; + } + + case FieldDescriptor::TYPE_GROUP: { + parent_unknown_fields->AddGroup((*iter)->number()) + ->MergeFrom(*unknown_fields); + break; + } + + default: + GOOGLE_LOG(FATAL) << "Invalid wire type for CPPTYPE_MESSAGE: " + << (*iter)->type(); + return false; + } + unknown_fields.reset(parent_unknown_fields.release()); + } + + // Now merge the UnknownFieldSet corresponding to the top-level message into + // the options message. + options->GetReflection()->MutableUnknownFields(options)->MergeFrom( + *unknown_fields); + + // record the element path of the interpreted option + if (field->is_repeated()) { + int index = repeated_option_counts_[dest_path]++; + dest_path.push_back(index); + } + interpreted_paths_[src_path] = dest_path; + + return true; +} + +void DescriptorBuilder::OptionInterpreter::UpdateSourceCodeInfo( + SourceCodeInfo* info) { + if (interpreted_paths_.empty()) { + // nothing to do! + return; + } + + // We find locations that match keys in interpreted_paths_ and + // 1) replace the path with the corresponding value in interpreted_paths_ + // 2) remove any subsequent sub-locations (sub-location is one whose path + // has the parent path as a prefix) + // + // To avoid quadratic behavior of removing interior rows as we go, + // we keep a copy. But we don't actually copy anything until we've + // found the first match (so if the source code info has no locations + // that need to be changed, there is zero copy overhead). + + RepeatedPtrField<SourceCodeInfo_Location>* locs = info->mutable_location(); + RepeatedPtrField<SourceCodeInfo_Location> new_locs; + bool copying = false; + + std::vector<int> pathv; + bool matched = false; + + for (RepeatedPtrField<SourceCodeInfo_Location>::iterator loc = locs->begin(); + loc != locs->end(); loc++) { + if (matched) { + // see if this location is in the range to remove + bool loc_matches = true; + if (loc->path_size() < static_cast<arc_i64>(pathv.size())) { + loc_matches = false; + } else { + for (size_t j = 0; j < pathv.size(); j++) { + if (loc->path(j) != pathv[j]) { + loc_matches = false; + break; + } + } + } + + if (loc_matches) { + // don't copy this row since it is a sub-location that we're removing + continue; + } + + matched = false; + } + + pathv.clear(); + for (int j = 0; j < loc->path_size(); j++) { + pathv.push_back(loc->path(j)); + } + + std::map<std::vector<int>, std::vector<int>>::iterator entry = + interpreted_paths_.find(pathv); + + if (entry == interpreted_paths_.end()) { + // not a match + if (copying) { + *new_locs.Add() = *loc; + } + continue; + } + + matched = true; + + if (!copying) { + // initialize the copy we are building + copying = true; + new_locs.Reserve(locs->size()); + for (RepeatedPtrField<SourceCodeInfo_Location>::iterator it = + locs->begin(); + it != loc; it++) { + *new_locs.Add() = *it; + } + } + + // add replacement and update its path + SourceCodeInfo_Location* replacement = new_locs.Add(); + *replacement = *loc; + replacement->clear_path(); + for (std::vector<int>::iterator rit = entry->second.begin(); + rit != entry->second.end(); rit++) { + replacement->add_path(*rit); + } + } + + // if we made a changed copy, put it in place + if (copying) { + *locs = new_locs; + } +} + +void DescriptorBuilder::OptionInterpreter::AddWithoutInterpreting( + const UninterpretedOption& uninterpreted_option, Message* options) { + const FieldDescriptor* field = + options->GetDescriptor()->FindFieldByName("uninterpreted_option"); + GOOGLE_CHECK(field != nullptr); + + options->GetReflection() + ->AddMessage(options, field) + ->CopyFrom(uninterpreted_option); +} + +bool DescriptorBuilder::OptionInterpreter::ExamineIfOptionIsSet( + std::vector<const FieldDescriptor*>::const_iterator + intermediate_fields_iter, + std::vector<const FieldDescriptor*>::const_iterator intermediate_fields_end, + const FieldDescriptor* innermost_field, const TProtoStringType& debug_msg_name, + const UnknownFieldSet& unknown_fields) { + // We do linear searches of the UnknownFieldSet and its sub-groups. This + // should be fine since it's unlikely that any one options structure will + // contain more than a handful of options. + + if (intermediate_fields_iter == intermediate_fields_end) { + // We're at the innermost submessage. + for (int i = 0; i < unknown_fields.field_count(); i++) { + if (unknown_fields.field(i).number() == innermost_field->number()) { + return AddNameError("Option \"" + debug_msg_name + + "\" was already set."); + } + } + return true; + } + + for (int i = 0; i < unknown_fields.field_count(); i++) { + if (unknown_fields.field(i).number() == + (*intermediate_fields_iter)->number()) { + const UnknownField* unknown_field = &unknown_fields.field(i); + FieldDescriptor::Type type = (*intermediate_fields_iter)->type(); + // Recurse into the next submessage. + switch (type) { + case FieldDescriptor::TYPE_MESSAGE: + if (unknown_field->type() == UnknownField::TYPE_LENGTH_DELIMITED) { + UnknownFieldSet intermediate_unknown_fields; + if (intermediate_unknown_fields.ParseFromString( + unknown_field->length_delimited()) && + !ExamineIfOptionIsSet(intermediate_fields_iter + 1, + intermediate_fields_end, innermost_field, + debug_msg_name, + intermediate_unknown_fields)) { + return false; // Error already added. + } + } + break; + + case FieldDescriptor::TYPE_GROUP: + if (unknown_field->type() == UnknownField::TYPE_GROUP) { + if (!ExamineIfOptionIsSet(intermediate_fields_iter + 1, + intermediate_fields_end, innermost_field, + debug_msg_name, unknown_field->group())) { + return false; // Error already added. + } + } + break; + + default: + GOOGLE_LOG(FATAL) << "Invalid wire type for CPPTYPE_MESSAGE: " << type; + return false; + } + } + } + return true; +} + +bool DescriptorBuilder::OptionInterpreter::SetOptionValue( + const FieldDescriptor* option_field, UnknownFieldSet* unknown_fields) { + // We switch on the CppType to validate. + switch (option_field->cpp_type()) { + case FieldDescriptor::CPPTYPE_INT32: + if (uninterpreted_option_->has_positive_int_value()) { + if (uninterpreted_option_->positive_int_value() > + static_cast<arc_ui64>(std::numeric_limits<arc_i32>::max())) { + return AddValueError("Value out of range for int32 option \"" + + option_field->full_name() + "\"."); + } else { + SetInt32(option_field->number(), + uninterpreted_option_->positive_int_value(), + option_field->type(), unknown_fields); + } + } else if (uninterpreted_option_->has_negative_int_value()) { + if (uninterpreted_option_->negative_int_value() < + static_cast<arc_i64>(std::numeric_limits<arc_i32>::min())) { + return AddValueError("Value out of range for int32 option \"" + + option_field->full_name() + "\"."); + } else { + SetInt32(option_field->number(), + uninterpreted_option_->negative_int_value(), + option_field->type(), unknown_fields); + } + } else { + return AddValueError("Value must be integer for int32 option \"" + + option_field->full_name() + "\"."); + } + break; + + case FieldDescriptor::CPPTYPE_INT64: + if (uninterpreted_option_->has_positive_int_value()) { + if (uninterpreted_option_->positive_int_value() > + static_cast<arc_ui64>(std::numeric_limits<arc_i64>::max())) { + return AddValueError("Value out of range for int64 option \"" + + option_field->full_name() + "\"."); + } else { + SetInt64(option_field->number(), + uninterpreted_option_->positive_int_value(), + option_field->type(), unknown_fields); + } + } else if (uninterpreted_option_->has_negative_int_value()) { + SetInt64(option_field->number(), + uninterpreted_option_->negative_int_value(), + option_field->type(), unknown_fields); + } else { + return AddValueError("Value must be integer for int64 option \"" + + option_field->full_name() + "\"."); + } + break; + + case FieldDescriptor::CPPTYPE_UINT32: + if (uninterpreted_option_->has_positive_int_value()) { + if (uninterpreted_option_->positive_int_value() > + std::numeric_limits<arc_ui32>::max()) { + return AddValueError("Value out of range for uint32 option \"" + + option_field->name() + "\"."); + } else { + SetUInt32(option_field->number(), + uninterpreted_option_->positive_int_value(), + option_field->type(), unknown_fields); + } + } else { + return AddValueError( + "Value must be non-negative integer for uint32 " + "option \"" + + option_field->full_name() + "\"."); + } + break; + + case FieldDescriptor::CPPTYPE_UINT64: + if (uninterpreted_option_->has_positive_int_value()) { + SetUInt64(option_field->number(), + uninterpreted_option_->positive_int_value(), + option_field->type(), unknown_fields); + } else { + return AddValueError( + "Value must be non-negative integer for uint64 " + "option \"" + + option_field->full_name() + "\"."); + } + break; + + case FieldDescriptor::CPPTYPE_FLOAT: { + float value; + if (uninterpreted_option_->has_double_value()) { + value = uninterpreted_option_->double_value(); + } else if (uninterpreted_option_->has_positive_int_value()) { + value = uninterpreted_option_->positive_int_value(); + } else if (uninterpreted_option_->has_negative_int_value()) { + value = uninterpreted_option_->negative_int_value(); + } else { + return AddValueError("Value must be number for float option \"" + + option_field->full_name() + "\"."); + } + unknown_fields->AddFixed32(option_field->number(), + internal::WireFormatLite::EncodeFloat(value)); + break; + } + + case FieldDescriptor::CPPTYPE_DOUBLE: { + double value; + if (uninterpreted_option_->has_double_value()) { + value = uninterpreted_option_->double_value(); + } else if (uninterpreted_option_->has_positive_int_value()) { + value = uninterpreted_option_->positive_int_value(); + } else if (uninterpreted_option_->has_negative_int_value()) { + value = uninterpreted_option_->negative_int_value(); + } else { + return AddValueError("Value must be number for double option \"" + + option_field->full_name() + "\"."); + } + unknown_fields->AddFixed64(option_field->number(), + internal::WireFormatLite::EncodeDouble(value)); + break; + } + + case FieldDescriptor::CPPTYPE_BOOL: + arc_ui64 value; + if (!uninterpreted_option_->has_identifier_value()) { + return AddValueError( + "Value must be identifier for boolean option " + "\"" + + option_field->full_name() + "\"."); + } + if (uninterpreted_option_->identifier_value() == "true") { + value = 1; + } else if (uninterpreted_option_->identifier_value() == "false") { + value = 0; + } else { + return AddValueError( + "Value must be \"true\" or \"false\" for boolean " + "option \"" + + option_field->full_name() + "\"."); + } + unknown_fields->AddVarint(option_field->number(), value); + break; + + case FieldDescriptor::CPPTYPE_ENUM: { + if (!uninterpreted_option_->has_identifier_value()) { + return AddValueError( + "Value must be identifier for enum-valued option " + "\"" + + option_field->full_name() + "\"."); + } + const EnumDescriptor* enum_type = option_field->enum_type(); + const TProtoStringType& value_name = uninterpreted_option_->identifier_value(); + const EnumValueDescriptor* enum_value = nullptr; + + if (enum_type->file()->pool() != DescriptorPool::generated_pool()) { + // Note that the enum value's fully-qualified name is a sibling of the + // enum's name, not a child of it. + TProtoStringType fully_qualified_name = enum_type->full_name(); + fully_qualified_name.resize(fully_qualified_name.size() - + enum_type->name().size()); + fully_qualified_name += value_name; + + // Search for the enum value's descriptor in the builder's pool. Note + // that we use DescriptorBuilder::FindSymbolNotEnforcingDeps(), not + // DescriptorPool::FindEnumValueByName() because we're already holding + // the pool's mutex, and the latter method locks it again. + Symbol symbol = + builder_->FindSymbolNotEnforcingDeps(fully_qualified_name); + if (auto* candicate_descriptor = symbol.enum_value_descriptor()) { + if (candicate_descriptor->type() != enum_type) { + return AddValueError( + "Enum type \"" + enum_type->full_name() + + "\" has no value named \"" + value_name + "\" for option \"" + + option_field->full_name() + + "\". This appears to be a value from a sibling type."); + } else { + enum_value = candicate_descriptor; + } + } + } else { + // The enum type is in the generated pool, so we can search for the + // value there. + enum_value = enum_type->FindValueByName(value_name); + } + + if (enum_value == nullptr) { + return AddValueError("Enum type \"" + + option_field->enum_type()->full_name() + + "\" has no value named \"" + value_name + + "\" for " + "option \"" + + option_field->full_name() + "\"."); + } else { + // Sign-extension is not a problem, since we cast directly from arc_i32 + // to arc_ui64, without first going through arc_ui32. + unknown_fields->AddVarint( + option_field->number(), + static_cast<arc_ui64>(static_cast<arc_i64>(enum_value->number()))); + } + break; + } + + case FieldDescriptor::CPPTYPE_STRING: + if (!uninterpreted_option_->has_string_value()) { + return AddValueError( + "Value must be quoted string for string option " + "\"" + + option_field->full_name() + "\"."); + } + // The string has already been unquoted and unescaped by the parser. + unknown_fields->AddLengthDelimited(option_field->number(), + uninterpreted_option_->string_value()); + break; + + case FieldDescriptor::CPPTYPE_MESSAGE: + if (!SetAggregateOption(option_field, unknown_fields)) { + return false; + } + break; + } + + return true; +} + +class DescriptorBuilder::OptionInterpreter::AggregateOptionFinder + : public TextFormat::Finder { + public: + DescriptorBuilder* builder_; + + const Descriptor* FindAnyType(const Message& /*message*/, + const TProtoStringType& prefix, + const TProtoStringType& name) const override { + if (prefix != internal::kTypeGoogleApisComPrefix && + prefix != internal::kTypeGoogleProdComPrefix) { + return nullptr; + } + assert_mutex_held(builder_->pool_); + return builder_->FindSymbol(name).descriptor(); + } + + const FieldDescriptor* FindExtension(Message* message, + const TProtoStringType& name) const override { + assert_mutex_held(builder_->pool_); + const Descriptor* descriptor = message->GetDescriptor(); + Symbol result = + builder_->LookupSymbolNoPlaceholder(name, descriptor->full_name()); + if (auto* field = result.field_descriptor()) { + return field; + } else if (result.type() == Symbol::MESSAGE && + descriptor->options().message_set_wire_format()) { + const Descriptor* foreign_type = result.descriptor(); + // The text format allows MessageSet items to be specified using + // the type name, rather than the extension identifier. If the symbol + // lookup returned a Message, and the enclosing Message has + // message_set_wire_format = true, then return the message set + // extension, if one exists. + for (int i = 0; i < foreign_type->extension_count(); i++) { + const FieldDescriptor* extension = foreign_type->extension(i); + if (extension->containing_type() == descriptor && + extension->type() == FieldDescriptor::TYPE_MESSAGE && + extension->is_optional() && + extension->message_type() == foreign_type) { + // Found it. + return extension; + } + } + } + return nullptr; + } +}; + +// A custom error collector to record any text-format parsing errors +namespace { +class AggregateErrorCollector : public io::ErrorCollector { + public: + TProtoStringType error_; + + void AddError(int /* line */, int /* column */, + const TProtoStringType& message) override { + if (!error_.empty()) { + error_ += "; "; + } + error_ += message; + } + + void AddWarning(int /* line */, int /* column */, + const TProtoStringType& /* message */) override { + // Ignore warnings + } +}; +} // namespace + +// We construct a dynamic message of the type corresponding to +// option_field, parse the supplied text-format string into this +// message, and serialize the resulting message to produce the value. +bool DescriptorBuilder::OptionInterpreter::SetAggregateOption( + const FieldDescriptor* option_field, UnknownFieldSet* unknown_fields) { + if (!uninterpreted_option_->has_aggregate_value()) { + return AddValueError("Option \"" + option_field->full_name() + + "\" is a message. To set the entire message, use " + "syntax like \"" + + option_field->name() + + " = { <proto text format> }\". " + "To set fields within it, use " + "syntax like \"" + + option_field->name() + ".foo = value\"."); + } + + const Descriptor* type = option_field->message_type(); + std::unique_ptr<Message> dynamic(dynamic_factory_.GetPrototype(type)->New()); + GOOGLE_CHECK(dynamic.get() != nullptr) + << "Could not create an instance of " << option_field->DebugString(); + + AggregateErrorCollector collector; + AggregateOptionFinder finder; + finder.builder_ = builder_; + TextFormat::Parser parser; + parser.RecordErrorsTo(&collector); + parser.SetFinder(&finder); + if (!parser.ParseFromString(uninterpreted_option_->aggregate_value(), + dynamic.get())) { + AddValueError("Error while parsing option value for \"" + + option_field->name() + "\": " + collector.error_); + return false; + } else { + TProtoStringType serial; + dynamic->SerializeToString(&serial); // Never fails + if (option_field->type() == FieldDescriptor::TYPE_MESSAGE) { + unknown_fields->AddLengthDelimited(option_field->number(), serial); + } else { + GOOGLE_CHECK_EQ(option_field->type(), FieldDescriptor::TYPE_GROUP); + UnknownFieldSet* group = unknown_fields->AddGroup(option_field->number()); + group->ParseFromString(serial); + } + return true; + } +} + +void DescriptorBuilder::OptionInterpreter::SetInt32( + int number, arc_i32 value, FieldDescriptor::Type type, + UnknownFieldSet* unknown_fields) { + switch (type) { + case FieldDescriptor::TYPE_INT32: + unknown_fields->AddVarint( + number, static_cast<arc_ui64>(static_cast<arc_i64>(value))); + break; + + case FieldDescriptor::TYPE_SFIXED32: + unknown_fields->AddFixed32(number, static_cast<arc_ui32>(value)); + break; + + case FieldDescriptor::TYPE_SINT32: + unknown_fields->AddVarint( + number, internal::WireFormatLite::ZigZagEncode32(value)); + break; + + default: + GOOGLE_LOG(FATAL) << "Invalid wire type for CPPTYPE_INT32: " << type; + break; + } +} + +void DescriptorBuilder::OptionInterpreter::SetInt64( + int number, arc_i64 value, FieldDescriptor::Type type, + UnknownFieldSet* unknown_fields) { + switch (type) { + case FieldDescriptor::TYPE_INT64: + unknown_fields->AddVarint(number, static_cast<arc_ui64>(value)); + break; + + case FieldDescriptor::TYPE_SFIXED64: + unknown_fields->AddFixed64(number, static_cast<arc_ui64>(value)); + break; + + case FieldDescriptor::TYPE_SINT64: + unknown_fields->AddVarint( + number, internal::WireFormatLite::ZigZagEncode64(value)); + break; + + default: + GOOGLE_LOG(FATAL) << "Invalid wire type for CPPTYPE_INT64: " << type; + break; + } +} + +void DescriptorBuilder::OptionInterpreter::SetUInt32( + int number, arc_ui32 value, FieldDescriptor::Type type, + UnknownFieldSet* unknown_fields) { + switch (type) { + case FieldDescriptor::TYPE_UINT32: + unknown_fields->AddVarint(number, static_cast<arc_ui64>(value)); + break; + + case FieldDescriptor::TYPE_FIXED32: + unknown_fields->AddFixed32(number, static_cast<arc_ui32>(value)); + break; + + default: + GOOGLE_LOG(FATAL) << "Invalid wire type for CPPTYPE_UINT32: " << type; + break; + } +} + +void DescriptorBuilder::OptionInterpreter::SetUInt64( + int number, arc_ui64 value, FieldDescriptor::Type type, + UnknownFieldSet* unknown_fields) { + switch (type) { + case FieldDescriptor::TYPE_UINT64: + unknown_fields->AddVarint(number, value); + break; + + case FieldDescriptor::TYPE_FIXED64: + unknown_fields->AddFixed64(number, value); + break; + + default: + GOOGLE_LOG(FATAL) << "Invalid wire type for CPPTYPE_UINT64: " << type; + break; + } +} + +void DescriptorBuilder::LogUnusedDependency(const FileDescriptorProto& proto, + const FileDescriptor* result) { + (void)result; // Parameter is used by Google-internal code. + + if (!unused_dependency_.empty()) { + auto itr = pool_->unused_import_track_files_.find(proto.name()); + bool is_error = + itr != pool_->unused_import_track_files_.end() && itr->second; + for (std::set<const FileDescriptor*>::const_iterator it = + unused_dependency_.begin(); + it != unused_dependency_.end(); ++it) { + TProtoStringType error_message = "Import " + (*it)->name() + " is unused."; + if (is_error) { + AddError((*it)->name(), proto, DescriptorPool::ErrorCollector::IMPORT, + error_message); + } else { + AddWarning((*it)->name(), proto, DescriptorPool::ErrorCollector::IMPORT, + error_message); + } + } + } +} + +Symbol DescriptorPool::CrossLinkOnDemandHelper(StringPiece name, + bool expecting_enum) const { + (void)expecting_enum; // Parameter is used by Google-internal code. + auto lookup_name = TProtoStringType(name); + if (!lookup_name.empty() && lookup_name[0] == '.') { + lookup_name = lookup_name.substr(1); + } + Symbol result = tables_->FindByNameHelper(this, lookup_name); + return result; +} + +// Handle the lazy import building for a message field whose type wasn't built +// at cross link time. If that was the case, we saved the name of the type to +// be looked up when the accessor for the type was called. Set type_, +// enum_type_, message_type_, and default_value_enum_ appropriately. +void FieldDescriptor::InternalTypeOnceInit() const { + GOOGLE_CHECK(file()->finished_building_ == true); + const EnumDescriptor* enum_type = nullptr; + Symbol result = file()->pool()->CrossLinkOnDemandHelper( + type_descriptor_.lazy_type_name, type_ == FieldDescriptor::TYPE_ENUM); + if (result.type() == Symbol::MESSAGE) { + type_ = FieldDescriptor::TYPE_MESSAGE; + type_descriptor_.message_type = result.descriptor(); + } else if (result.type() == Symbol::ENUM) { + type_ = FieldDescriptor::TYPE_ENUM; + enum_type = type_descriptor_.enum_type = result.enum_descriptor(); + } + + if (enum_type) { + if (lazy_default_value_enum_name_) { + // Have to build the full name now instead of at CrossLink time, + // because enum_type may not be known at the time. + TProtoStringType name = enum_type->full_name(); + // Enum values reside in the same scope as the enum type. + TProtoStringType::size_type last_dot = name.find_last_of('.'); + if (last_dot != TProtoStringType::npos) { + name = name.substr(0, last_dot) + "." + lazy_default_value_enum_name_; + } else { + name = lazy_default_value_enum_name_; + } + Symbol result = file()->pool()->CrossLinkOnDemandHelper(name, true); + default_value_enum_ = result.enum_value_descriptor(); + } else { + default_value_enum_ = nullptr; + } + if (!default_value_enum_) { + // We use the first defined value as the default + // if a default is not explicitly defined. + GOOGLE_CHECK(enum_type->value_count()); + default_value_enum_ = enum_type->value(0); + } + } +} + +void FieldDescriptor::TypeOnceInit(const FieldDescriptor* to_init) { + to_init->InternalTypeOnceInit(); +} + +// message_type(), enum_type(), default_value_enum(), and type() +// all share the same internal::call_once init path to do lazy +// import building and cross linking of a field of a message. +const Descriptor* FieldDescriptor::message_type() const { + if (type_once_) { + internal::call_once(*type_once_, FieldDescriptor::TypeOnceInit, this); + } + return type_ == TYPE_MESSAGE || type_ == TYPE_GROUP + ? type_descriptor_.message_type + : nullptr; +} + +const EnumDescriptor* FieldDescriptor::enum_type() const { + if (type_once_) { + internal::call_once(*type_once_, FieldDescriptor::TypeOnceInit, this); + } + return type_ == TYPE_ENUM ? type_descriptor_.enum_type : nullptr; +} + +const EnumValueDescriptor* FieldDescriptor::default_value_enum() const { + if (type_once_) { + internal::call_once(*type_once_, FieldDescriptor::TypeOnceInit, this); + } + return default_value_enum_; +} + +const TProtoStringType& FieldDescriptor::PrintableNameForExtension() const { + const bool is_message_set_extension = + is_extension() && + containing_type()->options().message_set_wire_format() && + type() == FieldDescriptor::TYPE_MESSAGE && is_optional() && + extension_scope() == message_type(); + return is_message_set_extension ? message_type()->full_name() : full_name(); +} + +void FileDescriptor::InternalDependenciesOnceInit() const { + GOOGLE_CHECK(finished_building_ == true); + auto* names = dependencies_once_->dependencies_names; + for (int i = 0; i < dependency_count(); i++) { + if (names[i]) { + dependencies_[i] = pool_->FindFileByName(names[i]); + } + } +} + +void FileDescriptor::DependenciesOnceInit(const FileDescriptor* to_init) { + to_init->InternalDependenciesOnceInit(); +} + +const FileDescriptor* FileDescriptor::dependency(int index) const { + if (dependencies_once_) { + // Do once init for all indices, as it's unlikely only a single index would + // be called, and saves on internal::call_once allocations. + internal::call_once(dependencies_once_->once, + FileDescriptor::DependenciesOnceInit, this); + } + return dependencies_[index]; +} + +const Descriptor* MethodDescriptor::input_type() const { + return input_type_.Get(service()); +} + +const Descriptor* MethodDescriptor::output_type() const { + return output_type_.Get(service()); +} + + +namespace internal { +void LazyDescriptor::Set(const Descriptor* descriptor) { + GOOGLE_CHECK(!once_); + descriptor_ = descriptor; +} + +void LazyDescriptor::SetLazy(StringPiece name, + const FileDescriptor* file) { + // verify Init() has been called and Set hasn't been called yet. + GOOGLE_CHECK(!descriptor_); + GOOGLE_CHECK(!once_); + GOOGLE_CHECK(file && file->pool_); + GOOGLE_CHECK(file->pool_->lazily_build_dependencies_); + GOOGLE_CHECK(!file->finished_building_); + once_ = file->pool_->tables_->Create<internal::once_flag>(); + lazy_name_ = file->pool_->tables_->Strdup(name); +} + +void LazyDescriptor::Once(const ServiceDescriptor* service) { + if (once_) { + internal::call_once(*once_, [&] { + auto* file = service->file(); + GOOGLE_CHECK(file->finished_building_); + descriptor_ = + file->pool_->CrossLinkOnDemandHelper(lazy_name_, false).descriptor(); + }); + } +} + +} // namespace internal + +} // namespace protobuf +} // namespace google + +#include <google/protobuf/port_undef.inc> diff --git a/contrib/libs/protobuf_old/src/google/protobuf/descriptor.h b/contrib/libs/protobuf_old/src/google/protobuf/descriptor.h new file mode 100644 index 0000000000..10dcc1eab0 --- /dev/null +++ b/contrib/libs/protobuf_old/src/google/protobuf/descriptor.h @@ -0,0 +1,2417 @@ +// 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: kenton@google.com (Kenton Varda) +// Based on original Protocol Buffers design by +// Sanjay Ghemawat, Jeff Dean, and others. +// +// This file contains classes which describe a type of protocol message. +// You can use a message's descriptor to learn at runtime what fields +// it contains and what the types of those fields are. The Message +// interface also allows you to dynamically access and modify individual +// fields by passing the FieldDescriptor of the field you are interested +// in. +// +// Most users will not care about descriptors, because they will write +// code specific to certain protocol types and will simply use the classes +// generated by the protocol compiler directly. Advanced users who want +// to operate on arbitrary types (not known at compile time) may want to +// read descriptors in order to learn about the contents of a message. +// A very small number of users will want to construct their own +// Descriptors, either because they are implementing Message manually or +// because they are writing something like the protocol compiler. +// +// For an example of how you might use descriptors, see the code example +// at the top of message.h. + +#ifndef GOOGLE_PROTOBUF_DESCRIPTOR_H__ +#define GOOGLE_PROTOBUF_DESCRIPTOR_H__ + +#include <atomic> +#include <map> +#include <memory> +#include <set> +#include <string> +#include <vector> + +#include <google/protobuf/stubs/common.h> +#include <google/protobuf/stubs/logging.h> +#include <google/protobuf/stubs/mutex.h> +#include <google/protobuf/stubs/once.h> +#include <google/protobuf/port.h> +#include <google/protobuf/port_def.inc> + +// TYPE_BOOL is defined in the MacOS's ConditionalMacros.h. +#ifdef TYPE_BOOL +#undef TYPE_BOOL +#endif // TYPE_BOOL + +#ifdef SWIG +#define PROTOBUF_EXPORT +#endif + + +namespace google { +namespace protobuf { + +// Defined in this file. +class Descriptor; +class FieldDescriptor; +class OneofDescriptor; +class EnumDescriptor; +class EnumValueDescriptor; +class ServiceDescriptor; +class MethodDescriptor; +class FileDescriptor; +class DescriptorDatabase; +class DescriptorPool; + +// Defined in descriptor.proto +class DescriptorProto; +class DescriptorProto_ExtensionRange; +class FieldDescriptorProto; +class OneofDescriptorProto; +class EnumDescriptorProto; +class EnumValueDescriptorProto; +class ServiceDescriptorProto; +class MethodDescriptorProto; +class FileDescriptorProto; +class MessageOptions; +class FieldOptions; +class OneofOptions; +class EnumOptions; +class EnumValueOptions; +class ExtensionRangeOptions; +class ServiceOptions; +class MethodOptions; +class FileOptions; +class UninterpretedOption; +class SourceCodeInfo; + +// Defined in message.h +class Message; +class Reflection; + +// Defined in descriptor.cc +class DescriptorBuilder; +class FileDescriptorTables; +class Symbol; + +// Defined in unknown_field_set.h. +class UnknownField; + +// Defined in command_line_interface.cc +namespace compiler { +class CommandLineInterface; +namespace cpp { +// Defined in helpers.h +class Formatter; +} // namespace cpp +} // namespace compiler + +namespace descriptor_unittest { +class DescriptorTest; +} // namespace descriptor_unittest + +// Defined in printer.h +namespace io { +class Printer; +} // namespace io + +// NB, all indices are zero-based. +struct SourceLocation { + int start_line; + int end_line; + int start_column; + int end_column; + + // Doc comments found at the source location. + // See the comments in SourceCodeInfo.Location (descriptor.proto) for details. + TProtoStringType leading_comments; + TProtoStringType trailing_comments; + std::vector<TProtoStringType> leading_detached_comments; +}; + +// Options when generating machine-parsable output from a descriptor with +// DebugString(). +struct DebugStringOptions { + // include original user comments as recorded in SourceLocation entries. N.B. + // that this must be |false| by default: several other pieces of code (for + // example, the C++ code generation for fields in the proto compiler) rely on + // DebugString() output being unobstructed by user comments. + bool include_comments; + // If true, elide the braced body in the debug string. + bool elide_group_body; + bool elide_oneof_body; + + DebugStringOptions() + : include_comments(false), + elide_group_body(false), + elide_oneof_body(false) { + } +}; + +// A class to handle the simplest cases of a lazily linked descriptor +// for a message type that isn't built at the time of cross linking, +// which is needed when a pool has lazily_build_dependencies_ set. +// Must be instantiated as mutable in a descriptor. +namespace internal { + +class PROTOBUF_EXPORT LazyDescriptor { + public: + // Init function to be called at init time of a descriptor containing + // a LazyDescriptor. + void Init() { + descriptor_ = nullptr; + once_ = nullptr; + } + + // Sets the value of the descriptor if it is known during the descriptor + // building process. Not thread safe, should only be called during the + // descriptor build process. Should not be called after SetLazy has been + // called. + void Set(const Descriptor* descriptor); + + // Sets the information needed to lazily cross link the descriptor at a later + // time, SetLazy is not thread safe, should be called only once at descriptor + // build time if the symbol wasn't found and building of the file containing + // that type is delayed because lazily_build_dependencies_ is set on the pool. + // Should not be called after Set() has been called. + void SetLazy(StringPiece name, const FileDescriptor* file); + + // Returns the current value of the descriptor, thread-safe. If SetLazy(...) + // has been called, will do a one-time cross link of the type specified, + // building the descriptor file that contains the type if necessary. + inline const Descriptor* Get(const ServiceDescriptor* service) { + Once(service); + return descriptor_; + } + + private: + void Once(const ServiceDescriptor* service); + + union { + const Descriptor* descriptor_; + const char* lazy_name_; + }; + internal::once_flag* once_; +}; + +class PROTOBUF_EXPORT SymbolBase { + private: + friend class google::protobuf::Symbol; + uint8_t symbol_type_; +}; + +// Some types have more than one SymbolBase because they have multiple +// identities in the table. We can't have duplicate direct bases, so we use this +// intermediate base to do so. +// See BuildEnumValue for details. +template <int N> +class PROTOBUF_EXPORT SymbolBaseN : public SymbolBase {}; + +} // namespace internal + +// Describes a type of protocol message, or a particular group within a +// message. To obtain the Descriptor for a given message object, call +// Message::GetDescriptor(). Generated message classes also have a +// static method called descriptor() which returns the type's descriptor. +// Use DescriptorPool to construct your own descriptors. +class PROTOBUF_EXPORT Descriptor : private internal::SymbolBase { + public: + typedef DescriptorProto Proto; + + // The name of the message type, not including its scope. + const TProtoStringType& name() const; + + // The fully-qualified name of the message type, scope delimited by + // periods. For example, message type "Foo" which is declared in package + // "bar" has full name "bar.Foo". If a type "Baz" is nested within + // Foo, Baz's full_name is "bar.Foo.Baz". To get only the part that + // comes after the last '.', use name(). + const TProtoStringType& full_name() const; + + // Index of this descriptor within the file or containing type's message + // type array. + int index() const; + + // The .proto file in which this message type was defined. Never nullptr. + const FileDescriptor* file() const; + + // If this Descriptor describes a nested type, this returns the type + // in which it is nested. Otherwise, returns nullptr. + const Descriptor* containing_type() const; + + // Get options for this message type. These are specified in the .proto file + // by placing lines like "option foo = 1234;" in the message definition. + // Allowed options are defined by MessageOptions in descriptor.proto, and any + // available extensions of that message. + const MessageOptions& options() const; + + // Write the contents of this Descriptor into the given DescriptorProto. + // The target DescriptorProto must be clear before calling this; if it + // isn't, the result may be garbage. + void CopyTo(DescriptorProto* proto) const; + + // Write the contents of this descriptor in a human-readable form. Output + // will be suitable for re-parsing. + TProtoStringType DebugString() const; + + // Similar to DebugString(), but additionally takes options (e.g., + // include original user comments in output). + TProtoStringType DebugStringWithOptions(const DebugStringOptions& options) const; + + // Returns true if this is a placeholder for an unknown type. This will + // only be the case if this descriptor comes from a DescriptorPool + // with AllowUnknownDependencies() set. + bool is_placeholder() const; + + enum WellKnownType { + WELLKNOWNTYPE_UNSPECIFIED, // Not a well-known type. + + // Wrapper types. + WELLKNOWNTYPE_DOUBLEVALUE, // google.protobuf.DoubleValue + WELLKNOWNTYPE_FLOATVALUE, // google.protobuf.FloatValue + WELLKNOWNTYPE_INT64VALUE, // google.protobuf.Int64Value + WELLKNOWNTYPE_UINT64VALUE, // google.protobuf.UInt64Value + WELLKNOWNTYPE_INT32VALUE, // google.protobuf.Int32Value + WELLKNOWNTYPE_UINT32VALUE, // google.protobuf.UInt32Value + WELLKNOWNTYPE_STRINGVALUE, // google.protobuf.StringValue + WELLKNOWNTYPE_BYTESVALUE, // google.protobuf.BytesValue + WELLKNOWNTYPE_BOOLVALUE, // google.protobuf.BoolValue + + // Other well known types. + WELLKNOWNTYPE_ANY, // google.protobuf.Any + WELLKNOWNTYPE_FIELDMASK, // google.protobuf.FieldMask + WELLKNOWNTYPE_DURATION, // google.protobuf.Duration + WELLKNOWNTYPE_TIMESTAMP, // google.protobuf.Timestamp + WELLKNOWNTYPE_VALUE, // google.protobuf.Value + WELLKNOWNTYPE_LISTVALUE, // google.protobuf.ListValue + WELLKNOWNTYPE_STRUCT, // google.protobuf.Struct + + // New well-known types may be added in the future. + // Please make sure any switch() statements have a 'default' case. + __WELLKNOWNTYPE__DO_NOT_USE__ADD_DEFAULT_INSTEAD__, + }; + + WellKnownType well_known_type() const; + + // Field stuff ----------------------------------------------------- + + // The number of fields in this message type. + int field_count() const; + // Gets a field by index, where 0 <= index < field_count(). + // These are returned in the order they were defined in the .proto file. + const FieldDescriptor* field(int index) const; + + // Looks up a field by declared tag number. Returns nullptr if no such field + // exists. + const FieldDescriptor* FindFieldByNumber(int number) const; + // Looks up a field by name. Returns nullptr if no such field exists. + const FieldDescriptor* FindFieldByName(ConstStringParam name) const; + + // Looks up a field by lowercased name (as returned by lowercase_name()). + // This lookup may be ambiguous if multiple field names differ only by case, + // in which case the field returned is chosen arbitrarily from the matches. + const FieldDescriptor* FindFieldByLowercaseName( + ConstStringParam lowercase_name) const; + + // Looks up a field by camel-case name (as returned by camelcase_name()). + // This lookup may be ambiguous if multiple field names differ in a way that + // leads them to have identical camel-case names, in which case the field + // returned is chosen arbitrarily from the matches. + const FieldDescriptor* FindFieldByCamelcaseName( + ConstStringParam camelcase_name) const; + + // The number of oneofs in this message type. + int oneof_decl_count() const; + // The number of oneofs in this message type, excluding synthetic oneofs. + // Real oneofs always come first, so iterating up to real_oneof_decl_cout() + // will yield all real oneofs. + int real_oneof_decl_count() const; + // Get a oneof by index, where 0 <= index < oneof_decl_count(). + // These are returned in the order they were defined in the .proto file. + const OneofDescriptor* oneof_decl(int index) const; + + // Looks up a oneof by name. Returns nullptr if no such oneof exists. + const OneofDescriptor* FindOneofByName(ConstStringParam name) const; + + // Nested type stuff ----------------------------------------------- + + // The number of nested types in this message type. + int nested_type_count() const; + // Gets a nested type by index, where 0 <= index < nested_type_count(). + // These are returned in the order they were defined in the .proto file. + const Descriptor* nested_type(int index) const; + + // Looks up a nested type by name. Returns nullptr if no such nested type + // exists. + const Descriptor* FindNestedTypeByName(ConstStringParam name) const; + + // Enum stuff ------------------------------------------------------ + + // The number of enum types in this message type. + int enum_type_count() const; + // Gets an enum type by index, where 0 <= index < enum_type_count(). + // These are returned in the order they were defined in the .proto file. + const EnumDescriptor* enum_type(int index) const; + + // Looks up an enum type by name. Returns nullptr if no such enum type + // exists. + const EnumDescriptor* FindEnumTypeByName(ConstStringParam name) const; + + // Looks up an enum value by name, among all enum types in this message. + // Returns nullptr if no such value exists. + const EnumValueDescriptor* FindEnumValueByName(ConstStringParam name) const; + + // Extensions ------------------------------------------------------ + + // A range of field numbers which are designated for third-party + // extensions. + struct ExtensionRange { + typedef DescriptorProto_ExtensionRange Proto; + + typedef ExtensionRangeOptions OptionsType; + + // See Descriptor::CopyTo(). + void CopyTo(DescriptorProto_ExtensionRange* proto) const; + + int start; // inclusive + int end; // exclusive + + const ExtensionRangeOptions* options_; + }; + + // The number of extension ranges in this message type. + int extension_range_count() const; + // Gets an extension range by index, where 0 <= index < + // extension_range_count(). These are returned in the order they were defined + // in the .proto file. + const ExtensionRange* extension_range(int index) const; + + // Returns true if the number is in one of the extension ranges. + bool IsExtensionNumber(int number) const; + + // Returns nullptr if no extension range contains the given number. + const ExtensionRange* FindExtensionRangeContainingNumber(int number) const; + + // The number of extensions defined nested within this message type's scope. + // See doc: + // https://developers.google.com/protocol-buffers/docs/proto#nested-extensions + // + // Note that the extensions may be extending *other* messages. + // + // For example: + // message M1 { + // extensions 1 to max; + // } + // + // message M2 { + // extend M1 { + // optional int32 foo = 1; + // } + // } + // + // In this case, + // DescriptorPool::generated_pool() + // ->FindMessageTypeByName("M2") + // ->extension(0) + // will return "foo", even though "foo" is an extension of M1. + // To find all known extensions of a given message, instead use + // DescriptorPool::FindAllExtensions. + int extension_count() const; + // Get an extension by index, where 0 <= index < extension_count(). + // These are returned in the order they were defined in the .proto file. + const FieldDescriptor* extension(int index) const; + + // Looks up a named extension (which extends some *other* message type) + // defined within this message type's scope. + const FieldDescriptor* FindExtensionByName(ConstStringParam name) const; + + // Similar to FindFieldByLowercaseName(), but finds extensions defined within + // this message type's scope. + const FieldDescriptor* FindExtensionByLowercaseName( + ConstStringParam name) const; + + // Similar to FindFieldByCamelcaseName(), but finds extensions defined within + // this message type's scope. + const FieldDescriptor* FindExtensionByCamelcaseName( + ConstStringParam name) const; + + // Reserved fields ------------------------------------------------- + + // A range of reserved field numbers. + struct ReservedRange { + int start; // inclusive + int end; // exclusive + }; + + // The number of reserved ranges in this message type. + int reserved_range_count() const; + // Gets an reserved range by index, where 0 <= index < + // reserved_range_count(). These are returned in the order they were defined + // in the .proto file. + const ReservedRange* reserved_range(int index) const; + + // Returns true if the number is in one of the reserved ranges. + bool IsReservedNumber(int number) const; + + // Returns nullptr if no reserved range contains the given number. + const ReservedRange* FindReservedRangeContainingNumber(int number) const; + + // The number of reserved field names in this message type. + int reserved_name_count() const; + + // Gets a reserved name by index, where 0 <= index < reserved_name_count(). + const TProtoStringType& reserved_name(int index) const; + + // Returns true if the field name is reserved. + bool IsReservedName(ConstStringParam name) const; + + // Source Location --------------------------------------------------- + + // Updates |*out_location| to the source location of the complete + // extent of this message declaration. Returns false and leaves + // |*out_location| unchanged iff location information was not available. + bool GetSourceLocation(SourceLocation* out_location) const; + + // Maps -------------------------------------------------------------- + + // Returns the FieldDescriptor for the "key" field. If this isn't a map entry + // field, returns nullptr. + const FieldDescriptor* map_key() const; + + // Returns the FieldDescriptor for the "value" field. If this isn't a map + // entry field, returns nullptr. + const FieldDescriptor* map_value() const; + + private: + friend class Symbol; + typedef MessageOptions OptionsType; + + // Allows tests to test CopyTo(proto, true). + friend class descriptor_unittest::DescriptorTest; + + // Allows access to GetLocationPath for annotations. + friend class io::Printer; + friend class compiler::cpp::Formatter; + + // Fill the json_name field of FieldDescriptorProto. + void CopyJsonNameTo(DescriptorProto* proto) const; + + // Internal version of DebugString; controls the level of indenting for + // correct depth. Takes |options| to control debug-string options, and + // |include_opening_clause| to indicate whether the "message ... " part of the + // clause has already been generated (this varies depending on context). + void DebugString(int depth, TProtoStringType* contents, + const DebugStringOptions& options, + bool include_opening_clause) const; + + // Walks up the descriptor tree to generate the source location path + // to this descriptor from the file root. + void GetLocationPath(std::vector<int>* output) const; + + // True if this is a placeholder for an unknown type. + bool is_placeholder_ : 1; + // True if this is a placeholder and the type name wasn't fully-qualified. + bool is_unqualified_placeholder_ : 1; + // Well known type. Stored like this to conserve space. + uint8_t well_known_type_ : 5; + + // This points to the last field _number_ that is part of the sequence + // starting at 1, where + // `desc->field(i)->number() == i + 1` + // A value of `0` means no field matches. That is, there are no fields or the + // first field is not field `1`. + // Uses 16-bit to avoid extra padding. Unlikely to have more than 2^16 + // sequentially numbered fields in a message. + uint16_t sequential_field_limit_; + + int field_count_; + + // all_names_ = [name, full_name] + const TProtoStringType* all_names_; + const FileDescriptor* file_; + const Descriptor* containing_type_; + const MessageOptions* options_; + + // These arrays are separated from their sizes to minimize padding on 64-bit. + FieldDescriptor* fields_; + OneofDescriptor* oneof_decls_; + Descriptor* nested_types_; + EnumDescriptor* enum_types_; + ExtensionRange* extension_ranges_; + FieldDescriptor* extensions_; + ReservedRange* reserved_ranges_; + const TProtoStringType** reserved_names_; + + int oneof_decl_count_; + int real_oneof_decl_count_; + int nested_type_count_; + int enum_type_count_; + int extension_range_count_; + int extension_count_; + int reserved_range_count_; + int reserved_name_count_; + + // IMPORTANT: If you add a new field, make sure to search for all instances + // of Allocate<Descriptor>() and AllocateArray<Descriptor>() in descriptor.cc + // and update them to initialize the field. + + // Must be constructed using DescriptorPool. + Descriptor() {} + friend class DescriptorBuilder; + friend class DescriptorPool; + friend class EnumDescriptor; + friend class FieldDescriptor; + friend class FileDescriptorTables; + friend class OneofDescriptor; + friend class MethodDescriptor; + friend class FileDescriptor; + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(Descriptor); +}; + + +// Describes a single field of a message. To get the descriptor for a given +// field, first get the Descriptor for the message in which it is defined, +// then call Descriptor::FindFieldByName(). To get a FieldDescriptor for +// an extension, do one of the following: +// - Get the Descriptor or FileDescriptor for its containing scope, then +// call Descriptor::FindExtensionByName() or +// FileDescriptor::FindExtensionByName(). +// - Given a DescriptorPool, call DescriptorPool::FindExtensionByNumber() or +// DescriptorPool::FindExtensionByPrintableName(). +// Use DescriptorPool to construct your own descriptors. +class PROTOBUF_EXPORT FieldDescriptor : private internal::SymbolBase { + public: + typedef FieldDescriptorProto Proto; + + // Identifies a field type. 0 is reserved for errors. The order is weird + // for historical reasons. Types 12 and up are new in proto2. + enum Type { + TYPE_DOUBLE = 1, // double, exactly eight bytes on the wire. + TYPE_FLOAT = 2, // float, exactly four bytes on the wire. + TYPE_INT64 = 3, // int64, varint on the wire. Negative numbers + // take 10 bytes. Use TYPE_SINT64 if negative + // values are likely. + TYPE_UINT64 = 4, // uint64, varint on the wire. + TYPE_INT32 = 5, // int32, varint on the wire. Negative numbers + // take 10 bytes. Use TYPE_SINT32 if negative + // values are likely. + TYPE_FIXED64 = 6, // uint64, exactly eight bytes on the wire. + TYPE_FIXED32 = 7, // uint32, exactly four bytes on the wire. + TYPE_BOOL = 8, // bool, varint on the wire. + TYPE_STRING = 9, // UTF-8 text. + TYPE_GROUP = 10, // Tag-delimited message. Deprecated. + TYPE_MESSAGE = 11, // Length-delimited message. + + TYPE_BYTES = 12, // Arbitrary byte array. + TYPE_UINT32 = 13, // uint32, varint on the wire + TYPE_ENUM = 14, // Enum, varint on the wire + TYPE_SFIXED32 = 15, // int32, exactly four bytes on the wire + TYPE_SFIXED64 = 16, // int64, exactly eight bytes on the wire + TYPE_SINT32 = 17, // int32, ZigZag-encoded varint on the wire + TYPE_SINT64 = 18, // int64, ZigZag-encoded varint on the wire + + MAX_TYPE = 18, // Constant useful for defining lookup tables + // indexed by Type. + }; + + // Specifies the C++ data type used to represent the field. There is a + // fixed mapping from Type to CppType where each Type maps to exactly one + // CppType. 0 is reserved for errors. + enum CppType { + CPPTYPE_INT32 = 1, // TYPE_INT32, TYPE_SINT32, TYPE_SFIXED32 + CPPTYPE_INT64 = 2, // TYPE_INT64, TYPE_SINT64, TYPE_SFIXED64 + CPPTYPE_UINT32 = 3, // TYPE_UINT32, TYPE_FIXED32 + CPPTYPE_UINT64 = 4, // TYPE_UINT64, TYPE_FIXED64 + CPPTYPE_DOUBLE = 5, // TYPE_DOUBLE + CPPTYPE_FLOAT = 6, // TYPE_FLOAT + CPPTYPE_BOOL = 7, // TYPE_BOOL + CPPTYPE_ENUM = 8, // TYPE_ENUM + CPPTYPE_STRING = 9, // TYPE_STRING, TYPE_BYTES + CPPTYPE_MESSAGE = 10, // TYPE_MESSAGE, TYPE_GROUP + + MAX_CPPTYPE = 10, // Constant useful for defining lookup tables + // indexed by CppType. + }; + + // Identifies whether the field is optional, required, or repeated. 0 is + // reserved for errors. + enum Label { + LABEL_OPTIONAL = 1, // optional + LABEL_REQUIRED = 2, // required + LABEL_REPEATED = 3, // repeated + + MAX_LABEL = 3, // Constant useful for defining lookup tables + // indexed by Label. + }; + + // Valid field numbers are positive integers up to kMaxNumber. + static const int kMaxNumber = (1 << 29) - 1; + + // First field number reserved for the protocol buffer library implementation. + // Users may not declare fields that use reserved numbers. + static const int kFirstReservedNumber = 19000; + // Last field number reserved for the protocol buffer library implementation. + // Users may not declare fields that use reserved numbers. + static const int kLastReservedNumber = 19999; + + const TProtoStringType& name() const; // Name of this field within the message. + const TProtoStringType& full_name() const; // Fully-qualified name of the field. + const TProtoStringType& json_name() const; // JSON name of this field. + const FileDescriptor* file() const; // File in which this field was defined. + bool is_extension() const; // Is this an extension field? + int number() const; // Declared tag number. + + // Same as name() except converted to lower-case. This (and especially the + // FindFieldByLowercaseName() method) can be useful when parsing formats + // which prefer to use lowercase naming style. (Although, technically + // field names should be lowercased anyway according to the protobuf style + // guide, so this only makes a difference when dealing with old .proto files + // which do not follow the guide.) + const TProtoStringType& lowercase_name() const; + + // Same as name() except converted to camel-case. In this conversion, any + // time an underscore appears in the name, it is removed and the next + // letter is capitalized. Furthermore, the first letter of the name is + // lower-cased. Examples: + // FooBar -> fooBar + // foo_bar -> fooBar + // fooBar -> fooBar + // This (and especially the FindFieldByCamelcaseName() method) can be useful + // when parsing formats which prefer to use camel-case naming style. + const TProtoStringType& camelcase_name() const; + + Type type() const; // Declared type of this field. + const char* type_name() const; // Name of the declared type. + CppType cpp_type() const; // C++ type of this field. + const char* cpp_type_name() const; // Name of the C++ type. + Label label() const; // optional/required/repeated + + bool is_required() const; // shorthand for label() == LABEL_REQUIRED + bool is_optional() const; // shorthand for label() == LABEL_OPTIONAL + bool is_repeated() const; // shorthand for label() == LABEL_REPEATED + bool is_packable() const; // shorthand for is_repeated() && + // IsTypePackable(type()) + bool is_packed() const; // shorthand for is_packable() && + // options().packed() + bool is_map() const; // shorthand for type() == TYPE_MESSAGE && + // message_type()->options().map_entry() + + // Returns true if this field was syntactically written with "optional" in the + // .proto file. Excludes singular proto3 fields that do not have a label. + bool has_optional_keyword() const; + + // Returns true if this field tracks presence, ie. does the field + // distinguish between "unset" and "present with default value." + // This includes required, optional, and oneof fields. It excludes maps, + // repeated fields, and singular proto3 fields without "optional". + // + // For fields where has_presence() == true, the return value of + // Reflection::HasField() is semantically meaningful. + bool has_presence() const; + + // Index of this field within the message's field array, or the file or + // extension scope's extensions array. + int index() const; + + // Does this field have an explicitly-declared default value? + bool has_default_value() const; + + // Whether the user has specified the json_name field option in the .proto + // file. + bool has_json_name() const; + + // Get the field default value if cpp_type() == CPPTYPE_INT32. If no + // explicit default was defined, the default is 0. + arc_i32 default_value_arc_i32() const; + arc_i32 default_value_int32() const { return default_value_arc_i32(); } + // Get the field default value if cpp_type() == CPPTYPE_INT64. If no + // explicit default was defined, the default is 0. + arc_i64 default_value_arc_i64() const; + arc_i64 default_value_int64() const { return default_value_arc_i64(); } + // Get the field default value if cpp_type() == CPPTYPE_UINT32. If no + // explicit default was defined, the default is 0. + arc_ui32 default_value_arc_ui32() const; + arc_ui32 default_value_uint32() const { return default_value_arc_ui32(); } + // Get the field default value if cpp_type() == CPPTYPE_UINT64. If no + // explicit default was defined, the default is 0. + arc_ui64 default_value_arc_ui64() const; + arc_ui64 default_value_uint64() const { return default_value_arc_ui64(); } + // Get the field default value if cpp_type() == CPPTYPE_FLOAT. If no + // explicit default was defined, the default is 0.0. + float default_value_float() const; + // Get the field default value if cpp_type() == CPPTYPE_DOUBLE. If no + // explicit default was defined, the default is 0.0. + double default_value_double() const; + // Get the field default value if cpp_type() == CPPTYPE_BOOL. If no + // explicit default was defined, the default is false. + bool default_value_bool() const; + // Get the field default value if cpp_type() == CPPTYPE_ENUM. If no + // explicit default was defined, the default is the first value defined + // in the enum type (all enum types are required to have at least one value). + // This never returns nullptr. + const EnumValueDescriptor* default_value_enum() const; + // Get the field default value if cpp_type() == CPPTYPE_STRING. If no + // explicit default was defined, the default is the empty string. + const TProtoStringType& default_value_string() const; + + // The Descriptor for the message of which this is a field. For extensions, + // this is the extended type. Never nullptr. + const Descriptor* containing_type() const; + + // If the field is a member of a oneof, this is the one, otherwise this is + // nullptr. + const OneofDescriptor* containing_oneof() const; + + // If the field is a member of a non-synthetic oneof, returns the descriptor + // for the oneof, otherwise returns nullptr. + const OneofDescriptor* real_containing_oneof() const; + + // If the field is a member of a oneof, returns the index in that oneof. + int index_in_oneof() const; + + // An extension may be declared within the scope of another message. If this + // field is an extension (is_extension() is true), then extension_scope() + // returns that message, or nullptr if the extension was declared at global + // scope. If this is not an extension, extension_scope() is undefined (may + // assert-fail). + const Descriptor* extension_scope() const; + + // If type is TYPE_MESSAGE or TYPE_GROUP, returns a descriptor for the + // message or the group type. Otherwise, returns null. + const Descriptor* message_type() const; + // If type is TYPE_ENUM, returns a descriptor for the enum. Otherwise, + // returns null. + const EnumDescriptor* enum_type() const; + + // Get the FieldOptions for this field. This includes things listed in + // square brackets after the field definition. E.g., the field: + // optional string text = 1 [ctype=CORD]; + // has the "ctype" option set. Allowed options are defined by FieldOptions in + // descriptor.proto, and any available extensions of that message. + const FieldOptions& options() const; + + // See Descriptor::CopyTo(). + void CopyTo(FieldDescriptorProto* proto) const; + + // See Descriptor::DebugString(). + TProtoStringType DebugString() const; + + // See Descriptor::DebugStringWithOptions(). + TProtoStringType DebugStringWithOptions(const DebugStringOptions& options) const; + + // Helper method to get the CppType for a particular Type. + static CppType TypeToCppType(Type type); + + // Helper method to get the name of a Type. + static const char* TypeName(Type type); + + // Helper method to get the name of a CppType. + static const char* CppTypeName(CppType cpp_type); + + // Return true iff [packed = true] is valid for fields of this type. + static inline bool IsTypePackable(Type field_type); + + // Returns full_name() except if the field is a MessageSet extension, + // in which case it returns the full_name() of the containing message type + // for backwards compatibility with proto1. + // + // A MessageSet extension is defined as an optional message extension + // whose containing type has the message_set_wire_format option set. + // This should be true of extensions of google.protobuf.bridge.MessageSet; + // by convention, such extensions are named "message_set_extension". + // + // The opposite operation (looking up an extension's FieldDescriptor given + // its printable name) can be accomplished with + // message->file()->pool()->FindExtensionByPrintableName(message, name) + // where the extension extends "message". + const TProtoStringType& PrintableNameForExtension() const; + + // Source Location --------------------------------------------------- + + // Updates |*out_location| to the source location of the complete + // extent of this field declaration. Returns false and leaves + // |*out_location| unchanged iff location information was not available. + bool GetSourceLocation(SourceLocation* out_location) const; + + private: + friend class Symbol; + typedef FieldOptions OptionsType; + + // Allows access to GetLocationPath for annotations. + friend class io::Printer; + friend class compiler::cpp::Formatter; + friend class Reflection; + + // Fill the json_name field of FieldDescriptorProto. + void CopyJsonNameTo(FieldDescriptorProto* proto) const; + + // See Descriptor::DebugString(). + void DebugString(int depth, TProtoStringType* contents, + const DebugStringOptions& options) const; + + // formats the default value appropriately and returns it as a string. + // Must have a default value to call this. If quote_string_type is true, then + // types of CPPTYPE_STRING whill be surrounded by quotes and CEscaped. + TProtoStringType DefaultValueAsString(bool quote_string_type) const; + + // Helper function that returns the field type name for DebugString. + TProtoStringType FieldTypeNameDebugString() const; + + // Walks up the descriptor tree to generate the source location path + // to this descriptor from the file root. + void GetLocationPath(std::vector<int>* output) const; + + // Returns true if this is a map message type. + bool is_map_message_type() const; + + bool has_default_value_ : 1; + bool proto3_optional_ : 1; + // Whether the user has specified the json_name field option in the .proto + // file. + bool has_json_name_ : 1; + bool is_extension_ : 1; + bool is_oneof_ : 1; + + // Actually a `Label` but stored as uint8_t to save space. + uint8_t label_ : 2; + + // Actually a `Type`, but stored as uint8_t to save space. + mutable uint8_t type_; + + // Logically: + // all_names_ = [name, full_name, lower, camel, json] + // However: + // duplicates will be omitted, so lower/camel/json might be in the same + // position. + // We store the true offset for each name here, and the bit width must be + // large enough to account for the worst case where all names are present. + uint8_t lowercase_name_index_ : 2; + uint8_t camelcase_name_index_ : 2; + uint8_t json_name_index_ : 3; + // Sadly, `number_` located here to reduce padding. Unrelated to all_names_ + // and its indices above. + int number_; + const TProtoStringType* all_names_; + const FileDescriptor* file_; + + internal::once_flag* type_once_; + static void TypeOnceInit(const FieldDescriptor* to_init); + void InternalTypeOnceInit() const; + const Descriptor* containing_type_; + union { + const OneofDescriptor* containing_oneof; + const Descriptor* extension_scope; + } scope_; + union { + mutable const Descriptor* message_type; + mutable const EnumDescriptor* enum_type; + const char* lazy_type_name; + } type_descriptor_; + const FieldOptions* options_; + // IMPORTANT: If you add a new field, make sure to search for all instances + // of Allocate<FieldDescriptor>() and AllocateArray<FieldDescriptor>() in + // descriptor.cc and update them to initialize the field. + + union { + arc_i32 default_value_arc_i32_; + arc_i64 default_value_arc_i64_; + arc_ui32 default_value_arc_ui32_; + arc_ui64 default_value_arc_ui64_; + float default_value_float_; + double default_value_double_; + bool default_value_bool_; + + mutable const EnumValueDescriptor* default_value_enum_; + const char* lazy_default_value_enum_name_; + const TProtoStringType* default_value_string_; + mutable std::atomic<const Message*> default_generated_instance_; + }; + + static const CppType kTypeToCppTypeMap[MAX_TYPE + 1]; + + static const char* const kTypeToName[MAX_TYPE + 1]; + + static const char* const kCppTypeToName[MAX_CPPTYPE + 1]; + + static const char* const kLabelToName[MAX_LABEL + 1]; + + // Must be constructed using DescriptorPool. + FieldDescriptor() {} + friend class DescriptorBuilder; + friend class FileDescriptor; + friend class Descriptor; + friend class OneofDescriptor; + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(FieldDescriptor); +}; + + +// Describes a oneof defined in a message type. +class PROTOBUF_EXPORT OneofDescriptor : private internal::SymbolBase { + public: + typedef OneofDescriptorProto Proto; + + const TProtoStringType& name() const; // Name of this oneof. + const TProtoStringType& full_name() const; // Fully-qualified name of the oneof. + + // Index of this oneof within the message's oneof array. + int index() const; + + // Returns whether this oneof was inserted by the compiler to wrap a proto3 + // optional field. If this returns true, code generators should *not* emit it. + bool is_synthetic() const; + + // The .proto file in which this oneof was defined. Never nullptr. + const FileDescriptor* file() const; + // The Descriptor for the message containing this oneof. + const Descriptor* containing_type() const; + + // The number of (non-extension) fields which are members of this oneof. + int field_count() const; + // Get a member of this oneof, in the order in which they were declared in the + // .proto file. Does not include extensions. + const FieldDescriptor* field(int index) const; + + const OneofOptions& options() const; + + // See Descriptor::CopyTo(). + void CopyTo(OneofDescriptorProto* proto) const; + + // See Descriptor::DebugString(). + TProtoStringType DebugString() const; + + // See Descriptor::DebugStringWithOptions(). + TProtoStringType DebugStringWithOptions(const DebugStringOptions& options) const; + + // Source Location --------------------------------------------------- + + // Updates |*out_location| to the source location of the complete + // extent of this oneof declaration. Returns false and leaves + // |*out_location| unchanged iff location information was not available. + bool GetSourceLocation(SourceLocation* out_location) const; + + private: + friend class Symbol; + typedef OneofOptions OptionsType; + + // Allows access to GetLocationPath for annotations. + friend class io::Printer; + friend class compiler::cpp::Formatter; + + // See Descriptor::DebugString(). + void DebugString(int depth, TProtoStringType* contents, + const DebugStringOptions& options) const; + + // Walks up the descriptor tree to generate the source location path + // to this descriptor from the file root. + void GetLocationPath(std::vector<int>* output) const; + + int field_count_; + + // all_names_ = [name, full_name] + const TProtoStringType* all_names_; + const Descriptor* containing_type_; + const OneofOptions* options_; + const FieldDescriptor* fields_; + + // IMPORTANT: If you add a new field, make sure to search for all instances + // of Allocate<OneofDescriptor>() and AllocateArray<OneofDescriptor>() + // in descriptor.cc and update them to initialize the field. + + // Must be constructed using DescriptorPool. + OneofDescriptor() {} + friend class DescriptorBuilder; + friend class Descriptor; + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(OneofDescriptor); +}; + +// Describes an enum type defined in a .proto file. To get the EnumDescriptor +// for a generated enum type, call TypeName_descriptor(). Use DescriptorPool +// to construct your own descriptors. +class PROTOBUF_EXPORT EnumDescriptor : private internal::SymbolBase { + public: + typedef EnumDescriptorProto Proto; + + // The name of this enum type in the containing scope. + const TProtoStringType& name() const; + + // The fully-qualified name of the enum type, scope delimited by periods. + const TProtoStringType& full_name() const; + + // Index of this enum within the file or containing message's enum array. + int index() const; + + // The .proto file in which this enum type was defined. Never nullptr. + const FileDescriptor* file() const; + + // The number of values for this EnumDescriptor. Guaranteed to be greater + // than zero. + int value_count() const; + // Gets a value by index, where 0 <= index < value_count(). + // These are returned in the order they were defined in the .proto file. + const EnumValueDescriptor* value(int index) const; + + // Looks up a value by name. Returns nullptr if no such value exists. + const EnumValueDescriptor* FindValueByName(ConstStringParam name) const; + // Looks up a value by number. Returns nullptr if no such value exists. If + // multiple values have this number, the first one defined is returned. + const EnumValueDescriptor* FindValueByNumber(int number) const; + + // If this enum type is nested in a message type, this is that message type. + // Otherwise, nullptr. + const Descriptor* containing_type() const; + + // Get options for this enum type. These are specified in the .proto file by + // placing lines like "option foo = 1234;" in the enum definition. Allowed + // options are defined by EnumOptions in descriptor.proto, and any available + // extensions of that message. + const EnumOptions& options() const; + + // See Descriptor::CopyTo(). + void CopyTo(EnumDescriptorProto* proto) const; + + // See Descriptor::DebugString(). + TProtoStringType DebugString() const; + + // See Descriptor::DebugStringWithOptions(). + TProtoStringType DebugStringWithOptions(const DebugStringOptions& options) const; + + // Returns true if this is a placeholder for an unknown enum. This will + // only be the case if this descriptor comes from a DescriptorPool + // with AllowUnknownDependencies() set. + bool is_placeholder() const; + + // Reserved fields ------------------------------------------------- + + // A range of reserved field numbers. + struct ReservedRange { + int start; // inclusive + int end; // inclusive + }; + + // The number of reserved ranges in this message type. + int reserved_range_count() const; + // Gets an reserved range by index, where 0 <= index < + // reserved_range_count(). These are returned in the order they were defined + // in the .proto file. + const EnumDescriptor::ReservedRange* reserved_range(int index) const; + + // Returns true if the number is in one of the reserved ranges. + bool IsReservedNumber(int number) const; + + // Returns nullptr if no reserved range contains the given number. + const EnumDescriptor::ReservedRange* FindReservedRangeContainingNumber( + int number) const; + + // The number of reserved field names in this message type. + int reserved_name_count() const; + + // Gets a reserved name by index, where 0 <= index < reserved_name_count(). + const TProtoStringType& reserved_name(int index) const; + + // Returns true if the field name is reserved. + bool IsReservedName(ConstStringParam name) const; + + // Source Location --------------------------------------------------- + + // Updates |*out_location| to the source location of the complete + // extent of this enum declaration. Returns false and leaves + // |*out_location| unchanged iff location information was not available. + bool GetSourceLocation(SourceLocation* out_location) const; + + private: + friend class Symbol; + typedef EnumOptions OptionsType; + + // Allows access to GetLocationPath for annotations. + friend class io::Printer; + friend class compiler::cpp::Formatter; + + // Allow access to FindValueByNumberCreatingIfUnknown. + friend class descriptor_unittest::DescriptorTest; + + // Looks up a value by number. If the value does not exist, dynamically + // creates a new EnumValueDescriptor for that value, assuming that it was + // unknown. If a new descriptor is created, this is done in a thread-safe way, + // and future calls will return the same value descriptor pointer. + // + // This is private but is used by Reflection (which is friended below) to + // return a valid EnumValueDescriptor from GetEnum() when this feature is + // enabled. + const EnumValueDescriptor* FindValueByNumberCreatingIfUnknown( + int number) const; + + // See Descriptor::DebugString(). + void DebugString(int depth, TProtoStringType* contents, + const DebugStringOptions& options) const; + + // Walks up the descriptor tree to generate the source location path + // to this descriptor from the file root. + void GetLocationPath(std::vector<int>* output) const; + + // True if this is a placeholder for an unknown type. + bool is_placeholder_ : 1; + // True if this is a placeholder and the type name wasn't fully-qualified. + bool is_unqualified_placeholder_ : 1; + + // This points to the last value _index_ that is part of the sequence starting + // with the first label, where + // `enum->value(i)->number() == enum->value(0)->number() + i` + // We measure relative to the first label to adapt to enum labels starting at + // 0 or 1. + // Uses 16-bit to avoid extra padding. Unlikely to have more than 2^15 + // sequentially numbered labels in an enum. + int16_t sequential_value_limit_; + + int value_count_; + + // all_names_ = [name, full_name] + const TProtoStringType* all_names_; + const FileDescriptor* file_; + const Descriptor* containing_type_; + const EnumOptions* options_; + EnumValueDescriptor* values_; + + int reserved_range_count_; + int reserved_name_count_; + EnumDescriptor::ReservedRange* reserved_ranges_; + const TProtoStringType** reserved_names_; + + // IMPORTANT: If you add a new field, make sure to search for all instances + // of Allocate<EnumDescriptor>() and AllocateArray<EnumDescriptor>() in + // descriptor.cc and update them to initialize the field. + + // Must be constructed using DescriptorPool. + EnumDescriptor() {} + friend class DescriptorBuilder; + friend class Descriptor; + friend class FieldDescriptor; + friend class FileDescriptorTables; + friend class EnumValueDescriptor; + friend class FileDescriptor; + friend class DescriptorPool; + friend class Reflection; + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(EnumDescriptor); +}; + +// Describes an individual enum constant of a particular type. To get the +// EnumValueDescriptor for a given enum value, first get the EnumDescriptor +// for its type, then use EnumDescriptor::FindValueByName() or +// EnumDescriptor::FindValueByNumber(). Use DescriptorPool to construct +// your own descriptors. +class PROTOBUF_EXPORT EnumValueDescriptor : private internal::SymbolBaseN<0>, + private internal::SymbolBaseN<1> { + public: + typedef EnumValueDescriptorProto Proto; + + const TProtoStringType& name() const; // Name of this enum constant. + int index() const; // Index within the enums's Descriptor. + int number() const; // Numeric value of this enum constant. + + // The full_name of an enum value is a sibling symbol of the enum type. + // e.g. the full name of FieldDescriptorProto::TYPE_INT32 is actually + // "google.protobuf.FieldDescriptorProto.TYPE_INT32", NOT + // "google.protobuf.FieldDescriptorProto.Type.TYPE_INT32". This is to conform + // with C++ scoping rules for enums. + const TProtoStringType& full_name() const; + + // The .proto file in which this value was defined. Never nullptr. + const FileDescriptor* file() const; + // The type of this value. Never nullptr. + const EnumDescriptor* type() const; + + // Get options for this enum value. These are specified in the .proto file by + // adding text like "[foo = 1234]" after an enum value definition. Allowed + // options are defined by EnumValueOptions in descriptor.proto, and any + // available extensions of that message. + const EnumValueOptions& options() const; + + // See Descriptor::CopyTo(). + void CopyTo(EnumValueDescriptorProto* proto) const; + + // See Descriptor::DebugString(). + TProtoStringType DebugString() const; + + // See Descriptor::DebugStringWithOptions(). + TProtoStringType DebugStringWithOptions(const DebugStringOptions& options) const; + + // Source Location --------------------------------------------------- + + // Updates |*out_location| to the source location of the complete + // extent of this enum value declaration. Returns false and leaves + // |*out_location| unchanged iff location information was not available. + bool GetSourceLocation(SourceLocation* out_location) const; + + private: + friend class Symbol; + typedef EnumValueOptions OptionsType; + + // Allows access to GetLocationPath for annotations. + friend class io::Printer; + friend class compiler::cpp::Formatter; + + // See Descriptor::DebugString(). + void DebugString(int depth, TProtoStringType* contents, + const DebugStringOptions& options) const; + + // Walks up the descriptor tree to generate the source location path + // to this descriptor from the file root. + void GetLocationPath(std::vector<int>* output) const; + + int number_; + // all_names_ = [name, full_name] + const TProtoStringType* all_names_; + const EnumDescriptor* type_; + const EnumValueOptions* options_; + // IMPORTANT: If you add a new field, make sure to search for all instances + // of Allocate<EnumValueDescriptor>() and AllocateArray<EnumValueDescriptor>() + // in descriptor.cc and update them to initialize the field. + + // Must be constructed using DescriptorPool. + EnumValueDescriptor() {} + friend class DescriptorBuilder; + friend class EnumDescriptor; + friend class DescriptorPool; + friend class FileDescriptorTables; + friend class Reflection; + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(EnumValueDescriptor); +}; + +// Describes an RPC service. Use DescriptorPool to construct your own +// descriptors. +class PROTOBUF_EXPORT ServiceDescriptor : private internal::SymbolBase { + public: + typedef ServiceDescriptorProto Proto; + + // The name of the service, not including its containing scope. + const TProtoStringType& name() const; + // The fully-qualified name of the service, scope delimited by periods. + const TProtoStringType& full_name() const; + // Index of this service within the file's services array. + int index() const; + + // The .proto file in which this service was defined. Never nullptr. + const FileDescriptor* file() const; + + // Get options for this service type. These are specified in the .proto file + // by placing lines like "option foo = 1234;" in the service definition. + // Allowed options are defined by ServiceOptions in descriptor.proto, and any + // available extensions of that message. + const ServiceOptions& options() const; + + // The number of methods this service defines. + int method_count() const; + // Gets a MethodDescriptor by index, where 0 <= index < method_count(). + // These are returned in the order they were defined in the .proto file. + const MethodDescriptor* method(int index) const; + + // Look up a MethodDescriptor by name. + const MethodDescriptor* FindMethodByName(ConstStringParam name) const; + // See Descriptor::CopyTo(). + void CopyTo(ServiceDescriptorProto* proto) const; + + // See Descriptor::DebugString(). + TProtoStringType DebugString() const; + + // See Descriptor::DebugStringWithOptions(). + TProtoStringType DebugStringWithOptions(const DebugStringOptions& options) const; + + // Source Location --------------------------------------------------- + + // Updates |*out_location| to the source location of the complete + // extent of this service declaration. Returns false and leaves + // |*out_location| unchanged iff location information was not available. + bool GetSourceLocation(SourceLocation* out_location) const; + + private: + friend class Symbol; + typedef ServiceOptions OptionsType; + + // Allows access to GetLocationPath for annotations. + friend class io::Printer; + friend class compiler::cpp::Formatter; + + // See Descriptor::DebugString(). + void DebugString(TProtoStringType* contents, + const DebugStringOptions& options) const; + + // Walks up the descriptor tree to generate the source location path + // to this descriptor from the file root. + void GetLocationPath(std::vector<int>* output) const; + + // all_names_ = [name, full_name] + const TProtoStringType* all_names_; + const FileDescriptor* file_; + const ServiceOptions* options_; + MethodDescriptor* methods_; + int method_count_; + // IMPORTANT: If you add a new field, make sure to search for all instances + // of Allocate<ServiceDescriptor>() and AllocateArray<ServiceDescriptor>() in + // descriptor.cc and update them to initialize the field. + + // Must be constructed using DescriptorPool. + ServiceDescriptor() {} + friend class DescriptorBuilder; + friend class FileDescriptor; + friend class MethodDescriptor; + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ServiceDescriptor); +}; + + +// Describes an individual service method. To obtain a MethodDescriptor given +// a service, first get its ServiceDescriptor, then call +// ServiceDescriptor::FindMethodByName(). Use DescriptorPool to construct your +// own descriptors. +class PROTOBUF_EXPORT MethodDescriptor : private internal::SymbolBase { + public: + typedef MethodDescriptorProto Proto; + + // Name of this method, not including containing scope. + const TProtoStringType& name() const; + // The fully-qualified name of the method, scope delimited by periods. + const TProtoStringType& full_name() const; + // Index within the service's Descriptor. + int index() const; + + // The .proto file in which this method was defined. Never nullptr. + const FileDescriptor* file() const; + // Gets the service to which this method belongs. Never nullptr. + const ServiceDescriptor* service() const; + + // Gets the type of protocol message which this method accepts as input. + const Descriptor* input_type() const; + // Gets the type of protocol message which this message produces as output. + const Descriptor* output_type() const; + + // Gets whether the client streams multiple requests. + bool client_streaming() const; + // Gets whether the server streams multiple responses. + bool server_streaming() const; + + // Get options for this method. These are specified in the .proto file by + // placing lines like "option foo = 1234;" in curly-braces after a method + // declaration. Allowed options are defined by MethodOptions in + // descriptor.proto, and any available extensions of that message. + const MethodOptions& options() const; + + // See Descriptor::CopyTo(). + void CopyTo(MethodDescriptorProto* proto) const; + + // See Descriptor::DebugString(). + TProtoStringType DebugString() const; + + // See Descriptor::DebugStringWithOptions(). + TProtoStringType DebugStringWithOptions(const DebugStringOptions& options) const; + + // Source Location --------------------------------------------------- + + // Updates |*out_location| to the source location of the complete + // extent of this method declaration. Returns false and leaves + // |*out_location| unchanged iff location information was not available. + bool GetSourceLocation(SourceLocation* out_location) const; + + private: + friend class Symbol; + typedef MethodOptions OptionsType; + + // Allows access to GetLocationPath for annotations. + friend class io::Printer; + friend class compiler::cpp::Formatter; + + // See Descriptor::DebugString(). + void DebugString(int depth, TProtoStringType* contents, + const DebugStringOptions& options) const; + + // Walks up the descriptor tree to generate the source location path + // to this descriptor from the file root. + void GetLocationPath(std::vector<int>* output) const; + + bool client_streaming_; + bool server_streaming_; + // all_names_ = [name, full_name] + const TProtoStringType* all_names_; + const ServiceDescriptor* service_; + mutable internal::LazyDescriptor input_type_; + mutable internal::LazyDescriptor output_type_; + const MethodOptions* options_; + // IMPORTANT: If you add a new field, make sure to search for all instances + // of Allocate<MethodDescriptor>() and AllocateArray<MethodDescriptor>() in + // descriptor.cc and update them to initialize the field. + + // Must be constructed using DescriptorPool. + MethodDescriptor() {} + friend class DescriptorBuilder; + friend class ServiceDescriptor; + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(MethodDescriptor); +}; + + +// Describes a whole .proto file. To get the FileDescriptor for a compiled-in +// file, get the descriptor for something defined in that file and call +// descriptor->file(). Use DescriptorPool to construct your own descriptors. +class PROTOBUF_EXPORT FileDescriptor { + public: + typedef FileDescriptorProto Proto; + + // The filename, relative to the source tree. + // e.g. "foo/bar/baz.proto" + const TProtoStringType& name() const; + + // The package, e.g. "google.protobuf.compiler". + const TProtoStringType& package() const; + + // The DescriptorPool in which this FileDescriptor and all its contents were + // allocated. Never nullptr. + const DescriptorPool* pool() const; + + // The number of files imported by this one. + int dependency_count() const; + // Gets an imported file by index, where 0 <= index < dependency_count(). + // These are returned in the order they were defined in the .proto file. + const FileDescriptor* dependency(int index) const; + + // The number of files public imported by this one. + // The public dependency list is a subset of the dependency list. + int public_dependency_count() const; + // Gets a public imported file by index, where 0 <= index < + // public_dependency_count(). + // These are returned in the order they were defined in the .proto file. + const FileDescriptor* public_dependency(int index) const; + + // The number of files that are imported for weak fields. + // The weak dependency list is a subset of the dependency list. + int weak_dependency_count() const; + // Gets a weak imported file by index, where 0 <= index < + // weak_dependency_count(). + // These are returned in the order they were defined in the .proto file. + const FileDescriptor* weak_dependency(int index) const; + + // Number of top-level message types defined in this file. (This does not + // include nested types.) + int message_type_count() const; + // Gets a top-level message type, where 0 <= index < message_type_count(). + // These are returned in the order they were defined in the .proto file. + const Descriptor* message_type(int index) const; + + // Number of top-level enum types defined in this file. (This does not + // include nested types.) + int enum_type_count() const; + // Gets a top-level enum type, where 0 <= index < enum_type_count(). + // These are returned in the order they were defined in the .proto file. + const EnumDescriptor* enum_type(int index) const; + + // Number of services defined in this file. + int service_count() const; + // Gets a service, where 0 <= index < service_count(). + // These are returned in the order they were defined in the .proto file. + const ServiceDescriptor* service(int index) const; + + // Number of extensions defined at file scope. (This does not include + // extensions nested within message types.) + int extension_count() const; + // Gets an extension's descriptor, where 0 <= index < extension_count(). + // These are returned in the order they were defined in the .proto file. + const FieldDescriptor* extension(int index) const; + + // Get options for this file. These are specified in the .proto file by + // placing lines like "option foo = 1234;" at the top level, outside of any + // other definitions. Allowed options are defined by FileOptions in + // descriptor.proto, and any available extensions of that message. + const FileOptions& options() const; + + // Syntax of this file. + enum Syntax { + SYNTAX_UNKNOWN = 0, + SYNTAX_PROTO2 = 2, + SYNTAX_PROTO3 = 3, + }; + Syntax syntax() const; + static const char* SyntaxName(Syntax syntax); + + // Find a top-level message type by name (not full_name). Returns nullptr if + // not found. + const Descriptor* FindMessageTypeByName(ConstStringParam name) const; + // Find a top-level enum type by name. Returns nullptr if not found. + const EnumDescriptor* FindEnumTypeByName(ConstStringParam name) const; + // Find an enum value defined in any top-level enum by name. Returns nullptr + // if not found. + const EnumValueDescriptor* FindEnumValueByName(ConstStringParam name) const; + // Find a service definition by name. Returns nullptr if not found. + const ServiceDescriptor* FindServiceByName(ConstStringParam name) const; + // Find a top-level extension definition by name. Returns nullptr if not + // found. + const FieldDescriptor* FindExtensionByName(ConstStringParam name) const; + // Similar to FindExtensionByName(), but searches by lowercased-name. See + // Descriptor::FindFieldByLowercaseName(). + const FieldDescriptor* FindExtensionByLowercaseName( + ConstStringParam name) const; + // Similar to FindExtensionByName(), but searches by camelcased-name. See + // Descriptor::FindFieldByCamelcaseName(). + const FieldDescriptor* FindExtensionByCamelcaseName( + ConstStringParam name) const; + + // See Descriptor::CopyTo(). + // Notes: + // - This method does NOT copy source code information since it is relatively + // large and rarely needed. See CopySourceCodeInfoTo() below. + void CopyTo(FileDescriptorProto* proto) const; + // Write the source code information of this FileDescriptor into the given + // FileDescriptorProto. See CopyTo() above. + void CopySourceCodeInfoTo(FileDescriptorProto* proto) const; + // Fill the json_name field of FieldDescriptorProto for all fields. Can only + // be called after CopyTo(). + void CopyJsonNameTo(FileDescriptorProto* proto) const; + + // See Descriptor::DebugString(). + TProtoStringType DebugString() const; + + // See Descriptor::DebugStringWithOptions(). + TProtoStringType DebugStringWithOptions(const DebugStringOptions& options) const; + + // Returns true if this is a placeholder for an unknown file. This will + // only be the case if this descriptor comes from a DescriptorPool + // with AllowUnknownDependencies() set. + bool is_placeholder() const; + + // Updates |*out_location| to the source location of the complete extent of + // this file declaration (namely, the empty path). + bool GetSourceLocation(SourceLocation* out_location) const; + + // Updates |*out_location| to the source location of the complete + // extent of the declaration or declaration-part denoted by |path|. + // Returns false and leaves |*out_location| unchanged iff location + // information was not available. (See SourceCodeInfo for + // description of path encoding.) + bool GetSourceLocation(const std::vector<int>& path, + SourceLocation* out_location) const; + + private: + typedef FileOptions OptionsType; + + const TProtoStringType* name_; + const TProtoStringType* package_; + const DescriptorPool* pool_; + + // Data required to do lazy initialization. + struct PROTOBUF_EXPORT LazyInitData { +#ifndef SWIG + internal::once_flag once; +#endif + const char** dependencies_names; + }; + + LazyInitData* dependencies_once_; + static void DependenciesOnceInit(const FileDescriptor* to_init); + void InternalDependenciesOnceInit() const; + + // These are arranged to minimize padding on 64-bit. + int dependency_count_; + int public_dependency_count_; + int weak_dependency_count_; + int message_type_count_; + int enum_type_count_; + int service_count_; + + bool is_placeholder_; + // Indicates the FileDescriptor is completed building. Used to verify + // that type accessor functions that can possibly build a dependent file + // aren't called during the process of building the file. + bool finished_building_; + // Actually a `Syntax` but stored as uint8_t to save space. + uint8_t syntax_; + // This one is here to fill the padding. + int extension_count_; + + mutable const FileDescriptor** dependencies_; + int* public_dependencies_; + int* weak_dependencies_; + Descriptor* message_types_; + EnumDescriptor* enum_types_; + ServiceDescriptor* services_; + FieldDescriptor* extensions_; + const FileOptions* options_; + + const FileDescriptorTables* tables_; + const SourceCodeInfo* source_code_info_; + + // IMPORTANT: If you add a new field, make sure to search for all instances + // of Allocate<FileDescriptor>() and AllocateArray<FileDescriptor>() in + // descriptor.cc and update them to initialize the field. + + FileDescriptor() {} + friend class DescriptorBuilder; + friend class DescriptorPool; + friend class Descriptor; + friend class FieldDescriptor; + friend class internal::LazyDescriptor; + friend class OneofDescriptor; + friend class EnumDescriptor; + friend class EnumValueDescriptor; + friend class MethodDescriptor; + friend class ServiceDescriptor; + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(FileDescriptor); +}; + + +// =================================================================== + +// Used to construct descriptors. +// +// Normally you won't want to build your own descriptors. Message classes +// constructed by the protocol compiler will provide them for you. However, +// if you are implementing Message on your own, or if you are writing a +// program which can operate on totally arbitrary types and needs to load +// them from some sort of database, you might need to. +// +// Since Descriptors are composed of a whole lot of cross-linked bits of +// data that would be a pain to put together manually, the +// DescriptorPool class is provided to make the process easier. It can +// take a FileDescriptorProto (defined in descriptor.proto), validate it, +// and convert it to a set of nicely cross-linked Descriptors. +// +// DescriptorPool also helps with memory management. Descriptors are +// composed of many objects containing static data and pointers to each +// other. In all likelihood, when it comes time to delete this data, +// you'll want to delete it all at once. In fact, it is not uncommon to +// have a whole pool of descriptors all cross-linked with each other which +// you wish to delete all at once. This class represents such a pool, and +// handles the memory management for you. +// +// You can also search for descriptors within a DescriptorPool by name, and +// extensions by number. +class PROTOBUF_EXPORT DescriptorPool { + public: + // Create a normal, empty DescriptorPool. + DescriptorPool(); + + // Constructs a DescriptorPool that, when it can't find something among the + // descriptors already in the pool, looks for it in the given + // DescriptorDatabase. + // Notes: + // - If a DescriptorPool is constructed this way, its BuildFile*() methods + // must not be called (they will assert-fail). The only way to populate + // the pool with descriptors is to call the Find*By*() methods. + // - The Find*By*() methods may block the calling thread if the + // DescriptorDatabase blocks. This in turn means that parsing messages + // may block if they need to look up extensions. + // - The Find*By*() methods will use mutexes for thread-safety, thus making + // them slower even when they don't have to fall back to the database. + // In fact, even the Find*By*() methods of descriptor objects owned by + // this pool will be slower, since they will have to obtain locks too. + // - An ErrorCollector may optionally be given to collect validation errors + // in files loaded from the database. If not given, errors will be printed + // to GOOGLE_LOG(ERROR). Remember that files are built on-demand, so this + // ErrorCollector may be called from any thread that calls one of the + // Find*By*() methods. + // - The DescriptorDatabase must not be mutated during the lifetime of + // the DescriptorPool. Even if the client takes care to avoid data races, + // changes to the content of the DescriptorDatabase may not be reflected + // in subsequent lookups in the DescriptorPool. + class ErrorCollector; + explicit DescriptorPool(DescriptorDatabase* fallback_database, + ErrorCollector* error_collector = nullptr); + + ~DescriptorPool(); + + // Get a pointer to the generated pool. Generated protocol message classes + // which are compiled into the binary will allocate their descriptors in + // this pool. Do not add your own descriptors to this pool. + static const DescriptorPool* generated_pool(); + + + // Find a FileDescriptor in the pool by file name. Returns nullptr if not + // found. + const FileDescriptor* FindFileByName(ConstStringParam name) const; + + // Find the FileDescriptor in the pool which defines the given symbol. + // If any of the Find*ByName() methods below would succeed, then this is + // equivalent to calling that method and calling the result's file() method. + // Otherwise this returns nullptr. + const FileDescriptor* FindFileContainingSymbol( + ConstStringParam symbol_name) const; + + // Looking up descriptors ------------------------------------------ + // These find descriptors by fully-qualified name. These will find both + // top-level descriptors and nested descriptors. They return nullptr if not + // found. + + const Descriptor* FindMessageTypeByName(ConstStringParam name) const; + const FieldDescriptor* FindFieldByName(ConstStringParam name) const; + const FieldDescriptor* FindExtensionByName(ConstStringParam name) const; + const OneofDescriptor* FindOneofByName(ConstStringParam name) const; + const EnumDescriptor* FindEnumTypeByName(ConstStringParam name) const; + const EnumValueDescriptor* FindEnumValueByName(ConstStringParam name) const; + const ServiceDescriptor* FindServiceByName(ConstStringParam name) const; + const MethodDescriptor* FindMethodByName(ConstStringParam name) const; + + // Finds an extension of the given type by number. The extendee must be + // a member of this DescriptorPool or one of its underlays. + const FieldDescriptor* FindExtensionByNumber(const Descriptor* extendee, + int number) const; + + // Finds an extension of the given type by its printable name. + // See comments above PrintableNameForExtension() for the definition of + // "printable name". The extendee must be a member of this DescriptorPool + // or one of its underlays. Returns nullptr if there is no known message + // extension with the given printable name. + const FieldDescriptor* FindExtensionByPrintableName( + const Descriptor* extendee, ConstStringParam printable_name) const; + + // Finds extensions of extendee. The extensions will be appended to + // out in an undefined order. Only extensions defined directly in + // this DescriptorPool or one of its underlays are guaranteed to be + // found: extensions defined in the fallback database might not be found + // depending on the database implementation. + void FindAllExtensions(const Descriptor* extendee, + std::vector<const FieldDescriptor*>* out) const; + + // Building descriptors -------------------------------------------- + + // When converting a FileDescriptorProto to a FileDescriptor, various + // errors might be detected in the input. The caller may handle these + // programmatically by implementing an ErrorCollector. + class PROTOBUF_EXPORT ErrorCollector { + public: + inline ErrorCollector() {} + virtual ~ErrorCollector(); + + // These constants specify what exact part of the construct is broken. + // This is useful e.g. for mapping the error back to an exact location + // in a .proto file. + enum ErrorLocation { + NAME, // the symbol name, or the package name for files + NUMBER, // field or extension range number + TYPE, // field type + EXTENDEE, // field extendee + DEFAULT_VALUE, // field default value + INPUT_TYPE, // method input type + OUTPUT_TYPE, // method output type + OPTION_NAME, // name in assignment + OPTION_VALUE, // value in option assignment + IMPORT, // import error + OTHER // some other problem + }; + + // Reports an error in the FileDescriptorProto. Use this function if the + // problem occurred should interrupt building the FileDescriptorProto. + virtual void AddError( + const TProtoStringType& filename, // File name in which the error occurred. + const TProtoStringType& element_name, // Full name of the erroneous element. + const Message* descriptor, // Descriptor of the erroneous element. + ErrorLocation location, // One of the location constants, above. + const TProtoStringType& message // Human-readable error message. + ) = 0; + + // Reports a warning in the FileDescriptorProto. Use this function if the + // problem occurred should NOT interrupt building the FileDescriptorProto. + virtual void AddWarning( + const TProtoStringType& /*filename*/, // File name in which the error + // occurred. + const TProtoStringType& /*element_name*/, // Full name of the erroneous + // element. + const Message* /*descriptor*/, // Descriptor of the erroneous element. + ErrorLocation /*location*/, // One of the location constants, above. + const TProtoStringType& /*message*/ // Human-readable error message. + ) {} + + private: + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ErrorCollector); + }; + + // Convert the FileDescriptorProto to real descriptors and place them in + // this DescriptorPool. All dependencies of the file must already be in + // the pool. Returns the resulting FileDescriptor, or nullptr if there were + // problems with the input (e.g. the message was invalid, or dependencies + // were missing). Details about the errors are written to GOOGLE_LOG(ERROR). + const FileDescriptor* BuildFile(const FileDescriptorProto& proto); + + // Same as BuildFile() except errors are sent to the given ErrorCollector. + const FileDescriptor* BuildFileCollectingErrors( + const FileDescriptorProto& proto, ErrorCollector* error_collector); + + // By default, it is an error if a FileDescriptorProto contains references + // to types or other files that are not found in the DescriptorPool (or its + // backing DescriptorDatabase, if any). If you call + // AllowUnknownDependencies(), however, then unknown types and files + // will be replaced by placeholder descriptors (which can be identified by + // the is_placeholder() method). This can allow you to + // perform some useful operations with a .proto file even if you do not + // have access to other .proto files on which it depends. However, some + // heuristics must be used to fill in the gaps in information, and these + // can lead to descriptors which are inaccurate. For example, the + // DescriptorPool may be forced to guess whether an unknown type is a message + // or an enum, as well as what package it resides in. Furthermore, + // placeholder types will not be discoverable via FindMessageTypeByName() + // and similar methods, which could confuse some descriptor-based algorithms. + // Generally, the results of this option should be handled with extreme care. + void AllowUnknownDependencies() { allow_unknown_ = true; } + + // By default, weak imports are allowed to be missing, in which case we will + // use a placeholder for the dependency and convert the field to be an Empty + // message field. If you call EnforceWeakDependencies(true), however, the + // DescriptorPool will report a import not found error. + void EnforceWeakDependencies(bool enforce) { enforce_weak_ = enforce; } + + // Internal stuff -------------------------------------------------- + // These methods MUST NOT be called from outside the proto2 library. + // These methods may contain hidden pitfalls and may be removed in a + // future library version. + + // Create a DescriptorPool which is overlaid on top of some other pool. + // If you search for a descriptor in the overlay and it is not found, the + // underlay will be searched as a backup. If the underlay has its own + // underlay, that will be searched next, and so on. This also means that + // files built in the overlay will be cross-linked with the underlay's + // descriptors if necessary. The underlay remains property of the caller; + // it must remain valid for the lifetime of the newly-constructed pool. + // + // Example: Say you want to parse a .proto file at runtime in order to use + // its type with a DynamicMessage. Say this .proto file has dependencies, + // but you know that all the dependencies will be things that are already + // compiled into the binary. For ease of use, you'd like to load the types + // right out of generated_pool() rather than have to parse redundant copies + // of all these .protos and runtime. But, you don't want to add the parsed + // types directly into generated_pool(): this is not allowed, and would be + // bad design anyway. So, instead, you could use generated_pool() as an + // underlay for a new DescriptorPool in which you add only the new file. + // + // WARNING: Use of underlays can lead to many subtle gotchas. Instead, + // try to formulate what you want to do in terms of DescriptorDatabases. + explicit DescriptorPool(const DescriptorPool* underlay); + + // Called by generated classes at init time to add their descriptors to + // generated_pool. Do NOT call this in your own code! filename must be a + // permanent string (e.g. a string literal). + static void InternalAddGeneratedFile(const void* encoded_file_descriptor, + int size); + + // Disallow [enforce_utf8 = false] in .proto files. + void DisallowEnforceUtf8() { disallow_enforce_utf8_ = true; } + + + // For internal use only: Gets a non-const pointer to the generated pool. + // This is called at static-initialization time only, so thread-safety is + // not a concern. If both an underlay and a fallback database are present, + // the underlay takes precedence. + static DescriptorPool* internal_generated_pool(); + + // For internal use only: Gets a non-const pointer to the generated + // descriptor database. + // Only used for testing. + static DescriptorDatabase* internal_generated_database(); + + // For internal use only: Changes the behavior of BuildFile() such that it + // allows the file to make reference to message types declared in other files + // which it did not officially declare as dependencies. + void InternalDontEnforceDependencies(); + + // For internal use only: Enables lazy building of dependencies of a file. + // Delay the building of dependencies of a file descriptor until absolutely + // necessary, like when message_type() is called on a field that is defined + // in that dependency's file. This will cause functional issues if a proto + // or one of its dependencies has errors. Should only be enabled for the + // generated_pool_ (because no descriptor build errors are guaranteed by + // the compilation generation process), testing, or if a lack of descriptor + // build errors can be guaranteed for a pool. + void InternalSetLazilyBuildDependencies() { + lazily_build_dependencies_ = true; + // This needs to be set when lazily building dependencies, as it breaks + // dependency checking. + InternalDontEnforceDependencies(); + } + + // For internal use only. + void internal_set_underlay(const DescriptorPool* underlay) { + underlay_ = underlay; + } + + // For internal (unit test) use only: Returns true if a FileDescriptor has + // been constructed for the given file, false otherwise. Useful for testing + // lazy descriptor initialization behavior. + bool InternalIsFileLoaded(ConstStringParam filename) const; + + // Add a file to unused_import_track_files_. DescriptorBuilder will log + // warnings or errors for those files if there is any unused import. + void AddUnusedImportTrackFile(ConstStringParam file_name, + bool is_error = false); + void ClearUnusedImportTrackFiles(); + + private: + friend class Descriptor; + friend class internal::LazyDescriptor; + friend class FieldDescriptor; + friend class EnumDescriptor; + friend class ServiceDescriptor; + friend class MethodDescriptor; + friend class FileDescriptor; + friend class StreamDescriptor; + friend class DescriptorBuilder; + friend class FileDescriptorTables; + + // Return true if the given name is a sub-symbol of any non-package + // descriptor that already exists in the descriptor pool. (The full + // definition of such types is already known.) + bool IsSubSymbolOfBuiltType(StringPiece name) const; + + // Tries to find something in the fallback database and link in the + // corresponding proto file. Returns true if successful, in which case + // the caller should search for the thing again. These are declared + // const because they are called by (semantically) const methods. + bool TryFindFileInFallbackDatabase(StringPiece name) const; + bool TryFindSymbolInFallbackDatabase(StringPiece name) const; + bool TryFindExtensionInFallbackDatabase(const Descriptor* containing_type, + int field_number) const; + + // This internal find extension method only check with its table and underlay + // descriptor_pool's table. It does not check with fallback DB and no + // additional proto file will be build in this method. + const FieldDescriptor* InternalFindExtensionByNumberNoLock( + const Descriptor* extendee, int number) const; + + // Like BuildFile() but called internally when the file has been loaded from + // fallback_database_. Declared const because it is called by (semantically) + // const methods. + const FileDescriptor* BuildFileFromDatabase( + const FileDescriptorProto& proto) const; + + // Helper for when lazily_build_dependencies_ is set, can look up a symbol + // after the file's descriptor is built, and can build the file where that + // symbol is defined if necessary. Will create a placeholder if the type + // doesn't exist in the fallback database, or the file doesn't build + // successfully. + Symbol CrossLinkOnDemandHelper(StringPiece name, + bool expecting_enum) const; + + // Create a placeholder FileDescriptor of the specified name + FileDescriptor* NewPlaceholderFile(StringPiece name) const; + FileDescriptor* NewPlaceholderFileWithMutexHeld(StringPiece name) const; + + enum PlaceholderType { + PLACEHOLDER_MESSAGE, + PLACEHOLDER_ENUM, + PLACEHOLDER_EXTENDABLE_MESSAGE + }; + // Create a placeholder Descriptor of the specified name + Symbol NewPlaceholder(StringPiece name, + PlaceholderType placeholder_type) const; + Symbol NewPlaceholderWithMutexHeld(StringPiece name, + PlaceholderType placeholder_type) const; + + // If fallback_database_ is nullptr, this is nullptr. Otherwise, this is a + // mutex which must be locked while accessing tables_. + internal::WrappedMutex* mutex_; + + // See constructor. + DescriptorDatabase* fallback_database_; + ErrorCollector* default_error_collector_; + const DescriptorPool* underlay_; + + // This class contains a lot of hash maps with complicated types that + // we'd like to keep out of the header. + class Tables; + std::unique_ptr<Tables> tables_; + + bool enforce_dependencies_; + bool lazily_build_dependencies_; + bool allow_unknown_; + bool enforce_weak_; + bool disallow_enforce_utf8_; + + // Set of files to track for unused imports. The bool value when true means + // unused imports are treated as errors (and as warnings when false). + std::map<TProtoStringType, bool> unused_import_track_files_; + + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(DescriptorPool); +}; + + +// inline methods ==================================================== + +// These macros makes this repetitive code more readable. +#define PROTOBUF_DEFINE_ACCESSOR(CLASS, FIELD, TYPE) \ + inline TYPE CLASS::FIELD() const { return FIELD##_; } + +// Strings fields are stored as pointers but returned as const references. +#define PROTOBUF_DEFINE_STRING_ACCESSOR(CLASS, FIELD) \ + inline const TProtoStringType& CLASS::FIELD() const { return *FIELD##_; } + +// Name and full name are stored in a single array to save space. +#define PROTOBUF_DEFINE_NAME_ACCESSOR(CLASS) \ + inline const TProtoStringType& CLASS::name() const { return all_names_[0]; } \ + inline const TProtoStringType& CLASS::full_name() const { return all_names_[1]; } + +// Arrays take an index parameter, obviously. +#define PROTOBUF_DEFINE_ARRAY_ACCESSOR(CLASS, FIELD, TYPE) \ + inline TYPE CLASS::FIELD(int index) const { return FIELD##s_ + index; } + +#define PROTOBUF_DEFINE_OPTIONS_ACCESSOR(CLASS, TYPE) \ + inline const TYPE& CLASS::options() const { return *options_; } + +PROTOBUF_DEFINE_NAME_ACCESSOR(Descriptor) +PROTOBUF_DEFINE_ACCESSOR(Descriptor, file, const FileDescriptor*) +PROTOBUF_DEFINE_ACCESSOR(Descriptor, containing_type, const Descriptor*) + +PROTOBUF_DEFINE_ACCESSOR(Descriptor, field_count, int) +PROTOBUF_DEFINE_ACCESSOR(Descriptor, oneof_decl_count, int) +PROTOBUF_DEFINE_ACCESSOR(Descriptor, real_oneof_decl_count, int) +PROTOBUF_DEFINE_ACCESSOR(Descriptor, nested_type_count, int) +PROTOBUF_DEFINE_ACCESSOR(Descriptor, enum_type_count, int) + +PROTOBUF_DEFINE_ARRAY_ACCESSOR(Descriptor, field, const FieldDescriptor*) +PROTOBUF_DEFINE_ARRAY_ACCESSOR(Descriptor, oneof_decl, const OneofDescriptor*) +PROTOBUF_DEFINE_ARRAY_ACCESSOR(Descriptor, nested_type, const Descriptor*) +PROTOBUF_DEFINE_ARRAY_ACCESSOR(Descriptor, enum_type, const EnumDescriptor*) + +PROTOBUF_DEFINE_ACCESSOR(Descriptor, extension_range_count, int) +PROTOBUF_DEFINE_ACCESSOR(Descriptor, extension_count, int) +PROTOBUF_DEFINE_ARRAY_ACCESSOR(Descriptor, extension_range, + const Descriptor::ExtensionRange*) +PROTOBUF_DEFINE_ARRAY_ACCESSOR(Descriptor, extension, const FieldDescriptor*) + +PROTOBUF_DEFINE_ACCESSOR(Descriptor, reserved_range_count, int) +PROTOBUF_DEFINE_ARRAY_ACCESSOR(Descriptor, reserved_range, + const Descriptor::ReservedRange*) +PROTOBUF_DEFINE_ACCESSOR(Descriptor, reserved_name_count, int) + +PROTOBUF_DEFINE_OPTIONS_ACCESSOR(Descriptor, MessageOptions) +PROTOBUF_DEFINE_ACCESSOR(Descriptor, is_placeholder, bool) + +PROTOBUF_DEFINE_NAME_ACCESSOR(FieldDescriptor) +PROTOBUF_DEFINE_ACCESSOR(FieldDescriptor, file, const FileDescriptor*) +PROTOBUF_DEFINE_ACCESSOR(FieldDescriptor, number, int) +PROTOBUF_DEFINE_ACCESSOR(FieldDescriptor, is_extension, bool) +PROTOBUF_DEFINE_ACCESSOR(FieldDescriptor, containing_type, const Descriptor*) +PROTOBUF_DEFINE_OPTIONS_ACCESSOR(FieldDescriptor, FieldOptions) +PROTOBUF_DEFINE_ACCESSOR(FieldDescriptor, has_default_value, bool) +PROTOBUF_DEFINE_ACCESSOR(FieldDescriptor, has_json_name, bool) +PROTOBUF_DEFINE_ACCESSOR(FieldDescriptor, default_value_arc_i32, arc_i32) +PROTOBUF_DEFINE_ACCESSOR(FieldDescriptor, default_value_arc_i64, arc_i64) +PROTOBUF_DEFINE_ACCESSOR(FieldDescriptor, default_value_arc_ui32, arc_ui32) +PROTOBUF_DEFINE_ACCESSOR(FieldDescriptor, default_value_arc_ui64, arc_ui64) +PROTOBUF_DEFINE_ACCESSOR(FieldDescriptor, default_value_float, float) +PROTOBUF_DEFINE_ACCESSOR(FieldDescriptor, default_value_double, double) +PROTOBUF_DEFINE_ACCESSOR(FieldDescriptor, default_value_bool, bool) +PROTOBUF_DEFINE_STRING_ACCESSOR(FieldDescriptor, default_value_string) + +PROTOBUF_DEFINE_NAME_ACCESSOR(OneofDescriptor) +PROTOBUF_DEFINE_ACCESSOR(OneofDescriptor, containing_type, const Descriptor*) +PROTOBUF_DEFINE_ACCESSOR(OneofDescriptor, field_count, int) +PROTOBUF_DEFINE_ARRAY_ACCESSOR(OneofDescriptor, field, const FieldDescriptor*) +PROTOBUF_DEFINE_OPTIONS_ACCESSOR(OneofDescriptor, OneofOptions) + +PROTOBUF_DEFINE_NAME_ACCESSOR(EnumDescriptor) +PROTOBUF_DEFINE_ACCESSOR(EnumDescriptor, file, const FileDescriptor*) +PROTOBUF_DEFINE_ACCESSOR(EnumDescriptor, containing_type, const Descriptor*) +PROTOBUF_DEFINE_ACCESSOR(EnumDescriptor, value_count, int) +PROTOBUF_DEFINE_ARRAY_ACCESSOR(EnumDescriptor, value, + const EnumValueDescriptor*) +PROTOBUF_DEFINE_OPTIONS_ACCESSOR(EnumDescriptor, EnumOptions) +PROTOBUF_DEFINE_ACCESSOR(EnumDescriptor, is_placeholder, bool) +PROTOBUF_DEFINE_ACCESSOR(EnumDescriptor, reserved_range_count, int) +PROTOBUF_DEFINE_ARRAY_ACCESSOR(EnumDescriptor, reserved_range, + const EnumDescriptor::ReservedRange*) +PROTOBUF_DEFINE_ACCESSOR(EnumDescriptor, reserved_name_count, int) + +PROTOBUF_DEFINE_NAME_ACCESSOR(EnumValueDescriptor) +PROTOBUF_DEFINE_ACCESSOR(EnumValueDescriptor, number, int) +PROTOBUF_DEFINE_ACCESSOR(EnumValueDescriptor, type, const EnumDescriptor*) +PROTOBUF_DEFINE_OPTIONS_ACCESSOR(EnumValueDescriptor, EnumValueOptions) + +PROTOBUF_DEFINE_NAME_ACCESSOR(ServiceDescriptor) +PROTOBUF_DEFINE_ACCESSOR(ServiceDescriptor, file, const FileDescriptor*) +PROTOBUF_DEFINE_ACCESSOR(ServiceDescriptor, method_count, int) +PROTOBUF_DEFINE_ARRAY_ACCESSOR(ServiceDescriptor, method, + const MethodDescriptor*) +PROTOBUF_DEFINE_OPTIONS_ACCESSOR(ServiceDescriptor, ServiceOptions) + +PROTOBUF_DEFINE_NAME_ACCESSOR(MethodDescriptor) +PROTOBUF_DEFINE_ACCESSOR(MethodDescriptor, service, const ServiceDescriptor*) +PROTOBUF_DEFINE_OPTIONS_ACCESSOR(MethodDescriptor, MethodOptions) +PROTOBUF_DEFINE_ACCESSOR(MethodDescriptor, client_streaming, bool) +PROTOBUF_DEFINE_ACCESSOR(MethodDescriptor, server_streaming, bool) + +PROTOBUF_DEFINE_STRING_ACCESSOR(FileDescriptor, name) +PROTOBUF_DEFINE_STRING_ACCESSOR(FileDescriptor, package) +PROTOBUF_DEFINE_ACCESSOR(FileDescriptor, pool, const DescriptorPool*) +PROTOBUF_DEFINE_ACCESSOR(FileDescriptor, dependency_count, int) +PROTOBUF_DEFINE_ACCESSOR(FileDescriptor, public_dependency_count, int) +PROTOBUF_DEFINE_ACCESSOR(FileDescriptor, weak_dependency_count, int) +PROTOBUF_DEFINE_ACCESSOR(FileDescriptor, message_type_count, int) +PROTOBUF_DEFINE_ACCESSOR(FileDescriptor, enum_type_count, int) +PROTOBUF_DEFINE_ACCESSOR(FileDescriptor, service_count, int) +PROTOBUF_DEFINE_ACCESSOR(FileDescriptor, extension_count, int) +PROTOBUF_DEFINE_OPTIONS_ACCESSOR(FileDescriptor, FileOptions) +PROTOBUF_DEFINE_ACCESSOR(FileDescriptor, is_placeholder, bool) + +PROTOBUF_DEFINE_ARRAY_ACCESSOR(FileDescriptor, message_type, const Descriptor*) +PROTOBUF_DEFINE_ARRAY_ACCESSOR(FileDescriptor, enum_type, const EnumDescriptor*) +PROTOBUF_DEFINE_ARRAY_ACCESSOR(FileDescriptor, service, + const ServiceDescriptor*) +PROTOBUF_DEFINE_ARRAY_ACCESSOR(FileDescriptor, extension, + const FieldDescriptor*) + +#undef PROTOBUF_DEFINE_ACCESSOR +#undef PROTOBUF_DEFINE_STRING_ACCESSOR +#undef PROTOBUF_DEFINE_ARRAY_ACCESSOR + +// A few accessors differ from the macros... + +inline Descriptor::WellKnownType Descriptor::well_known_type() const { + return static_cast<Descriptor::WellKnownType>(well_known_type_); +} + +inline bool Descriptor::IsExtensionNumber(int number) const { + return FindExtensionRangeContainingNumber(number) != nullptr; +} + +inline bool Descriptor::IsReservedNumber(int number) const { + return FindReservedRangeContainingNumber(number) != nullptr; +} + +inline bool Descriptor::IsReservedName(ConstStringParam name) const { + for (int i = 0; i < reserved_name_count(); i++) { + if (name == static_cast<ConstStringParam>(reserved_name(i))) { + return true; + } + } + return false; +} + +// Can't use PROTOBUF_DEFINE_ARRAY_ACCESSOR because reserved_names_ is actually +// an array of pointers rather than the usual array of objects. +inline const TProtoStringType& Descriptor::reserved_name(int index) const { + return *reserved_names_[index]; +} + +inline bool EnumDescriptor::IsReservedNumber(int number) const { + return FindReservedRangeContainingNumber(number) != nullptr; +} + +inline bool EnumDescriptor::IsReservedName(ConstStringParam name) const { + for (int i = 0; i < reserved_name_count(); i++) { + if (name == static_cast<ConstStringParam>(reserved_name(i))) { + return true; + } + } + return false; +} + +// Can't use PROTOBUF_DEFINE_ARRAY_ACCESSOR because reserved_names_ is actually +// an array of pointers rather than the usual array of objects. +inline const TProtoStringType& EnumDescriptor::reserved_name(int index) const { + return *reserved_names_[index]; +} + +inline const TProtoStringType& FieldDescriptor::lowercase_name() const { + return all_names_[lowercase_name_index_]; +} + +inline const TProtoStringType& FieldDescriptor::camelcase_name() const { + return all_names_[camelcase_name_index_]; +} + +inline const TProtoStringType& FieldDescriptor::json_name() const { + return all_names_[json_name_index_]; +} + +inline const OneofDescriptor* FieldDescriptor::containing_oneof() const { + return is_oneof_ ? scope_.containing_oneof : nullptr; +} + +inline int FieldDescriptor::index_in_oneof() const { + GOOGLE_DCHECK(is_oneof_); + return static_cast<int>(this - scope_.containing_oneof->field(0)); +} + +inline const Descriptor* FieldDescriptor::extension_scope() const { + GOOGLE_CHECK(is_extension_); + return scope_.extension_scope; +} + +inline FieldDescriptor::Label FieldDescriptor::label() const { + return static_cast<Label>(label_); +} + +inline FieldDescriptor::Type FieldDescriptor::type() const { + if (type_once_) { + internal::call_once(*type_once_, &FieldDescriptor::TypeOnceInit, this); + } + return static_cast<Type>(type_); +} + +inline bool FieldDescriptor::is_required() const { + return label() == LABEL_REQUIRED; +} + +inline bool FieldDescriptor::is_optional() const { + return label() == LABEL_OPTIONAL; +} + +inline bool FieldDescriptor::is_repeated() const { + return label() == LABEL_REPEATED; +} + +inline bool FieldDescriptor::is_packable() const { + return is_repeated() && IsTypePackable(type()); +} + +inline bool FieldDescriptor::is_map() const { + return type() == TYPE_MESSAGE && is_map_message_type(); +} + +inline bool FieldDescriptor::has_optional_keyword() const { + return proto3_optional_ || + (file()->syntax() == FileDescriptor::SYNTAX_PROTO2 && is_optional() && + !containing_oneof()); +} + +inline const OneofDescriptor* FieldDescriptor::real_containing_oneof() const { + auto* oneof = containing_oneof(); + return oneof && !oneof->is_synthetic() ? oneof : nullptr; +} + +inline bool FieldDescriptor::has_presence() const { + if (is_repeated()) return false; + return cpp_type() == CPPTYPE_MESSAGE || containing_oneof() || + file()->syntax() == FileDescriptor::SYNTAX_PROTO2; +} + +// To save space, index() is computed by looking at the descriptor's position +// in the parent's array of children. +inline int FieldDescriptor::index() const { + if (!is_extension_) { + return static_cast<int>(this - containing_type()->fields_); + } else if (extension_scope() != nullptr) { + return static_cast<int>(this - extension_scope()->extensions_); + } else { + return static_cast<int>(this - file_->extensions_); + } +} + +inline int Descriptor::index() const { + if (containing_type_ == nullptr) { + return static_cast<int>(this - file_->message_types_); + } else { + return static_cast<int>(this - containing_type_->nested_types_); + } +} + +inline const FileDescriptor* OneofDescriptor::file() const { + return containing_type()->file(); +} + +inline int OneofDescriptor::index() const { + return static_cast<int>(this - containing_type_->oneof_decls_); +} + +inline bool OneofDescriptor::is_synthetic() const { + return field_count() == 1 && field(0)->proto3_optional_; +} + +inline int EnumDescriptor::index() const { + if (containing_type_ == nullptr) { + return static_cast<int>(this - file_->enum_types_); + } else { + return static_cast<int>(this - containing_type_->enum_types_); + } +} + +inline const FileDescriptor* EnumValueDescriptor::file() const { + return type()->file(); +} + +inline int EnumValueDescriptor::index() const { + return static_cast<int>(this - type_->values_); +} + +inline int ServiceDescriptor::index() const { + return static_cast<int>(this - file_->services_); +} + +inline const FileDescriptor* MethodDescriptor::file() const { + return service()->file(); +} + +inline int MethodDescriptor::index() const { + return static_cast<int>(this - service_->methods_); +} + +inline const char* FieldDescriptor::type_name() const { + return kTypeToName[type()]; +} + +inline FieldDescriptor::CppType FieldDescriptor::cpp_type() const { + return kTypeToCppTypeMap[type()]; +} + +inline const char* FieldDescriptor::cpp_type_name() const { + return kCppTypeToName[kTypeToCppTypeMap[type()]]; +} + +inline FieldDescriptor::CppType FieldDescriptor::TypeToCppType(Type type) { + return kTypeToCppTypeMap[type]; +} + +inline const char* FieldDescriptor::TypeName(Type type) { + return kTypeToName[type]; +} + +inline const char* FieldDescriptor::CppTypeName(CppType cpp_type) { + return kCppTypeToName[cpp_type]; +} + +inline bool FieldDescriptor::IsTypePackable(Type field_type) { + return (field_type != FieldDescriptor::TYPE_STRING && + field_type != FieldDescriptor::TYPE_GROUP && + field_type != FieldDescriptor::TYPE_MESSAGE && + field_type != FieldDescriptor::TYPE_BYTES); +} + +inline const FileDescriptor* FileDescriptor::public_dependency( + int index) const { + return dependency(public_dependencies_[index]); +} + +inline const FileDescriptor* FileDescriptor::weak_dependency(int index) const { + return dependency(weak_dependencies_[index]); +} + +inline FileDescriptor::Syntax FileDescriptor::syntax() const { + return static_cast<Syntax>(syntax_); +} + +} // namespace protobuf +} // namespace google + +#include <google/protobuf/port_undef.inc> + +#endif // GOOGLE_PROTOBUF_DESCRIPTOR_H__ diff --git a/contrib/libs/protobuf_old/src/google/protobuf/descriptor.pb.cc b/contrib/libs/protobuf_old/src/google/protobuf/descriptor.pb.cc new file mode 100644 index 0000000000..928223de68 --- /dev/null +++ b/contrib/libs/protobuf_old/src/google/protobuf/descriptor.pb.cc @@ -0,0 +1,11125 @@ +// Generated by the protocol buffer compiler. DO NOT EDIT! +// source: google/protobuf/descriptor.proto + +#include <google/protobuf/descriptor.pb.h> + +#include <algorithm> + +#include <google/protobuf/io/coded_stream.h> +#include <google/protobuf/extension_set.h> +#include <google/protobuf/wire_format_lite.h> +#include <google/protobuf/descriptor.h> +#include <google/protobuf/generated_message_reflection.h> +#include <google/protobuf/reflection_ops.h> +#include <google/protobuf/wire_format.h> +// @@protoc_insertion_point(includes) +#include <google/protobuf/port_def.inc> + +PROTOBUF_PRAGMA_INIT_SEG +PROTOBUF_NAMESPACE_OPEN +constexpr FileDescriptorSet::FileDescriptorSet( + ::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized) + : file_(){} +struct FileDescriptorSetDefaultTypeInternal { + constexpr FileDescriptorSetDefaultTypeInternal() + : _instance(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized{}) {} + ~FileDescriptorSetDefaultTypeInternal() {} + union { + FileDescriptorSet _instance; + }; +}; +PROTOBUF_ATTRIBUTE_NO_DESTROY PROTOBUF_CONSTINIT FileDescriptorSetDefaultTypeInternal _FileDescriptorSet_default_instance_; +constexpr FileDescriptorProto::FileDescriptorProto( + ::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized) + : dependency_() + , message_type_() + , enum_type_() + , service_() + , extension_() + , public_dependency_() + , weak_dependency_() + , name_(&::PROTOBUF_NAMESPACE_ID::internal::fixed_address_empty_string) + , package_(&::PROTOBUF_NAMESPACE_ID::internal::fixed_address_empty_string) + , syntax_(&::PROTOBUF_NAMESPACE_ID::internal::fixed_address_empty_string) + , options_(nullptr) + , source_code_info_(nullptr){} +struct FileDescriptorProtoDefaultTypeInternal { + constexpr FileDescriptorProtoDefaultTypeInternal() + : _instance(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized{}) {} + ~FileDescriptorProtoDefaultTypeInternal() {} + union { + FileDescriptorProto _instance; + }; +}; +PROTOBUF_ATTRIBUTE_NO_DESTROY PROTOBUF_CONSTINIT FileDescriptorProtoDefaultTypeInternal _FileDescriptorProto_default_instance_; +constexpr DescriptorProto_ExtensionRange::DescriptorProto_ExtensionRange( + ::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized) + : options_(nullptr) + , start_(0) + , end_(0){} +struct DescriptorProto_ExtensionRangeDefaultTypeInternal { + constexpr DescriptorProto_ExtensionRangeDefaultTypeInternal() + : _instance(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized{}) {} + ~DescriptorProto_ExtensionRangeDefaultTypeInternal() {} + union { + DescriptorProto_ExtensionRange _instance; + }; +}; +PROTOBUF_ATTRIBUTE_NO_DESTROY PROTOBUF_CONSTINIT DescriptorProto_ExtensionRangeDefaultTypeInternal _DescriptorProto_ExtensionRange_default_instance_; +constexpr DescriptorProto_ReservedRange::DescriptorProto_ReservedRange( + ::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized) + : start_(0) + , end_(0){} +struct DescriptorProto_ReservedRangeDefaultTypeInternal { + constexpr DescriptorProto_ReservedRangeDefaultTypeInternal() + : _instance(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized{}) {} + ~DescriptorProto_ReservedRangeDefaultTypeInternal() {} + union { + DescriptorProto_ReservedRange _instance; + }; +}; +PROTOBUF_ATTRIBUTE_NO_DESTROY PROTOBUF_CONSTINIT DescriptorProto_ReservedRangeDefaultTypeInternal _DescriptorProto_ReservedRange_default_instance_; +constexpr DescriptorProto::DescriptorProto( + ::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized) + : field_() + , nested_type_() + , enum_type_() + , extension_range_() + , extension_() + , oneof_decl_() + , reserved_range_() + , reserved_name_() + , name_(&::PROTOBUF_NAMESPACE_ID::internal::fixed_address_empty_string) + , options_(nullptr){} +struct DescriptorProtoDefaultTypeInternal { + constexpr DescriptorProtoDefaultTypeInternal() + : _instance(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized{}) {} + ~DescriptorProtoDefaultTypeInternal() {} + union { + DescriptorProto _instance; + }; +}; +PROTOBUF_ATTRIBUTE_NO_DESTROY PROTOBUF_CONSTINIT DescriptorProtoDefaultTypeInternal _DescriptorProto_default_instance_; +constexpr ExtensionRangeOptions::ExtensionRangeOptions( + ::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized) + : uninterpreted_option_(){} +struct ExtensionRangeOptionsDefaultTypeInternal { + constexpr ExtensionRangeOptionsDefaultTypeInternal() + : _instance(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized{}) {} + ~ExtensionRangeOptionsDefaultTypeInternal() {} + union { + ExtensionRangeOptions _instance; + }; +}; +PROTOBUF_ATTRIBUTE_NO_DESTROY PROTOBUF_CONSTINIT ExtensionRangeOptionsDefaultTypeInternal _ExtensionRangeOptions_default_instance_; +constexpr FieldDescriptorProto::FieldDescriptorProto( + ::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized) + : name_(&::PROTOBUF_NAMESPACE_ID::internal::fixed_address_empty_string) + , extendee_(&::PROTOBUF_NAMESPACE_ID::internal::fixed_address_empty_string) + , type_name_(&::PROTOBUF_NAMESPACE_ID::internal::fixed_address_empty_string) + , default_value_(&::PROTOBUF_NAMESPACE_ID::internal::fixed_address_empty_string) + , json_name_(&::PROTOBUF_NAMESPACE_ID::internal::fixed_address_empty_string) + , options_(nullptr) + , number_(0) + , oneof_index_(0) + , proto3_optional_(false) + , label_(1) + + , type_(1) +{} +struct FieldDescriptorProtoDefaultTypeInternal { + constexpr FieldDescriptorProtoDefaultTypeInternal() + : _instance(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized{}) {} + ~FieldDescriptorProtoDefaultTypeInternal() {} + union { + FieldDescriptorProto _instance; + }; +}; +PROTOBUF_ATTRIBUTE_NO_DESTROY PROTOBUF_CONSTINIT FieldDescriptorProtoDefaultTypeInternal _FieldDescriptorProto_default_instance_; +constexpr OneofDescriptorProto::OneofDescriptorProto( + ::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized) + : name_(&::PROTOBUF_NAMESPACE_ID::internal::fixed_address_empty_string) + , options_(nullptr){} +struct OneofDescriptorProtoDefaultTypeInternal { + constexpr OneofDescriptorProtoDefaultTypeInternal() + : _instance(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized{}) {} + ~OneofDescriptorProtoDefaultTypeInternal() {} + union { + OneofDescriptorProto _instance; + }; +}; +PROTOBUF_ATTRIBUTE_NO_DESTROY PROTOBUF_CONSTINIT OneofDescriptorProtoDefaultTypeInternal _OneofDescriptorProto_default_instance_; +constexpr EnumDescriptorProto_EnumReservedRange::EnumDescriptorProto_EnumReservedRange( + ::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized) + : start_(0) + , end_(0){} +struct EnumDescriptorProto_EnumReservedRangeDefaultTypeInternal { + constexpr EnumDescriptorProto_EnumReservedRangeDefaultTypeInternal() + : _instance(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized{}) {} + ~EnumDescriptorProto_EnumReservedRangeDefaultTypeInternal() {} + union { + EnumDescriptorProto_EnumReservedRange _instance; + }; +}; +PROTOBUF_ATTRIBUTE_NO_DESTROY PROTOBUF_CONSTINIT EnumDescriptorProto_EnumReservedRangeDefaultTypeInternal _EnumDescriptorProto_EnumReservedRange_default_instance_; +constexpr EnumDescriptorProto::EnumDescriptorProto( + ::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized) + : value_() + , reserved_range_() + , reserved_name_() + , name_(&::PROTOBUF_NAMESPACE_ID::internal::fixed_address_empty_string) + , options_(nullptr){} +struct EnumDescriptorProtoDefaultTypeInternal { + constexpr EnumDescriptorProtoDefaultTypeInternal() + : _instance(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized{}) {} + ~EnumDescriptorProtoDefaultTypeInternal() {} + union { + EnumDescriptorProto _instance; + }; +}; +PROTOBUF_ATTRIBUTE_NO_DESTROY PROTOBUF_CONSTINIT EnumDescriptorProtoDefaultTypeInternal _EnumDescriptorProto_default_instance_; +constexpr EnumValueDescriptorProto::EnumValueDescriptorProto( + ::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized) + : name_(&::PROTOBUF_NAMESPACE_ID::internal::fixed_address_empty_string) + , options_(nullptr) + , number_(0){} +struct EnumValueDescriptorProtoDefaultTypeInternal { + constexpr EnumValueDescriptorProtoDefaultTypeInternal() + : _instance(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized{}) {} + ~EnumValueDescriptorProtoDefaultTypeInternal() {} + union { + EnumValueDescriptorProto _instance; + }; +}; +PROTOBUF_ATTRIBUTE_NO_DESTROY PROTOBUF_CONSTINIT EnumValueDescriptorProtoDefaultTypeInternal _EnumValueDescriptorProto_default_instance_; +constexpr ServiceDescriptorProto::ServiceDescriptorProto( + ::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized) + : method_() + , name_(&::PROTOBUF_NAMESPACE_ID::internal::fixed_address_empty_string) + , options_(nullptr){} +struct ServiceDescriptorProtoDefaultTypeInternal { + constexpr ServiceDescriptorProtoDefaultTypeInternal() + : _instance(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized{}) {} + ~ServiceDescriptorProtoDefaultTypeInternal() {} + union { + ServiceDescriptorProto _instance; + }; +}; +PROTOBUF_ATTRIBUTE_NO_DESTROY PROTOBUF_CONSTINIT ServiceDescriptorProtoDefaultTypeInternal _ServiceDescriptorProto_default_instance_; +constexpr MethodDescriptorProto::MethodDescriptorProto( + ::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized) + : name_(&::PROTOBUF_NAMESPACE_ID::internal::fixed_address_empty_string) + , input_type_(&::PROTOBUF_NAMESPACE_ID::internal::fixed_address_empty_string) + , output_type_(&::PROTOBUF_NAMESPACE_ID::internal::fixed_address_empty_string) + , options_(nullptr) + , client_streaming_(false) + , server_streaming_(false){} +struct MethodDescriptorProtoDefaultTypeInternal { + constexpr MethodDescriptorProtoDefaultTypeInternal() + : _instance(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized{}) {} + ~MethodDescriptorProtoDefaultTypeInternal() {} + union { + MethodDescriptorProto _instance; + }; +}; +PROTOBUF_ATTRIBUTE_NO_DESTROY PROTOBUF_CONSTINIT MethodDescriptorProtoDefaultTypeInternal _MethodDescriptorProto_default_instance_; +constexpr FileOptions::FileOptions( + ::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized) + : uninterpreted_option_() + , java_package_(&::PROTOBUF_NAMESPACE_ID::internal::fixed_address_empty_string) + , java_outer_classname_(&::PROTOBUF_NAMESPACE_ID::internal::fixed_address_empty_string) + , go_package_(&::PROTOBUF_NAMESPACE_ID::internal::fixed_address_empty_string) + , objc_class_prefix_(&::PROTOBUF_NAMESPACE_ID::internal::fixed_address_empty_string) + , csharp_namespace_(&::PROTOBUF_NAMESPACE_ID::internal::fixed_address_empty_string) + , swift_prefix_(&::PROTOBUF_NAMESPACE_ID::internal::fixed_address_empty_string) + , php_class_prefix_(&::PROTOBUF_NAMESPACE_ID::internal::fixed_address_empty_string) + , php_namespace_(&::PROTOBUF_NAMESPACE_ID::internal::fixed_address_empty_string) + , php_metadata_namespace_(&::PROTOBUF_NAMESPACE_ID::internal::fixed_address_empty_string) + , ruby_package_(&::PROTOBUF_NAMESPACE_ID::internal::fixed_address_empty_string) + , java_multiple_files_(false) + , java_generate_equals_and_hash_(false) + , java_string_check_utf8_(false) + , cc_generic_services_(false) + , java_generic_services_(false) + , py_generic_services_(false) + , php_generic_services_(false) + , deprecated_(false) + , optimize_for_(1) + + , cc_enable_arenas_(true){} +struct FileOptionsDefaultTypeInternal { + constexpr FileOptionsDefaultTypeInternal() + : _instance(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized{}) {} + ~FileOptionsDefaultTypeInternal() {} + union { + FileOptions _instance; + }; +}; +PROTOBUF_ATTRIBUTE_NO_DESTROY PROTOBUF_CONSTINIT FileOptionsDefaultTypeInternal _FileOptions_default_instance_; +constexpr MessageOptions::MessageOptions( + ::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized) + : uninterpreted_option_() + , message_set_wire_format_(false) + , no_standard_descriptor_accessor_(false) + , deprecated_(false) + , map_entry_(false){} +struct MessageOptionsDefaultTypeInternal { + constexpr MessageOptionsDefaultTypeInternal() + : _instance(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized{}) {} + ~MessageOptionsDefaultTypeInternal() {} + union { + MessageOptions _instance; + }; +}; +PROTOBUF_ATTRIBUTE_NO_DESTROY PROTOBUF_CONSTINIT MessageOptionsDefaultTypeInternal _MessageOptions_default_instance_; +constexpr FieldOptions::FieldOptions( + ::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized) + : uninterpreted_option_() + , ctype_(0) + + , packed_(false) + , lazy_(false) + , deprecated_(false) + , weak_(false) + , jstype_(0) +{} +struct FieldOptionsDefaultTypeInternal { + constexpr FieldOptionsDefaultTypeInternal() + : _instance(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized{}) {} + ~FieldOptionsDefaultTypeInternal() {} + union { + FieldOptions _instance; + }; +}; +PROTOBUF_ATTRIBUTE_NO_DESTROY PROTOBUF_CONSTINIT FieldOptionsDefaultTypeInternal _FieldOptions_default_instance_; +constexpr OneofOptions::OneofOptions( + ::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized) + : uninterpreted_option_(){} +struct OneofOptionsDefaultTypeInternal { + constexpr OneofOptionsDefaultTypeInternal() + : _instance(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized{}) {} + ~OneofOptionsDefaultTypeInternal() {} + union { + OneofOptions _instance; + }; +}; +PROTOBUF_ATTRIBUTE_NO_DESTROY PROTOBUF_CONSTINIT OneofOptionsDefaultTypeInternal _OneofOptions_default_instance_; +constexpr EnumOptions::EnumOptions( + ::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized) + : uninterpreted_option_() + , allow_alias_(false) + , deprecated_(false){} +struct EnumOptionsDefaultTypeInternal { + constexpr EnumOptionsDefaultTypeInternal() + : _instance(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized{}) {} + ~EnumOptionsDefaultTypeInternal() {} + union { + EnumOptions _instance; + }; +}; +PROTOBUF_ATTRIBUTE_NO_DESTROY PROTOBUF_CONSTINIT EnumOptionsDefaultTypeInternal _EnumOptions_default_instance_; +constexpr EnumValueOptions::EnumValueOptions( + ::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized) + : uninterpreted_option_() + , deprecated_(false){} +struct EnumValueOptionsDefaultTypeInternal { + constexpr EnumValueOptionsDefaultTypeInternal() + : _instance(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized{}) {} + ~EnumValueOptionsDefaultTypeInternal() {} + union { + EnumValueOptions _instance; + }; +}; +PROTOBUF_ATTRIBUTE_NO_DESTROY PROTOBUF_CONSTINIT EnumValueOptionsDefaultTypeInternal _EnumValueOptions_default_instance_; +constexpr ServiceOptions::ServiceOptions( + ::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized) + : uninterpreted_option_() + , deprecated_(false){} +struct ServiceOptionsDefaultTypeInternal { + constexpr ServiceOptionsDefaultTypeInternal() + : _instance(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized{}) {} + ~ServiceOptionsDefaultTypeInternal() {} + union { + ServiceOptions _instance; + }; +}; +PROTOBUF_ATTRIBUTE_NO_DESTROY PROTOBUF_CONSTINIT ServiceOptionsDefaultTypeInternal _ServiceOptions_default_instance_; +constexpr MethodOptions::MethodOptions( + ::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized) + : uninterpreted_option_() + , deprecated_(false) + , idempotency_level_(0) +{} +struct MethodOptionsDefaultTypeInternal { + constexpr MethodOptionsDefaultTypeInternal() + : _instance(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized{}) {} + ~MethodOptionsDefaultTypeInternal() {} + union { + MethodOptions _instance; + }; +}; +PROTOBUF_ATTRIBUTE_NO_DESTROY PROTOBUF_CONSTINIT MethodOptionsDefaultTypeInternal _MethodOptions_default_instance_; +constexpr UninterpretedOption_NamePart::UninterpretedOption_NamePart( + ::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized) + : name_part_(&::PROTOBUF_NAMESPACE_ID::internal::fixed_address_empty_string) + , is_extension_(false){} +struct UninterpretedOption_NamePartDefaultTypeInternal { + constexpr UninterpretedOption_NamePartDefaultTypeInternal() + : _instance(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized{}) {} + ~UninterpretedOption_NamePartDefaultTypeInternal() {} + union { + UninterpretedOption_NamePart _instance; + }; +}; +PROTOBUF_ATTRIBUTE_NO_DESTROY PROTOBUF_CONSTINIT UninterpretedOption_NamePartDefaultTypeInternal _UninterpretedOption_NamePart_default_instance_; +constexpr UninterpretedOption::UninterpretedOption( + ::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized) + : name_() + , identifier_value_(&::PROTOBUF_NAMESPACE_ID::internal::fixed_address_empty_string) + , string_value_(&::PROTOBUF_NAMESPACE_ID::internal::fixed_address_empty_string) + , aggregate_value_(&::PROTOBUF_NAMESPACE_ID::internal::fixed_address_empty_string) + , positive_int_value_(arc_ui64{0u}) + , negative_int_value_(arc_i64{0}) + , double_value_(0){} +struct UninterpretedOptionDefaultTypeInternal { + constexpr UninterpretedOptionDefaultTypeInternal() + : _instance(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized{}) {} + ~UninterpretedOptionDefaultTypeInternal() {} + union { + UninterpretedOption _instance; + }; +}; +PROTOBUF_ATTRIBUTE_NO_DESTROY PROTOBUF_CONSTINIT UninterpretedOptionDefaultTypeInternal _UninterpretedOption_default_instance_; +constexpr SourceCodeInfo_Location::SourceCodeInfo_Location( + ::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized) + : path_() + , _path_cached_byte_size_(0) + , span_() + , _span_cached_byte_size_(0) + , leading_detached_comments_() + , leading_comments_(&::PROTOBUF_NAMESPACE_ID::internal::fixed_address_empty_string) + , trailing_comments_(&::PROTOBUF_NAMESPACE_ID::internal::fixed_address_empty_string){} +struct SourceCodeInfo_LocationDefaultTypeInternal { + constexpr SourceCodeInfo_LocationDefaultTypeInternal() + : _instance(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized{}) {} + ~SourceCodeInfo_LocationDefaultTypeInternal() {} + union { + SourceCodeInfo_Location _instance; + }; +}; +PROTOBUF_ATTRIBUTE_NO_DESTROY PROTOBUF_CONSTINIT SourceCodeInfo_LocationDefaultTypeInternal _SourceCodeInfo_Location_default_instance_; +constexpr SourceCodeInfo::SourceCodeInfo( + ::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized) + : location_(){} +struct SourceCodeInfoDefaultTypeInternal { + constexpr SourceCodeInfoDefaultTypeInternal() + : _instance(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized{}) {} + ~SourceCodeInfoDefaultTypeInternal() {} + union { + SourceCodeInfo _instance; + }; +}; +PROTOBUF_ATTRIBUTE_NO_DESTROY PROTOBUF_CONSTINIT SourceCodeInfoDefaultTypeInternal _SourceCodeInfo_default_instance_; +constexpr GeneratedCodeInfo_Annotation::GeneratedCodeInfo_Annotation( + ::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized) + : path_() + , _path_cached_byte_size_(0) + , source_file_(&::PROTOBUF_NAMESPACE_ID::internal::fixed_address_empty_string) + , begin_(0) + , end_(0){} +struct GeneratedCodeInfo_AnnotationDefaultTypeInternal { + constexpr GeneratedCodeInfo_AnnotationDefaultTypeInternal() + : _instance(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized{}) {} + ~GeneratedCodeInfo_AnnotationDefaultTypeInternal() {} + union { + GeneratedCodeInfo_Annotation _instance; + }; +}; +PROTOBUF_ATTRIBUTE_NO_DESTROY PROTOBUF_CONSTINIT GeneratedCodeInfo_AnnotationDefaultTypeInternal _GeneratedCodeInfo_Annotation_default_instance_; +constexpr GeneratedCodeInfo::GeneratedCodeInfo( + ::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized) + : annotation_(){} +struct GeneratedCodeInfoDefaultTypeInternal { + constexpr GeneratedCodeInfoDefaultTypeInternal() + : _instance(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized{}) {} + ~GeneratedCodeInfoDefaultTypeInternal() {} + union { + GeneratedCodeInfo _instance; + }; +}; +PROTOBUF_ATTRIBUTE_NO_DESTROY PROTOBUF_CONSTINIT GeneratedCodeInfoDefaultTypeInternal _GeneratedCodeInfo_default_instance_; +PROTOBUF_NAMESPACE_CLOSE +static ::PROTOBUF_NAMESPACE_ID::Metadata file_level_metadata_google_2fprotobuf_2fdescriptor_2eproto[27]; +static const ::PROTOBUF_NAMESPACE_ID::EnumDescriptor* file_level_enum_descriptors_google_2fprotobuf_2fdescriptor_2eproto[6]; +static constexpr ::PROTOBUF_NAMESPACE_ID::ServiceDescriptor const** file_level_service_descriptors_google_2fprotobuf_2fdescriptor_2eproto = nullptr; + +const arc_ui32 TableStruct_google_2fprotobuf_2fdescriptor_2eproto::offsets[] PROTOBUF_SECTION_VARIABLE(protodesc_cold) = { + ~0u, // no _has_bits_ + PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::FileDescriptorSet, _internal_metadata_), + ~0u, // no _extensions_ + ~0u, // no _oneof_case_ + ~0u, // no _weak_field_map_ + ~0u, // no _inlined_string_donated_ + PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::FileDescriptorSet, file_), + PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::FileDescriptorProto, _has_bits_), + PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::FileDescriptorProto, _internal_metadata_), + ~0u, // no _extensions_ + ~0u, // no _oneof_case_ + ~0u, // no _weak_field_map_ + ~0u, // no _inlined_string_donated_ + PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::FileDescriptorProto, name_), + PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::FileDescriptorProto, package_), + PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::FileDescriptorProto, dependency_), + PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::FileDescriptorProto, public_dependency_), + PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::FileDescriptorProto, weak_dependency_), + PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::FileDescriptorProto, message_type_), + PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::FileDescriptorProto, enum_type_), + PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::FileDescriptorProto, service_), + PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::FileDescriptorProto, extension_), + PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::FileDescriptorProto, options_), + PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::FileDescriptorProto, source_code_info_), + PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::FileDescriptorProto, syntax_), + 0, + 1, + ~0u, + ~0u, + ~0u, + ~0u, + ~0u, + ~0u, + ~0u, + 3, + 4, + 2, + PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::DescriptorProto_ExtensionRange, _has_bits_), + PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::DescriptorProto_ExtensionRange, _internal_metadata_), + ~0u, // no _extensions_ + ~0u, // no _oneof_case_ + ~0u, // no _weak_field_map_ + ~0u, // no _inlined_string_donated_ + PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::DescriptorProto_ExtensionRange, start_), + PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::DescriptorProto_ExtensionRange, end_), + PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::DescriptorProto_ExtensionRange, options_), + 1, + 2, + 0, + PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::DescriptorProto_ReservedRange, _has_bits_), + PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::DescriptorProto_ReservedRange, _internal_metadata_), + ~0u, // no _extensions_ + ~0u, // no _oneof_case_ + ~0u, // no _weak_field_map_ + ~0u, // no _inlined_string_donated_ + PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::DescriptorProto_ReservedRange, start_), + PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::DescriptorProto_ReservedRange, end_), + 0, + 1, + PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::DescriptorProto, _has_bits_), + PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::DescriptorProto, _internal_metadata_), + ~0u, // no _extensions_ + ~0u, // no _oneof_case_ + ~0u, // no _weak_field_map_ + ~0u, // no _inlined_string_donated_ + PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::DescriptorProto, name_), + PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::DescriptorProto, field_), + PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::DescriptorProto, extension_), + PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::DescriptorProto, nested_type_), + PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::DescriptorProto, enum_type_), + PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::DescriptorProto, extension_range_), + PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::DescriptorProto, oneof_decl_), + PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::DescriptorProto, options_), + PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::DescriptorProto, reserved_range_), + PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::DescriptorProto, reserved_name_), + 0, + ~0u, + ~0u, + ~0u, + ~0u, + ~0u, + ~0u, + 1, + ~0u, + ~0u, + ~0u, // no _has_bits_ + PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::ExtensionRangeOptions, _internal_metadata_), + PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::ExtensionRangeOptions, _extensions_), + ~0u, // no _oneof_case_ + ~0u, // no _weak_field_map_ + ~0u, // no _inlined_string_donated_ + PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::ExtensionRangeOptions, uninterpreted_option_), + PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::FieldDescriptorProto, _has_bits_), + PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::FieldDescriptorProto, _internal_metadata_), + ~0u, // no _extensions_ + ~0u, // no _oneof_case_ + ~0u, // no _weak_field_map_ + ~0u, // no _inlined_string_donated_ + PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::FieldDescriptorProto, name_), + PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::FieldDescriptorProto, number_), + PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::FieldDescriptorProto, label_), + PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::FieldDescriptorProto, type_), + PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::FieldDescriptorProto, type_name_), + PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::FieldDescriptorProto, extendee_), + PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::FieldDescriptorProto, default_value_), + PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::FieldDescriptorProto, oneof_index_), + PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::FieldDescriptorProto, json_name_), + PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::FieldDescriptorProto, options_), + PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::FieldDescriptorProto, proto3_optional_), + 0, + 6, + 9, + 10, + 2, + 1, + 3, + 7, + 4, + 5, + 8, + PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::OneofDescriptorProto, _has_bits_), + PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::OneofDescriptorProto, _internal_metadata_), + ~0u, // no _extensions_ + ~0u, // no _oneof_case_ + ~0u, // no _weak_field_map_ + ~0u, // no _inlined_string_donated_ + PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::OneofDescriptorProto, name_), + PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::OneofDescriptorProto, options_), + 0, + 1, + PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::EnumDescriptorProto_EnumReservedRange, _has_bits_), + PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::EnumDescriptorProto_EnumReservedRange, _internal_metadata_), + ~0u, // no _extensions_ + ~0u, // no _oneof_case_ + ~0u, // no _weak_field_map_ + ~0u, // no _inlined_string_donated_ + PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::EnumDescriptorProto_EnumReservedRange, start_), + PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::EnumDescriptorProto_EnumReservedRange, end_), + 0, + 1, + PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::EnumDescriptorProto, _has_bits_), + PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::EnumDescriptorProto, _internal_metadata_), + ~0u, // no _extensions_ + ~0u, // no _oneof_case_ + ~0u, // no _weak_field_map_ + ~0u, // no _inlined_string_donated_ + PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::EnumDescriptorProto, name_), + PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::EnumDescriptorProto, value_), + PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::EnumDescriptorProto, options_), + PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::EnumDescriptorProto, reserved_range_), + PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::EnumDescriptorProto, reserved_name_), + 0, + ~0u, + 1, + ~0u, + ~0u, + PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::EnumValueDescriptorProto, _has_bits_), + PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::EnumValueDescriptorProto, _internal_metadata_), + ~0u, // no _extensions_ + ~0u, // no _oneof_case_ + ~0u, // no _weak_field_map_ + ~0u, // no _inlined_string_donated_ + PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::EnumValueDescriptorProto, name_), + PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::EnumValueDescriptorProto, number_), + PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::EnumValueDescriptorProto, options_), + 0, + 2, + 1, + PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::ServiceDescriptorProto, _has_bits_), + PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::ServiceDescriptorProto, _internal_metadata_), + ~0u, // no _extensions_ + ~0u, // no _oneof_case_ + ~0u, // no _weak_field_map_ + ~0u, // no _inlined_string_donated_ + PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::ServiceDescriptorProto, name_), + PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::ServiceDescriptorProto, method_), + PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::ServiceDescriptorProto, options_), + 0, + ~0u, + 1, + PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::MethodDescriptorProto, _has_bits_), + PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::MethodDescriptorProto, _internal_metadata_), + ~0u, // no _extensions_ + ~0u, // no _oneof_case_ + ~0u, // no _weak_field_map_ + ~0u, // no _inlined_string_donated_ + PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::MethodDescriptorProto, name_), + PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::MethodDescriptorProto, input_type_), + PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::MethodDescriptorProto, output_type_), + PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::MethodDescriptorProto, options_), + PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::MethodDescriptorProto, client_streaming_), + PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::MethodDescriptorProto, server_streaming_), + 0, + 1, + 2, + 3, + 4, + 5, + PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::FileOptions, _has_bits_), + PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::FileOptions, _internal_metadata_), + PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::FileOptions, _extensions_), + ~0u, // no _oneof_case_ + ~0u, // no _weak_field_map_ + ~0u, // no _inlined_string_donated_ + PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::FileOptions, java_package_), + PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::FileOptions, java_outer_classname_), + PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::FileOptions, java_multiple_files_), + PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::FileOptions, java_generate_equals_and_hash_), + PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::FileOptions, java_string_check_utf8_), + PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::FileOptions, optimize_for_), + PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::FileOptions, go_package_), + PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::FileOptions, cc_generic_services_), + PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::FileOptions, java_generic_services_), + PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::FileOptions, py_generic_services_), + PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::FileOptions, php_generic_services_), + PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::FileOptions, deprecated_), + PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::FileOptions, cc_enable_arenas_), + PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::FileOptions, objc_class_prefix_), + PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::FileOptions, csharp_namespace_), + PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::FileOptions, swift_prefix_), + PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::FileOptions, php_class_prefix_), + PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::FileOptions, php_namespace_), + PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::FileOptions, php_metadata_namespace_), + PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::FileOptions, ruby_package_), + PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::FileOptions, uninterpreted_option_), + 0, + 1, + 10, + 11, + 12, + 18, + 2, + 13, + 14, + 15, + 16, + 17, + 19, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + ~0u, + PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::MessageOptions, _has_bits_), + PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::MessageOptions, _internal_metadata_), + PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::MessageOptions, _extensions_), + ~0u, // no _oneof_case_ + ~0u, // no _weak_field_map_ + ~0u, // no _inlined_string_donated_ + PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::MessageOptions, message_set_wire_format_), + PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::MessageOptions, no_standard_descriptor_accessor_), + PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::MessageOptions, deprecated_), + PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::MessageOptions, map_entry_), + PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::MessageOptions, uninterpreted_option_), + 0, + 1, + 2, + 3, + ~0u, + PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::FieldOptions, _has_bits_), + PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::FieldOptions, _internal_metadata_), + PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::FieldOptions, _extensions_), + ~0u, // no _oneof_case_ + ~0u, // no _weak_field_map_ + ~0u, // no _inlined_string_donated_ + PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::FieldOptions, ctype_), + PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::FieldOptions, packed_), + PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::FieldOptions, jstype_), + PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::FieldOptions, lazy_), + PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::FieldOptions, deprecated_), + PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::FieldOptions, weak_), + PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::FieldOptions, uninterpreted_option_), + 0, + 1, + 5, + 2, + 3, + 4, + ~0u, + ~0u, // no _has_bits_ + PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::OneofOptions, _internal_metadata_), + PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::OneofOptions, _extensions_), + ~0u, // no _oneof_case_ + ~0u, // no _weak_field_map_ + ~0u, // no _inlined_string_donated_ + PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::OneofOptions, uninterpreted_option_), + PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::EnumOptions, _has_bits_), + PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::EnumOptions, _internal_metadata_), + PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::EnumOptions, _extensions_), + ~0u, // no _oneof_case_ + ~0u, // no _weak_field_map_ + ~0u, // no _inlined_string_donated_ + PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::EnumOptions, allow_alias_), + PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::EnumOptions, deprecated_), + PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::EnumOptions, uninterpreted_option_), + 0, + 1, + ~0u, + PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::EnumValueOptions, _has_bits_), + PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::EnumValueOptions, _internal_metadata_), + PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::EnumValueOptions, _extensions_), + ~0u, // no _oneof_case_ + ~0u, // no _weak_field_map_ + ~0u, // no _inlined_string_donated_ + PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::EnumValueOptions, deprecated_), + PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::EnumValueOptions, uninterpreted_option_), + 0, + ~0u, + PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::ServiceOptions, _has_bits_), + PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::ServiceOptions, _internal_metadata_), + PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::ServiceOptions, _extensions_), + ~0u, // no _oneof_case_ + ~0u, // no _weak_field_map_ + ~0u, // no _inlined_string_donated_ + PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::ServiceOptions, deprecated_), + PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::ServiceOptions, uninterpreted_option_), + 0, + ~0u, + PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::MethodOptions, _has_bits_), + PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::MethodOptions, _internal_metadata_), + PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::MethodOptions, _extensions_), + ~0u, // no _oneof_case_ + ~0u, // no _weak_field_map_ + ~0u, // no _inlined_string_donated_ + PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::MethodOptions, deprecated_), + PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::MethodOptions, idempotency_level_), + PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::MethodOptions, uninterpreted_option_), + 0, + 1, + ~0u, + PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::UninterpretedOption_NamePart, _has_bits_), + PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::UninterpretedOption_NamePart, _internal_metadata_), + ~0u, // no _extensions_ + ~0u, // no _oneof_case_ + ~0u, // no _weak_field_map_ + ~0u, // no _inlined_string_donated_ + PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::UninterpretedOption_NamePart, name_part_), + PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::UninterpretedOption_NamePart, is_extension_), + 0, + 1, + PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::UninterpretedOption, _has_bits_), + PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::UninterpretedOption, _internal_metadata_), + ~0u, // no _extensions_ + ~0u, // no _oneof_case_ + ~0u, // no _weak_field_map_ + ~0u, // no _inlined_string_donated_ + PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::UninterpretedOption, name_), + PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::UninterpretedOption, identifier_value_), + PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::UninterpretedOption, positive_int_value_), + PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::UninterpretedOption, negative_int_value_), + PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::UninterpretedOption, double_value_), + PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::UninterpretedOption, string_value_), + PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::UninterpretedOption, aggregate_value_), + ~0u, + 0, + 3, + 4, + 5, + 1, + 2, + PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::SourceCodeInfo_Location, _has_bits_), + PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::SourceCodeInfo_Location, _internal_metadata_), + ~0u, // no _extensions_ + ~0u, // no _oneof_case_ + ~0u, // no _weak_field_map_ + ~0u, // no _inlined_string_donated_ + PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::SourceCodeInfo_Location, path_), + PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::SourceCodeInfo_Location, span_), + PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::SourceCodeInfo_Location, leading_comments_), + PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::SourceCodeInfo_Location, trailing_comments_), + PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::SourceCodeInfo_Location, leading_detached_comments_), + ~0u, + ~0u, + 0, + 1, + ~0u, + ~0u, // no _has_bits_ + PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::SourceCodeInfo, _internal_metadata_), + ~0u, // no _extensions_ + ~0u, // no _oneof_case_ + ~0u, // no _weak_field_map_ + ~0u, // no _inlined_string_donated_ + PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::SourceCodeInfo, location_), + PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::GeneratedCodeInfo_Annotation, _has_bits_), + PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::GeneratedCodeInfo_Annotation, _internal_metadata_), + ~0u, // no _extensions_ + ~0u, // no _oneof_case_ + ~0u, // no _weak_field_map_ + ~0u, // no _inlined_string_donated_ + PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::GeneratedCodeInfo_Annotation, path_), + PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::GeneratedCodeInfo_Annotation, source_file_), + PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::GeneratedCodeInfo_Annotation, begin_), + PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::GeneratedCodeInfo_Annotation, end_), + ~0u, + 0, + 1, + 2, + ~0u, // no _has_bits_ + PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::GeneratedCodeInfo, _internal_metadata_), + ~0u, // no _extensions_ + ~0u, // no _oneof_case_ + ~0u, // no _weak_field_map_ + ~0u, // no _inlined_string_donated_ + PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::GeneratedCodeInfo, annotation_), +}; +static const ::PROTOBUF_NAMESPACE_ID::internal::MigrationSchema schemas[] PROTOBUF_SECTION_VARIABLE(protodesc_cold) = { + { 0, -1, -1, sizeof(::PROTOBUF_NAMESPACE_ID::FileDescriptorSet)}, + { 7, 25, -1, sizeof(::PROTOBUF_NAMESPACE_ID::FileDescriptorProto)}, + { 37, 46, -1, sizeof(::PROTOBUF_NAMESPACE_ID::DescriptorProto_ExtensionRange)}, + { 49, 57, -1, sizeof(::PROTOBUF_NAMESPACE_ID::DescriptorProto_ReservedRange)}, + { 59, 75, -1, sizeof(::PROTOBUF_NAMESPACE_ID::DescriptorProto)}, + { 85, -1, -1, sizeof(::PROTOBUF_NAMESPACE_ID::ExtensionRangeOptions)}, + { 92, 109, -1, sizeof(::PROTOBUF_NAMESPACE_ID::FieldDescriptorProto)}, + { 120, 128, -1, sizeof(::PROTOBUF_NAMESPACE_ID::OneofDescriptorProto)}, + { 130, 138, -1, sizeof(::PROTOBUF_NAMESPACE_ID::EnumDescriptorProto_EnumReservedRange)}, + { 140, 151, -1, sizeof(::PROTOBUF_NAMESPACE_ID::EnumDescriptorProto)}, + { 156, 165, -1, sizeof(::PROTOBUF_NAMESPACE_ID::EnumValueDescriptorProto)}, + { 168, 177, -1, sizeof(::PROTOBUF_NAMESPACE_ID::ServiceDescriptorProto)}, + { 180, 192, -1, sizeof(::PROTOBUF_NAMESPACE_ID::MethodDescriptorProto)}, + { 198, 225, -1, sizeof(::PROTOBUF_NAMESPACE_ID::FileOptions)}, + { 246, 257, -1, sizeof(::PROTOBUF_NAMESPACE_ID::MessageOptions)}, + { 262, 275, -1, sizeof(::PROTOBUF_NAMESPACE_ID::FieldOptions)}, + { 282, -1, -1, sizeof(::PROTOBUF_NAMESPACE_ID::OneofOptions)}, + { 289, 298, -1, sizeof(::PROTOBUF_NAMESPACE_ID::EnumOptions)}, + { 301, 309, -1, sizeof(::PROTOBUF_NAMESPACE_ID::EnumValueOptions)}, + { 311, 319, -1, sizeof(::PROTOBUF_NAMESPACE_ID::ServiceOptions)}, + { 321, 330, -1, sizeof(::PROTOBUF_NAMESPACE_ID::MethodOptions)}, + { 333, 341, -1, sizeof(::PROTOBUF_NAMESPACE_ID::UninterpretedOption_NamePart)}, + { 343, 356, -1, sizeof(::PROTOBUF_NAMESPACE_ID::UninterpretedOption)}, + { 363, 374, -1, sizeof(::PROTOBUF_NAMESPACE_ID::SourceCodeInfo_Location)}, + { 379, -1, -1, sizeof(::PROTOBUF_NAMESPACE_ID::SourceCodeInfo)}, + { 386, 396, -1, sizeof(::PROTOBUF_NAMESPACE_ID::GeneratedCodeInfo_Annotation)}, + { 400, -1, -1, sizeof(::PROTOBUF_NAMESPACE_ID::GeneratedCodeInfo)}, +}; + +static ::PROTOBUF_NAMESPACE_ID::Message const * const file_default_instances[] = { + reinterpret_cast<const ::PROTOBUF_NAMESPACE_ID::Message*>(&::PROTOBUF_NAMESPACE_ID::_FileDescriptorSet_default_instance_), + reinterpret_cast<const ::PROTOBUF_NAMESPACE_ID::Message*>(&::PROTOBUF_NAMESPACE_ID::_FileDescriptorProto_default_instance_), + reinterpret_cast<const ::PROTOBUF_NAMESPACE_ID::Message*>(&::PROTOBUF_NAMESPACE_ID::_DescriptorProto_ExtensionRange_default_instance_), + reinterpret_cast<const ::PROTOBUF_NAMESPACE_ID::Message*>(&::PROTOBUF_NAMESPACE_ID::_DescriptorProto_ReservedRange_default_instance_), + reinterpret_cast<const ::PROTOBUF_NAMESPACE_ID::Message*>(&::PROTOBUF_NAMESPACE_ID::_DescriptorProto_default_instance_), + reinterpret_cast<const ::PROTOBUF_NAMESPACE_ID::Message*>(&::PROTOBUF_NAMESPACE_ID::_ExtensionRangeOptions_default_instance_), + reinterpret_cast<const ::PROTOBUF_NAMESPACE_ID::Message*>(&::PROTOBUF_NAMESPACE_ID::_FieldDescriptorProto_default_instance_), + reinterpret_cast<const ::PROTOBUF_NAMESPACE_ID::Message*>(&::PROTOBUF_NAMESPACE_ID::_OneofDescriptorProto_default_instance_), + reinterpret_cast<const ::PROTOBUF_NAMESPACE_ID::Message*>(&::PROTOBUF_NAMESPACE_ID::_EnumDescriptorProto_EnumReservedRange_default_instance_), + reinterpret_cast<const ::PROTOBUF_NAMESPACE_ID::Message*>(&::PROTOBUF_NAMESPACE_ID::_EnumDescriptorProto_default_instance_), + reinterpret_cast<const ::PROTOBUF_NAMESPACE_ID::Message*>(&::PROTOBUF_NAMESPACE_ID::_EnumValueDescriptorProto_default_instance_), + reinterpret_cast<const ::PROTOBUF_NAMESPACE_ID::Message*>(&::PROTOBUF_NAMESPACE_ID::_ServiceDescriptorProto_default_instance_), + reinterpret_cast<const ::PROTOBUF_NAMESPACE_ID::Message*>(&::PROTOBUF_NAMESPACE_ID::_MethodDescriptorProto_default_instance_), + reinterpret_cast<const ::PROTOBUF_NAMESPACE_ID::Message*>(&::PROTOBUF_NAMESPACE_ID::_FileOptions_default_instance_), + reinterpret_cast<const ::PROTOBUF_NAMESPACE_ID::Message*>(&::PROTOBUF_NAMESPACE_ID::_MessageOptions_default_instance_), + reinterpret_cast<const ::PROTOBUF_NAMESPACE_ID::Message*>(&::PROTOBUF_NAMESPACE_ID::_FieldOptions_default_instance_), + reinterpret_cast<const ::PROTOBUF_NAMESPACE_ID::Message*>(&::PROTOBUF_NAMESPACE_ID::_OneofOptions_default_instance_), + reinterpret_cast<const ::PROTOBUF_NAMESPACE_ID::Message*>(&::PROTOBUF_NAMESPACE_ID::_EnumOptions_default_instance_), + reinterpret_cast<const ::PROTOBUF_NAMESPACE_ID::Message*>(&::PROTOBUF_NAMESPACE_ID::_EnumValueOptions_default_instance_), + reinterpret_cast<const ::PROTOBUF_NAMESPACE_ID::Message*>(&::PROTOBUF_NAMESPACE_ID::_ServiceOptions_default_instance_), + reinterpret_cast<const ::PROTOBUF_NAMESPACE_ID::Message*>(&::PROTOBUF_NAMESPACE_ID::_MethodOptions_default_instance_), + reinterpret_cast<const ::PROTOBUF_NAMESPACE_ID::Message*>(&::PROTOBUF_NAMESPACE_ID::_UninterpretedOption_NamePart_default_instance_), + reinterpret_cast<const ::PROTOBUF_NAMESPACE_ID::Message*>(&::PROTOBUF_NAMESPACE_ID::_UninterpretedOption_default_instance_), + reinterpret_cast<const ::PROTOBUF_NAMESPACE_ID::Message*>(&::PROTOBUF_NAMESPACE_ID::_SourceCodeInfo_Location_default_instance_), + reinterpret_cast<const ::PROTOBUF_NAMESPACE_ID::Message*>(&::PROTOBUF_NAMESPACE_ID::_SourceCodeInfo_default_instance_), + reinterpret_cast<const ::PROTOBUF_NAMESPACE_ID::Message*>(&::PROTOBUF_NAMESPACE_ID::_GeneratedCodeInfo_Annotation_default_instance_), + reinterpret_cast<const ::PROTOBUF_NAMESPACE_ID::Message*>(&::PROTOBUF_NAMESPACE_ID::_GeneratedCodeInfo_default_instance_), +}; + +const char descriptor_table_protodef_google_2fprotobuf_2fdescriptor_2eproto[] PROTOBUF_SECTION_VARIABLE(protodesc_cold) = + "\n google/protobuf/descriptor.proto\022\017goog" + "le.protobuf\"G\n\021FileDescriptorSet\0222\n\004file" + "\030\001 \003(\0132$.google.protobuf.FileDescriptorP" + "roto\"\333\003\n\023FileDescriptorProto\022\014\n\004name\030\001 \001" + "(\t\022\017\n\007package\030\002 \001(\t\022\022\n\ndependency\030\003 \003(\t\022" + "\031\n\021public_dependency\030\n \003(\005\022\027\n\017weak_depen" + "dency\030\013 \003(\005\0226\n\014message_type\030\004 \003(\0132 .goog" + "le.protobuf.DescriptorProto\0227\n\tenum_type" + "\030\005 \003(\0132$.google.protobuf.EnumDescriptorP" + "roto\0228\n\007service\030\006 \003(\0132\'.google.protobuf." + "ServiceDescriptorProto\0228\n\textension\030\007 \003(" + "\0132%.google.protobuf.FieldDescriptorProto" + "\022-\n\007options\030\010 \001(\0132\034.google.protobuf.File" + "Options\0229\n\020source_code_info\030\t \001(\0132\037.goog" + "le.protobuf.SourceCodeInfo\022\016\n\006syntax\030\014 \001" + "(\t\"\251\005\n\017DescriptorProto\022\014\n\004name\030\001 \001(\t\0224\n\005" + "field\030\002 \003(\0132%.google.protobuf.FieldDescr" + "iptorProto\0228\n\textension\030\006 \003(\0132%.google.p" + "rotobuf.FieldDescriptorProto\0225\n\013nested_t" + "ype\030\003 \003(\0132 .google.protobuf.DescriptorPr" + "oto\0227\n\tenum_type\030\004 \003(\0132$.google.protobuf" + ".EnumDescriptorProto\022H\n\017extension_range\030" + "\005 \003(\0132/.google.protobuf.DescriptorProto." + "ExtensionRange\0229\n\noneof_decl\030\010 \003(\0132%.goo" + "gle.protobuf.OneofDescriptorProto\0220\n\007opt" + "ions\030\007 \001(\0132\037.google.protobuf.MessageOpti" + "ons\022F\n\016reserved_range\030\t \003(\0132..google.pro" + "tobuf.DescriptorProto.ReservedRange\022\025\n\rr" + "eserved_name\030\n \003(\t\032e\n\016ExtensionRange\022\r\n\005" + "start\030\001 \001(\005\022\013\n\003end\030\002 \001(\005\0227\n\007options\030\003 \001(" + "\0132&.google.protobuf.ExtensionRangeOption" + "s\032+\n\rReservedRange\022\r\n\005start\030\001 \001(\005\022\013\n\003end" + "\030\002 \001(\005\"g\n\025ExtensionRangeOptions\022C\n\024unint" + "erpreted_option\030\347\007 \003(\0132$.google.protobuf" + ".UninterpretedOption*\t\010\350\007\020\200\200\200\200\002\"\325\005\n\024Fiel" + "dDescriptorProto\022\014\n\004name\030\001 \001(\t\022\016\n\006number" + "\030\003 \001(\005\022:\n\005label\030\004 \001(\0162+.google.protobuf." + "FieldDescriptorProto.Label\0228\n\004type\030\005 \001(\016" + "2*.google.protobuf.FieldDescriptorProto." + "Type\022\021\n\ttype_name\030\006 \001(\t\022\020\n\010extendee\030\002 \001(" + "\t\022\025\n\rdefault_value\030\007 \001(\t\022\023\n\013oneof_index\030" + "\t \001(\005\022\021\n\tjson_name\030\n \001(\t\022.\n\007options\030\010 \001(" + "\0132\035.google.protobuf.FieldOptions\022\027\n\017prot" + "o3_optional\030\021 \001(\010\"\266\002\n\004Type\022\017\n\013TYPE_DOUBL" + "E\020\001\022\016\n\nTYPE_FLOAT\020\002\022\016\n\nTYPE_INT64\020\003\022\017\n\013T" + "YPE_UINT64\020\004\022\016\n\nTYPE_INT32\020\005\022\020\n\014TYPE_FIX" + "ED64\020\006\022\020\n\014TYPE_FIXED32\020\007\022\r\n\tTYPE_BOOL\020\010\022" + "\017\n\013TYPE_STRING\020\t\022\016\n\nTYPE_GROUP\020\n\022\020\n\014TYPE" + "_MESSAGE\020\013\022\016\n\nTYPE_BYTES\020\014\022\017\n\013TYPE_UINT3" + "2\020\r\022\r\n\tTYPE_ENUM\020\016\022\021\n\rTYPE_SFIXED32\020\017\022\021\n" + "\rTYPE_SFIXED64\020\020\022\017\n\013TYPE_SINT32\020\021\022\017\n\013TYP" + "E_SINT64\020\022\"C\n\005Label\022\022\n\016LABEL_OPTIONAL\020\001\022" + "\022\n\016LABEL_REQUIRED\020\002\022\022\n\016LABEL_REPEATED\020\003\"" + "T\n\024OneofDescriptorProto\022\014\n\004name\030\001 \001(\t\022.\n" + "\007options\030\002 \001(\0132\035.google.protobuf.OneofOp" + "tions\"\244\002\n\023EnumDescriptorProto\022\014\n\004name\030\001 " + "\001(\t\0228\n\005value\030\002 \003(\0132).google.protobuf.Enu" + "mValueDescriptorProto\022-\n\007options\030\003 \001(\0132\034" + ".google.protobuf.EnumOptions\022N\n\016reserved" + "_range\030\004 \003(\01326.google.protobuf.EnumDescr" + "iptorProto.EnumReservedRange\022\025\n\rreserved" + "_name\030\005 \003(\t\032/\n\021EnumReservedRange\022\r\n\005star" + "t\030\001 \001(\005\022\013\n\003end\030\002 \001(\005\"l\n\030EnumValueDescrip" + "torProto\022\014\n\004name\030\001 \001(\t\022\016\n\006number\030\002 \001(\005\0222" + "\n\007options\030\003 \001(\0132!.google.protobuf.EnumVa" + "lueOptions\"\220\001\n\026ServiceDescriptorProto\022\014\n" + "\004name\030\001 \001(\t\0226\n\006method\030\002 \003(\0132&.google.pro" + "tobuf.MethodDescriptorProto\0220\n\007options\030\003" + " \001(\0132\037.google.protobuf.ServiceOptions\"\301\001" + "\n\025MethodDescriptorProto\022\014\n\004name\030\001 \001(\t\022\022\n" + "\ninput_type\030\002 \001(\t\022\023\n\013output_type\030\003 \001(\t\022/" + "\n\007options\030\004 \001(\0132\036.google.protobuf.Method" + "Options\022\037\n\020client_streaming\030\005 \001(\010:\005false" + "\022\037\n\020server_streaming\030\006 \001(\010:\005false\"\245\006\n\013Fi" + "leOptions\022\024\n\014java_package\030\001 \001(\t\022\034\n\024java_" + "outer_classname\030\010 \001(\t\022\"\n\023java_multiple_f" + "iles\030\n \001(\010:\005false\022)\n\035java_generate_equal" + "s_and_hash\030\024 \001(\010B\002\030\001\022%\n\026java_string_chec" + "k_utf8\030\033 \001(\010:\005false\022F\n\014optimize_for\030\t \001(" + "\0162).google.protobuf.FileOptions.Optimize" + "Mode:\005SPEED\022\022\n\ngo_package\030\013 \001(\t\022\"\n\023cc_ge" + "neric_services\030\020 \001(\010:\005false\022$\n\025java_gene" + "ric_services\030\021 \001(\010:\005false\022\"\n\023py_generic_" + "services\030\022 \001(\010:\005false\022#\n\024php_generic_ser" + "vices\030* \001(\010:\005false\022\031\n\ndeprecated\030\027 \001(\010:\005" + "false\022\036\n\020cc_enable_arenas\030\037 \001(\010:\004true\022\031\n" + "\021objc_class_prefix\030$ \001(\t\022\030\n\020csharp_names" + "pace\030% \001(\t\022\024\n\014swift_prefix\030\' \001(\t\022\030\n\020php_" + "class_prefix\030( \001(\t\022\025\n\rphp_namespace\030) \001(" + "\t\022\036\n\026php_metadata_namespace\030, \001(\t\022\024\n\014rub" + "y_package\030- \001(\t\022C\n\024uninterpreted_option\030" + "\347\007 \003(\0132$.google.protobuf.UninterpretedOp" + "tion\":\n\014OptimizeMode\022\t\n\005SPEED\020\001\022\r\n\tCODE_" + "SIZE\020\002\022\020\n\014LITE_RUNTIME\020\003*\t\010\350\007\020\200\200\200\200\002J\004\010&\020" + "\'\"\204\002\n\016MessageOptions\022&\n\027message_set_wire" + "_format\030\001 \001(\010:\005false\022.\n\037no_standard_desc" + "riptor_accessor\030\002 \001(\010:\005false\022\031\n\ndeprecat" + "ed\030\003 \001(\010:\005false\022\021\n\tmap_entry\030\007 \001(\010\022C\n\024un" + "interpreted_option\030\347\007 \003(\0132$.google.proto" + "buf.UninterpretedOption*\t\010\350\007\020\200\200\200\200\002J\004\010\004\020\005" + "J\004\010\005\020\006J\004\010\006\020\007J\004\010\010\020\tJ\004\010\t\020\n\"\236\003\n\014FieldOption" + "s\022:\n\005ctype\030\001 \001(\0162#.google.protobuf.Field" + "Options.CType:\006STRING\022\016\n\006packed\030\002 \001(\010\022\?\n" + "\006jstype\030\006 \001(\0162$.google.protobuf.FieldOpt" + "ions.JSType:\tJS_NORMAL\022\023\n\004lazy\030\005 \001(\010:\005fa" + "lse\022\031\n\ndeprecated\030\003 \001(\010:\005false\022\023\n\004weak\030\n" + " \001(\010:\005false\022C\n\024uninterpreted_option\030\347\007 \003" + "(\0132$.google.protobuf.UninterpretedOption" + "\"/\n\005CType\022\n\n\006STRING\020\000\022\010\n\004CORD\020\001\022\020\n\014STRIN" + "G_PIECE\020\002\"5\n\006JSType\022\r\n\tJS_NORMAL\020\000\022\r\n\tJS" + "_STRING\020\001\022\r\n\tJS_NUMBER\020\002*\t\010\350\007\020\200\200\200\200\002J\004\010\004\020" + "\005\"^\n\014OneofOptions\022C\n\024uninterpreted_optio" + "n\030\347\007 \003(\0132$.google.protobuf.Uninterpreted" + "Option*\t\010\350\007\020\200\200\200\200\002\"\223\001\n\013EnumOptions\022\023\n\013all" + "ow_alias\030\002 \001(\010\022\031\n\ndeprecated\030\003 \001(\010:\005fals" + "e\022C\n\024uninterpreted_option\030\347\007 \003(\0132$.googl" + "e.protobuf.UninterpretedOption*\t\010\350\007\020\200\200\200\200" + "\002J\004\010\005\020\006\"}\n\020EnumValueOptions\022\031\n\ndeprecate" + "d\030\001 \001(\010:\005false\022C\n\024uninterpreted_option\030\347" + "\007 \003(\0132$.google.protobuf.UninterpretedOpt" + "ion*\t\010\350\007\020\200\200\200\200\002\"{\n\016ServiceOptions\022\031\n\ndepr" + "ecated\030! \001(\010:\005false\022C\n\024uninterpreted_opt" + "ion\030\347\007 \003(\0132$.google.protobuf.Uninterpret" + "edOption*\t\010\350\007\020\200\200\200\200\002\"\255\002\n\rMethodOptions\022\031\n" + "\ndeprecated\030! \001(\010:\005false\022_\n\021idempotency_" + "level\030\" \001(\0162/.google.protobuf.MethodOpti" + "ons.IdempotencyLevel:\023IDEMPOTENCY_UNKNOW" + "N\022C\n\024uninterpreted_option\030\347\007 \003(\0132$.googl" + "e.protobuf.UninterpretedOption\"P\n\020Idempo" + "tencyLevel\022\027\n\023IDEMPOTENCY_UNKNOWN\020\000\022\023\n\017N" + "O_SIDE_EFFECTS\020\001\022\016\n\nIDEMPOTENT\020\002*\t\010\350\007\020\200\200" + "\200\200\002\"\236\002\n\023UninterpretedOption\022;\n\004name\030\002 \003(" + "\0132-.google.protobuf.UninterpretedOption." + "NamePart\022\030\n\020identifier_value\030\003 \001(\t\022\032\n\022po" + "sitive_int_value\030\004 \001(\004\022\032\n\022negative_int_v" + "alue\030\005 \001(\003\022\024\n\014double_value\030\006 \001(\001\022\024\n\014stri" + "ng_value\030\007 \001(\014\022\027\n\017aggregate_value\030\010 \001(\t\032" + "3\n\010NamePart\022\021\n\tname_part\030\001 \002(\t\022\024\n\014is_ext" + "ension\030\002 \002(\010\"\325\001\n\016SourceCodeInfo\022:\n\010locat" + "ion\030\001 \003(\0132(.google.protobuf.SourceCodeIn" + "fo.Location\032\206\001\n\010Location\022\020\n\004path\030\001 \003(\005B\002" + "\020\001\022\020\n\004span\030\002 \003(\005B\002\020\001\022\030\n\020leading_comments" + "\030\003 \001(\t\022\031\n\021trailing_comments\030\004 \001(\t\022!\n\031lea" + "ding_detached_comments\030\006 \003(\t\"\247\001\n\021Generat" + "edCodeInfo\022A\n\nannotation\030\001 \003(\0132-.google." + "protobuf.GeneratedCodeInfo.Annotation\032O\n" + "\nAnnotation\022\020\n\004path\030\001 \003(\005B\002\020\001\022\023\n\013source_" + "file\030\002 \001(\t\022\r\n\005begin\030\003 \001(\005\022\013\n\003end\030\004 \001(\005B~" + "\n\023com.google.protobufB\020DescriptorProtosH" + "\001Z-google.golang.org/protobuf/types/desc" + "riptorpb\370\001\001\242\002\003GPB\252\002\032Google.Protobuf.Refl" + "ection" + ; +static ::PROTOBUF_NAMESPACE_ID::internal::once_flag descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_once; +const ::PROTOBUF_NAMESPACE_ID::internal::DescriptorTable descriptor_table_google_2fprotobuf_2fdescriptor_2eproto = { + false, false, 6046, descriptor_table_protodef_google_2fprotobuf_2fdescriptor_2eproto, "google/protobuf/descriptor.proto", + &descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_once, nullptr, 0, 27, + schemas, file_default_instances, TableStruct_google_2fprotobuf_2fdescriptor_2eproto::offsets, + file_level_metadata_google_2fprotobuf_2fdescriptor_2eproto, file_level_enum_descriptors_google_2fprotobuf_2fdescriptor_2eproto, file_level_service_descriptors_google_2fprotobuf_2fdescriptor_2eproto, +}; +PROTOBUF_ATTRIBUTE_WEAK const ::PROTOBUF_NAMESPACE_ID::internal::DescriptorTable* descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_getter() { + return &descriptor_table_google_2fprotobuf_2fdescriptor_2eproto; +} + +// Force running AddDescriptors() at dynamic initialization time. +PROTOBUF_ATTRIBUTE_INIT_PRIORITY static ::PROTOBUF_NAMESPACE_ID::internal::AddDescriptorsRunner dynamic_init_dummy_google_2fprotobuf_2fdescriptor_2eproto(&descriptor_table_google_2fprotobuf_2fdescriptor_2eproto); +PROTOBUF_NAMESPACE_OPEN +const ::PROTOBUF_NAMESPACE_ID::EnumDescriptor* FieldDescriptorProto_Type_descriptor() { + ::PROTOBUF_NAMESPACE_ID::internal::AssignDescriptors(&descriptor_table_google_2fprotobuf_2fdescriptor_2eproto); + return file_level_enum_descriptors_google_2fprotobuf_2fdescriptor_2eproto[0]; +} +bool FieldDescriptorProto_Type_IsValid(int value) { + switch (value) { + case 1: + case 2: + case 3: + case 4: + case 5: + case 6: + case 7: + case 8: + case 9: + case 10: + case 11: + case 12: + case 13: + case 14: + case 15: + case 16: + case 17: + case 18: + return true; + default: + return false; + } +} + +#if (__cplusplus < 201703) && (!defined(_MSC_VER) || (_MSC_VER >= 1900 && _MSC_VER < 1912)) +constexpr FieldDescriptorProto_Type FieldDescriptorProto::TYPE_DOUBLE; +constexpr FieldDescriptorProto_Type FieldDescriptorProto::TYPE_FLOAT; +constexpr FieldDescriptorProto_Type FieldDescriptorProto::TYPE_INT64; +constexpr FieldDescriptorProto_Type FieldDescriptorProto::TYPE_UINT64; +constexpr FieldDescriptorProto_Type FieldDescriptorProto::TYPE_INT32; +constexpr FieldDescriptorProto_Type FieldDescriptorProto::TYPE_FIXED64; +constexpr FieldDescriptorProto_Type FieldDescriptorProto::TYPE_FIXED32; +constexpr FieldDescriptorProto_Type FieldDescriptorProto::TYPE_BOOL; +constexpr FieldDescriptorProto_Type FieldDescriptorProto::TYPE_STRING; +constexpr FieldDescriptorProto_Type FieldDescriptorProto::TYPE_GROUP; +constexpr FieldDescriptorProto_Type FieldDescriptorProto::TYPE_MESSAGE; +constexpr FieldDescriptorProto_Type FieldDescriptorProto::TYPE_BYTES; +constexpr FieldDescriptorProto_Type FieldDescriptorProto::TYPE_UINT32; +constexpr FieldDescriptorProto_Type FieldDescriptorProto::TYPE_ENUM; +constexpr FieldDescriptorProto_Type FieldDescriptorProto::TYPE_SFIXED32; +constexpr FieldDescriptorProto_Type FieldDescriptorProto::TYPE_SFIXED64; +constexpr FieldDescriptorProto_Type FieldDescriptorProto::TYPE_SINT32; +constexpr FieldDescriptorProto_Type FieldDescriptorProto::TYPE_SINT64; +constexpr FieldDescriptorProto_Type FieldDescriptorProto::Type_MIN; +constexpr FieldDescriptorProto_Type FieldDescriptorProto::Type_MAX; +constexpr int FieldDescriptorProto::Type_ARRAYSIZE; +#endif // (__cplusplus < 201703) && (!defined(_MSC_VER) || (_MSC_VER >= 1900 && _MSC_VER < 1912)) +const ::PROTOBUF_NAMESPACE_ID::EnumDescriptor* FieldDescriptorProto_Label_descriptor() { + ::PROTOBUF_NAMESPACE_ID::internal::AssignDescriptors(&descriptor_table_google_2fprotobuf_2fdescriptor_2eproto); + return file_level_enum_descriptors_google_2fprotobuf_2fdescriptor_2eproto[1]; +} +bool FieldDescriptorProto_Label_IsValid(int value) { + switch (value) { + case 1: + case 2: + case 3: + return true; + default: + return false; + } +} + +#if (__cplusplus < 201703) && (!defined(_MSC_VER) || (_MSC_VER >= 1900 && _MSC_VER < 1912)) +constexpr FieldDescriptorProto_Label FieldDescriptorProto::LABEL_OPTIONAL; +constexpr FieldDescriptorProto_Label FieldDescriptorProto::LABEL_REQUIRED; +constexpr FieldDescriptorProto_Label FieldDescriptorProto::LABEL_REPEATED; +constexpr FieldDescriptorProto_Label FieldDescriptorProto::Label_MIN; +constexpr FieldDescriptorProto_Label FieldDescriptorProto::Label_MAX; +constexpr int FieldDescriptorProto::Label_ARRAYSIZE; +#endif // (__cplusplus < 201703) && (!defined(_MSC_VER) || (_MSC_VER >= 1900 && _MSC_VER < 1912)) +const ::PROTOBUF_NAMESPACE_ID::EnumDescriptor* FileOptions_OptimizeMode_descriptor() { + ::PROTOBUF_NAMESPACE_ID::internal::AssignDescriptors(&descriptor_table_google_2fprotobuf_2fdescriptor_2eproto); + return file_level_enum_descriptors_google_2fprotobuf_2fdescriptor_2eproto[2]; +} +bool FileOptions_OptimizeMode_IsValid(int value) { + switch (value) { + case 1: + case 2: + case 3: + return true; + default: + return false; + } +} + +#if (__cplusplus < 201703) && (!defined(_MSC_VER) || (_MSC_VER >= 1900 && _MSC_VER < 1912)) +constexpr FileOptions_OptimizeMode FileOptions::SPEED; +constexpr FileOptions_OptimizeMode FileOptions::CODE_SIZE; +constexpr FileOptions_OptimizeMode FileOptions::LITE_RUNTIME; +constexpr FileOptions_OptimizeMode FileOptions::OptimizeMode_MIN; +constexpr FileOptions_OptimizeMode FileOptions::OptimizeMode_MAX; +constexpr int FileOptions::OptimizeMode_ARRAYSIZE; +#endif // (__cplusplus < 201703) && (!defined(_MSC_VER) || (_MSC_VER >= 1900 && _MSC_VER < 1912)) +const ::PROTOBUF_NAMESPACE_ID::EnumDescriptor* FieldOptions_CType_descriptor() { + ::PROTOBUF_NAMESPACE_ID::internal::AssignDescriptors(&descriptor_table_google_2fprotobuf_2fdescriptor_2eproto); + return file_level_enum_descriptors_google_2fprotobuf_2fdescriptor_2eproto[3]; +} +bool FieldOptions_CType_IsValid(int value) { + switch (value) { + case 0: + case 1: + case 2: + return true; + default: + return false; + } +} + +#if (__cplusplus < 201703) && (!defined(_MSC_VER) || (_MSC_VER >= 1900 && _MSC_VER < 1912)) +constexpr FieldOptions_CType FieldOptions::STRING; +constexpr FieldOptions_CType FieldOptions::CORD; +constexpr FieldOptions_CType FieldOptions::STRING_PIECE; +constexpr FieldOptions_CType FieldOptions::CType_MIN; +constexpr FieldOptions_CType FieldOptions::CType_MAX; +constexpr int FieldOptions::CType_ARRAYSIZE; +#endif // (__cplusplus < 201703) && (!defined(_MSC_VER) || (_MSC_VER >= 1900 && _MSC_VER < 1912)) +const ::PROTOBUF_NAMESPACE_ID::EnumDescriptor* FieldOptions_JSType_descriptor() { + ::PROTOBUF_NAMESPACE_ID::internal::AssignDescriptors(&descriptor_table_google_2fprotobuf_2fdescriptor_2eproto); + return file_level_enum_descriptors_google_2fprotobuf_2fdescriptor_2eproto[4]; +} +bool FieldOptions_JSType_IsValid(int value) { + switch (value) { + case 0: + case 1: + case 2: + return true; + default: + return false; + } +} + +#if (__cplusplus < 201703) && (!defined(_MSC_VER) || (_MSC_VER >= 1900 && _MSC_VER < 1912)) +constexpr FieldOptions_JSType FieldOptions::JS_NORMAL; +constexpr FieldOptions_JSType FieldOptions::JS_STRING; +constexpr FieldOptions_JSType FieldOptions::JS_NUMBER; +constexpr FieldOptions_JSType FieldOptions::JSType_MIN; +constexpr FieldOptions_JSType FieldOptions::JSType_MAX; +constexpr int FieldOptions::JSType_ARRAYSIZE; +#endif // (__cplusplus < 201703) && (!defined(_MSC_VER) || (_MSC_VER >= 1900 && _MSC_VER < 1912)) +const ::PROTOBUF_NAMESPACE_ID::EnumDescriptor* MethodOptions_IdempotencyLevel_descriptor() { + ::PROTOBUF_NAMESPACE_ID::internal::AssignDescriptors(&descriptor_table_google_2fprotobuf_2fdescriptor_2eproto); + return file_level_enum_descriptors_google_2fprotobuf_2fdescriptor_2eproto[5]; +} +bool MethodOptions_IdempotencyLevel_IsValid(int value) { + switch (value) { + case 0: + case 1: + case 2: + return true; + default: + return false; + } +} + +#if (__cplusplus < 201703) && (!defined(_MSC_VER) || (_MSC_VER >= 1900 && _MSC_VER < 1912)) +constexpr MethodOptions_IdempotencyLevel MethodOptions::IDEMPOTENCY_UNKNOWN; +constexpr MethodOptions_IdempotencyLevel MethodOptions::NO_SIDE_EFFECTS; +constexpr MethodOptions_IdempotencyLevel MethodOptions::IDEMPOTENT; +constexpr MethodOptions_IdempotencyLevel MethodOptions::IdempotencyLevel_MIN; +constexpr MethodOptions_IdempotencyLevel MethodOptions::IdempotencyLevel_MAX; +constexpr int MethodOptions::IdempotencyLevel_ARRAYSIZE; +#endif // (__cplusplus < 201703) && (!defined(_MSC_VER) || (_MSC_VER >= 1900 && _MSC_VER < 1912)) + +// =================================================================== + +class FileDescriptorSet::_Internal { + public: +}; + +FileDescriptorSet::FileDescriptorSet(::PROTOBUF_NAMESPACE_ID::Arena* arena, + bool is_message_owned) + : ::PROTOBUF_NAMESPACE_ID::Message(arena, is_message_owned), + file_(arena) { + SharedCtor(); + if (!is_message_owned) { + RegisterArenaDtor(arena); + } + // @@protoc_insertion_point(arena_constructor:google.protobuf.FileDescriptorSet) +} +FileDescriptorSet::FileDescriptorSet(const FileDescriptorSet& from) + : ::PROTOBUF_NAMESPACE_ID::Message(), + file_(from.file_) { + _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_); + // @@protoc_insertion_point(copy_constructor:google.protobuf.FileDescriptorSet) +} + +inline void FileDescriptorSet::SharedCtor() { +} + +FileDescriptorSet::~FileDescriptorSet() { + // @@protoc_insertion_point(destructor:google.protobuf.FileDescriptorSet) + if (GetArenaForAllocation() != nullptr) return; + SharedDtor(); + _internal_metadata_.Delete<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(); +} + +inline void FileDescriptorSet::SharedDtor() { + GOOGLE_DCHECK(GetArenaForAllocation() == nullptr); +} + +void FileDescriptorSet::ArenaDtor(void* object) { + FileDescriptorSet* _this = reinterpret_cast< FileDescriptorSet* >(object); + (void)_this; +} +void FileDescriptorSet::RegisterArenaDtor(::PROTOBUF_NAMESPACE_ID::Arena*) { +} +void FileDescriptorSet::SetCachedSize(int size) const { + _cached_size_.Set(size); +} + +void FileDescriptorSet::Clear() { +// @@protoc_insertion_point(message_clear_start:google.protobuf.FileDescriptorSet) + arc_ui32 cached_has_bits = 0; + // Prevent compiler warnings about cached_has_bits being unused + (void) cached_has_bits; + + file_.Clear(); + _internal_metadata_.Clear<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(); +} + +const char* FileDescriptorSet::_InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) { +#define CHK_(x) if (PROTOBUF_PREDICT_FALSE(!(x))) goto failure + while (!ctx->Done(&ptr)) { + arc_ui32 tag; + ptr = ::PROTOBUF_NAMESPACE_ID::internal::ReadTag(ptr, &tag); + switch (tag >> 3) { + // repeated .google.protobuf.FileDescriptorProto file = 1; + case 1: + if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 10)) { + ptr -= 1; + do { + ptr += 1; + ptr = ctx->ParseMessage(_internal_add_file(), ptr); + CHK_(ptr); + if (!ctx->DataAvailable(ptr)) break; + } while (::PROTOBUF_NAMESPACE_ID::internal::ExpectTag<10>(ptr)); + } else + goto handle_unusual; + continue; + default: + goto handle_unusual; + } // switch + handle_unusual: + if ((tag == 0) || ((tag & 7) == 4)) { + CHK_(ptr); + ctx->SetLastTag(tag); + goto message_done; + } + ptr = UnknownFieldParse( + tag, + _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(), + ptr, ctx); + CHK_(ptr != nullptr); + } // while +message_done: + return ptr; +failure: + ptr = nullptr; + goto message_done; +#undef CHK_ +} + +uint8_t* FileDescriptorSet::_InternalSerialize( + uint8_t* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const { + // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.FileDescriptorSet) + arc_ui32 cached_has_bits = 0; + (void) cached_has_bits; + + // repeated .google.protobuf.FileDescriptorProto file = 1; + for (unsigned int i = 0, + n = static_cast<unsigned int>(this->_internal_file_size()); i < n; i++) { + target = stream->EnsureSpace(target); + target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite:: + InternalWriteMessage(1, this->_internal_file(i), target, stream); + } + + if (PROTOBUF_PREDICT_FALSE(_internal_metadata_.have_unknown_fields())) { + target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::InternalSerializeUnknownFieldsToArray( + _internal_metadata_.unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(::PROTOBUF_NAMESPACE_ID::UnknownFieldSet::default_instance), target, stream); + } + // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.FileDescriptorSet) + return target; +} + +size_t FileDescriptorSet::ByteSizeLong() const { +// @@protoc_insertion_point(message_byte_size_start:google.protobuf.FileDescriptorSet) + size_t total_size = 0; + + arc_ui32 cached_has_bits = 0; + // Prevent compiler warnings about cached_has_bits being unused + (void) cached_has_bits; + + // repeated .google.protobuf.FileDescriptorProto file = 1; + total_size += 1UL * this->_internal_file_size(); + for (const auto& msg : this->file_) { + total_size += + ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::MessageSize(msg); + } + + return MaybeComputeUnknownFieldsSize(total_size, &_cached_size_); +} + +const ::PROTOBUF_NAMESPACE_ID::Message::ClassData FileDescriptorSet::_class_data_ = { + ::PROTOBUF_NAMESPACE_ID::Message::CopyWithSizeCheck, + FileDescriptorSet::MergeImpl +}; +const ::PROTOBUF_NAMESPACE_ID::Message::ClassData*FileDescriptorSet::GetClassData() const { return &_class_data_; } + +void FileDescriptorSet::MergeImpl(::PROTOBUF_NAMESPACE_ID::Message* to, + const ::PROTOBUF_NAMESPACE_ID::Message& from) { + static_cast<FileDescriptorSet *>(to)->MergeFrom( + static_cast<const FileDescriptorSet &>(from)); +} + + +void FileDescriptorSet::MergeFrom(const FileDescriptorSet& from) { +// @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.FileDescriptorSet) + GOOGLE_DCHECK_NE(&from, this); + arc_ui32 cached_has_bits = 0; + (void) cached_has_bits; + + file_.MergeFrom(from.file_); + _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_); +} + +void FileDescriptorSet::CopyFrom(const FileDescriptorSet& from) { +// @@protoc_insertion_point(class_specific_copy_from_start:google.protobuf.FileDescriptorSet) + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool FileDescriptorSet::IsInitialized() const { + if (!::PROTOBUF_NAMESPACE_ID::internal::AllAreInitialized(file_)) + return false; + return true; +} + +void FileDescriptorSet::InternalSwap(FileDescriptorSet* other) { + using std::swap; + _internal_metadata_.InternalSwap(&other->_internal_metadata_); + file_.InternalSwap(&other->file_); +} + +::PROTOBUF_NAMESPACE_ID::Metadata FileDescriptorSet::GetMetadata() const { + return ::PROTOBUF_NAMESPACE_ID::internal::AssignDescriptors( + &descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_getter, &descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_once, + file_level_metadata_google_2fprotobuf_2fdescriptor_2eproto[0]); +} + +// =================================================================== + +class FileDescriptorProto::_Internal { + public: + using HasBits = decltype(std::declval<FileDescriptorProto>()._has_bits_); + static void set_has_name(HasBits* has_bits) { + (*has_bits)[0] |= 1u; + } + static void set_has_package(HasBits* has_bits) { + (*has_bits)[0] |= 2u; + } + static const ::PROTOBUF_NAMESPACE_ID::FileOptions& options(const FileDescriptorProto* msg); + static void set_has_options(HasBits* has_bits) { + (*has_bits)[0] |= 8u; + } + static const ::PROTOBUF_NAMESPACE_ID::SourceCodeInfo& source_code_info(const FileDescriptorProto* msg); + static void set_has_source_code_info(HasBits* has_bits) { + (*has_bits)[0] |= 16u; + } + static void set_has_syntax(HasBits* has_bits) { + (*has_bits)[0] |= 4u; + } +}; + +const ::PROTOBUF_NAMESPACE_ID::FileOptions& +FileDescriptorProto::_Internal::options(const FileDescriptorProto* msg) { + return *msg->options_; +} +const ::PROTOBUF_NAMESPACE_ID::SourceCodeInfo& +FileDescriptorProto::_Internal::source_code_info(const FileDescriptorProto* msg) { + return *msg->source_code_info_; +} +FileDescriptorProto::FileDescriptorProto(::PROTOBUF_NAMESPACE_ID::Arena* arena, + bool is_message_owned) + : ::PROTOBUF_NAMESPACE_ID::Message(arena, is_message_owned), + dependency_(arena), + message_type_(arena), + enum_type_(arena), + service_(arena), + extension_(arena), + public_dependency_(arena), + weak_dependency_(arena) { + SharedCtor(); + if (!is_message_owned) { + RegisterArenaDtor(arena); + } + // @@protoc_insertion_point(arena_constructor:google.protobuf.FileDescriptorProto) +} +FileDescriptorProto::FileDescriptorProto(const FileDescriptorProto& from) + : ::PROTOBUF_NAMESPACE_ID::Message(), + _has_bits_(from._has_bits_), + dependency_(from.dependency_), + message_type_(from.message_type_), + enum_type_(from.enum_type_), + service_(from.service_), + extension_(from.extension_), + public_dependency_(from.public_dependency_), + weak_dependency_(from.weak_dependency_) { + _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_); + name_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); + #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING + name_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation()); + #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING + if (from._internal_has_name()) { + name_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, from._internal_name(), + GetArenaForAllocation()); + } + package_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); + #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING + package_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation()); + #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING + if (from._internal_has_package()) { + package_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, from._internal_package(), + GetArenaForAllocation()); + } + syntax_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); + #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING + syntax_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation()); + #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING + if (from._internal_has_syntax()) { + syntax_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, from._internal_syntax(), + GetArenaForAllocation()); + } + if (from._internal_has_options()) { + options_ = new ::PROTOBUF_NAMESPACE_ID::FileOptions(*from.options_); + } else { + options_ = nullptr; + } + if (from._internal_has_source_code_info()) { + source_code_info_ = new ::PROTOBUF_NAMESPACE_ID::SourceCodeInfo(*from.source_code_info_); + } else { + source_code_info_ = nullptr; + } + // @@protoc_insertion_point(copy_constructor:google.protobuf.FileDescriptorProto) +} + +inline void FileDescriptorProto::SharedCtor() { +name_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); +#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING + name_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation()); +#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING +package_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); +#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING + package_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation()); +#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING +syntax_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); +#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING + syntax_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation()); +#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING +::memset(reinterpret_cast<char*>(this) + static_cast<size_t>( + reinterpret_cast<char*>(&options_) - reinterpret_cast<char*>(this)), + 0, static_cast<size_t>(reinterpret_cast<char*>(&source_code_info_) - + reinterpret_cast<char*>(&options_)) + sizeof(source_code_info_)); +} + +FileDescriptorProto::~FileDescriptorProto() { + // @@protoc_insertion_point(destructor:google.protobuf.FileDescriptorProto) + if (GetArenaForAllocation() != nullptr) return; + SharedDtor(); + _internal_metadata_.Delete<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(); +} + +inline void FileDescriptorProto::SharedDtor() { + GOOGLE_DCHECK(GetArenaForAllocation() == nullptr); + name_.DestroyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); + package_.DestroyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); + syntax_.DestroyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); + if (this != internal_default_instance()) delete options_; + if (this != internal_default_instance()) delete source_code_info_; +} + +void FileDescriptorProto::ArenaDtor(void* object) { + FileDescriptorProto* _this = reinterpret_cast< FileDescriptorProto* >(object); + (void)_this; +} +void FileDescriptorProto::RegisterArenaDtor(::PROTOBUF_NAMESPACE_ID::Arena*) { +} +void FileDescriptorProto::SetCachedSize(int size) const { + _cached_size_.Set(size); +} + +void FileDescriptorProto::Clear() { +// @@protoc_insertion_point(message_clear_start:google.protobuf.FileDescriptorProto) + arc_ui32 cached_has_bits = 0; + // Prevent compiler warnings about cached_has_bits being unused + (void) cached_has_bits; + + dependency_.Clear(); + message_type_.Clear(); + enum_type_.Clear(); + service_.Clear(); + extension_.Clear(); + public_dependency_.Clear(); + weak_dependency_.Clear(); + cached_has_bits = _has_bits_[0]; + if (cached_has_bits & 0x0000001fu) { + if (cached_has_bits & 0x00000001u) { + name_.ClearNonDefaultToEmpty(); + } + if (cached_has_bits & 0x00000002u) { + package_.ClearNonDefaultToEmpty(); + } + if (cached_has_bits & 0x00000004u) { + syntax_.ClearNonDefaultToEmpty(); + } + if (cached_has_bits & 0x00000008u) { + GOOGLE_DCHECK(options_ != nullptr); + options_->Clear(); + } + if (cached_has_bits & 0x00000010u) { + GOOGLE_DCHECK(source_code_info_ != nullptr); + source_code_info_->Clear(); + } + } + _has_bits_.Clear(); + _internal_metadata_.Clear<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(); +} + +const char* FileDescriptorProto::_InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) { +#define CHK_(x) if (PROTOBUF_PREDICT_FALSE(!(x))) goto failure + _Internal::HasBits has_bits{}; + while (!ctx->Done(&ptr)) { + arc_ui32 tag; + ptr = ::PROTOBUF_NAMESPACE_ID::internal::ReadTag(ptr, &tag); + switch (tag >> 3) { + // optional string name = 1; + case 1: + if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 10)) { + auto str = _internal_mutable_name(); + ptr = ::PROTOBUF_NAMESPACE_ID::internal::InlineGreedyStringParser(str, ptr, ctx); + #ifndef NDEBUG + ::PROTOBUF_NAMESPACE_ID::internal::VerifyUTF8(str, "google.protobuf.FileDescriptorProto.name"); + #endif // !NDEBUG + CHK_(ptr); + } else + goto handle_unusual; + continue; + // optional string package = 2; + case 2: + if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 18)) { + auto str = _internal_mutable_package(); + ptr = ::PROTOBUF_NAMESPACE_ID::internal::InlineGreedyStringParser(str, ptr, ctx); + #ifndef NDEBUG + ::PROTOBUF_NAMESPACE_ID::internal::VerifyUTF8(str, "google.protobuf.FileDescriptorProto.package"); + #endif // !NDEBUG + CHK_(ptr); + } else + goto handle_unusual; + continue; + // repeated string dependency = 3; + case 3: + if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 26)) { + ptr -= 1; + do { + ptr += 1; + auto str = _internal_add_dependency(); + ptr = ::PROTOBUF_NAMESPACE_ID::internal::InlineGreedyStringParser(str, ptr, ctx); + #ifndef NDEBUG + ::PROTOBUF_NAMESPACE_ID::internal::VerifyUTF8(str, "google.protobuf.FileDescriptorProto.dependency"); + #endif // !NDEBUG + CHK_(ptr); + if (!ctx->DataAvailable(ptr)) break; + } while (::PROTOBUF_NAMESPACE_ID::internal::ExpectTag<26>(ptr)); + } else + goto handle_unusual; + continue; + // repeated .google.protobuf.DescriptorProto message_type = 4; + case 4: + if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 34)) { + ptr -= 1; + do { + ptr += 1; + ptr = ctx->ParseMessage(_internal_add_message_type(), ptr); + CHK_(ptr); + if (!ctx->DataAvailable(ptr)) break; + } while (::PROTOBUF_NAMESPACE_ID::internal::ExpectTag<34>(ptr)); + } else + goto handle_unusual; + continue; + // repeated .google.protobuf.EnumDescriptorProto enum_type = 5; + case 5: + if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 42)) { + ptr -= 1; + do { + ptr += 1; + ptr = ctx->ParseMessage(_internal_add_enum_type(), ptr); + CHK_(ptr); + if (!ctx->DataAvailable(ptr)) break; + } while (::PROTOBUF_NAMESPACE_ID::internal::ExpectTag<42>(ptr)); + } else + goto handle_unusual; + continue; + // repeated .google.protobuf.ServiceDescriptorProto service = 6; + case 6: + if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 50)) { + ptr -= 1; + do { + ptr += 1; + ptr = ctx->ParseMessage(_internal_add_service(), ptr); + CHK_(ptr); + if (!ctx->DataAvailable(ptr)) break; + } while (::PROTOBUF_NAMESPACE_ID::internal::ExpectTag<50>(ptr)); + } else + goto handle_unusual; + continue; + // repeated .google.protobuf.FieldDescriptorProto extension = 7; + case 7: + if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 58)) { + ptr -= 1; + do { + ptr += 1; + ptr = ctx->ParseMessage(_internal_add_extension(), ptr); + CHK_(ptr); + if (!ctx->DataAvailable(ptr)) break; + } while (::PROTOBUF_NAMESPACE_ID::internal::ExpectTag<58>(ptr)); + } else + goto handle_unusual; + continue; + // optional .google.protobuf.FileOptions options = 8; + case 8: + if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 66)) { + ptr = ctx->ParseMessage(_internal_mutable_options(), ptr); + CHK_(ptr); + } else + goto handle_unusual; + continue; + // optional .google.protobuf.SourceCodeInfo source_code_info = 9; + case 9: + if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 74)) { + ptr = ctx->ParseMessage(_internal_mutable_source_code_info(), ptr); + CHK_(ptr); + } else + goto handle_unusual; + continue; + // repeated int32 public_dependency = 10; + case 10: + if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 80)) { + ptr -= 1; + do { + ptr += 1; + _internal_add_public_dependency(::PROTOBUF_NAMESPACE_ID::internal::ReadVarint32(&ptr)); + CHK_(ptr); + if (!ctx->DataAvailable(ptr)) break; + } while (::PROTOBUF_NAMESPACE_ID::internal::ExpectTag<80>(ptr)); + } else if (static_cast<uint8_t>(tag) == 82) { + ptr = ::PROTOBUF_NAMESPACE_ID::internal::PackedInt32Parser(_internal_mutable_public_dependency(), ptr, ctx); + CHK_(ptr); + } else + goto handle_unusual; + continue; + // repeated int32 weak_dependency = 11; + case 11: + if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 88)) { + ptr -= 1; + do { + ptr += 1; + _internal_add_weak_dependency(::PROTOBUF_NAMESPACE_ID::internal::ReadVarint32(&ptr)); + CHK_(ptr); + if (!ctx->DataAvailable(ptr)) break; + } while (::PROTOBUF_NAMESPACE_ID::internal::ExpectTag<88>(ptr)); + } else if (static_cast<uint8_t>(tag) == 90) { + ptr = ::PROTOBUF_NAMESPACE_ID::internal::PackedInt32Parser(_internal_mutable_weak_dependency(), ptr, ctx); + CHK_(ptr); + } else + goto handle_unusual; + continue; + // optional string syntax = 12; + case 12: + if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 98)) { + auto str = _internal_mutable_syntax(); + ptr = ::PROTOBUF_NAMESPACE_ID::internal::InlineGreedyStringParser(str, ptr, ctx); + #ifndef NDEBUG + ::PROTOBUF_NAMESPACE_ID::internal::VerifyUTF8(str, "google.protobuf.FileDescriptorProto.syntax"); + #endif // !NDEBUG + CHK_(ptr); + } else + goto handle_unusual; + continue; + default: + goto handle_unusual; + } // switch + handle_unusual: + if ((tag == 0) || ((tag & 7) == 4)) { + CHK_(ptr); + ctx->SetLastTag(tag); + goto message_done; + } + ptr = UnknownFieldParse( + tag, + _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(), + ptr, ctx); + CHK_(ptr != nullptr); + } // while +message_done: + _has_bits_.Or(has_bits); + return ptr; +failure: + ptr = nullptr; + goto message_done; +#undef CHK_ +} + +uint8_t* FileDescriptorProto::_InternalSerialize( + uint8_t* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const { + // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.FileDescriptorProto) + arc_ui32 cached_has_bits = 0; + (void) cached_has_bits; + + cached_has_bits = _has_bits_[0]; + // optional string name = 1; + if (cached_has_bits & 0x00000001u) { + ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::VerifyUTF8StringNamedField( + this->_internal_name().data(), static_cast<int>(this->_internal_name().length()), + ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::SERIALIZE, + "google.protobuf.FileDescriptorProto.name"); + target = stream->WriteStringMaybeAliased( + 1, this->_internal_name(), target); + } + + // optional string package = 2; + if (cached_has_bits & 0x00000002u) { + ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::VerifyUTF8StringNamedField( + this->_internal_package().data(), static_cast<int>(this->_internal_package().length()), + ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::SERIALIZE, + "google.protobuf.FileDescriptorProto.package"); + target = stream->WriteStringMaybeAliased( + 2, this->_internal_package(), target); + } + + // repeated string dependency = 3; + for (int i = 0, n = this->_internal_dependency_size(); i < n; i++) { + const auto& s = this->_internal_dependency(i); + ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::VerifyUTF8StringNamedField( + s.data(), static_cast<int>(s.length()), + ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::SERIALIZE, + "google.protobuf.FileDescriptorProto.dependency"); + target = stream->WriteString(3, s, target); + } + + // repeated .google.protobuf.DescriptorProto message_type = 4; + for (unsigned int i = 0, + n = static_cast<unsigned int>(this->_internal_message_type_size()); i < n; i++) { + target = stream->EnsureSpace(target); + target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite:: + InternalWriteMessage(4, this->_internal_message_type(i), target, stream); + } + + // repeated .google.protobuf.EnumDescriptorProto enum_type = 5; + for (unsigned int i = 0, + n = static_cast<unsigned int>(this->_internal_enum_type_size()); i < n; i++) { + target = stream->EnsureSpace(target); + target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite:: + InternalWriteMessage(5, this->_internal_enum_type(i), target, stream); + } + + // repeated .google.protobuf.ServiceDescriptorProto service = 6; + for (unsigned int i = 0, + n = static_cast<unsigned int>(this->_internal_service_size()); i < n; i++) { + target = stream->EnsureSpace(target); + target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite:: + InternalWriteMessage(6, this->_internal_service(i), target, stream); + } + + // repeated .google.protobuf.FieldDescriptorProto extension = 7; + for (unsigned int i = 0, + n = static_cast<unsigned int>(this->_internal_extension_size()); i < n; i++) { + target = stream->EnsureSpace(target); + target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite:: + InternalWriteMessage(7, this->_internal_extension(i), target, stream); + } + + // optional .google.protobuf.FileOptions options = 8; + if (cached_has_bits & 0x00000008u) { + target = stream->EnsureSpace(target); + target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite:: + InternalWriteMessage( + 8, _Internal::options(this), target, stream); + } + + // optional .google.protobuf.SourceCodeInfo source_code_info = 9; + if (cached_has_bits & 0x00000010u) { + target = stream->EnsureSpace(target); + target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite:: + InternalWriteMessage( + 9, _Internal::source_code_info(this), target, stream); + } + + // repeated int32 public_dependency = 10; + for (int i = 0, n = this->_internal_public_dependency_size(); i < n; i++) { + target = stream->EnsureSpace(target); + target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteInt32ToArray(10, this->_internal_public_dependency(i), target); + } + + // repeated int32 weak_dependency = 11; + for (int i = 0, n = this->_internal_weak_dependency_size(); i < n; i++) { + target = stream->EnsureSpace(target); + target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteInt32ToArray(11, this->_internal_weak_dependency(i), target); + } + + // optional string syntax = 12; + if (cached_has_bits & 0x00000004u) { + ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::VerifyUTF8StringNamedField( + this->_internal_syntax().data(), static_cast<int>(this->_internal_syntax().length()), + ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::SERIALIZE, + "google.protobuf.FileDescriptorProto.syntax"); + target = stream->WriteStringMaybeAliased( + 12, this->_internal_syntax(), target); + } + + if (PROTOBUF_PREDICT_FALSE(_internal_metadata_.have_unknown_fields())) { + target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::InternalSerializeUnknownFieldsToArray( + _internal_metadata_.unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(::PROTOBUF_NAMESPACE_ID::UnknownFieldSet::default_instance), target, stream); + } + // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.FileDescriptorProto) + return target; +} + +size_t FileDescriptorProto::ByteSizeLong() const { +// @@protoc_insertion_point(message_byte_size_start:google.protobuf.FileDescriptorProto) + size_t total_size = 0; + + arc_ui32 cached_has_bits = 0; + // Prevent compiler warnings about cached_has_bits being unused + (void) cached_has_bits; + + // repeated string dependency = 3; + total_size += 1 * + ::PROTOBUF_NAMESPACE_ID::internal::FromIntSize(dependency_.size()); + for (int i = 0, n = dependency_.size(); i < n; i++) { + total_size += ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::StringSize( + dependency_.Get(i)); + } + + // repeated .google.protobuf.DescriptorProto message_type = 4; + total_size += 1UL * this->_internal_message_type_size(); + for (const auto& msg : this->message_type_) { + total_size += + ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::MessageSize(msg); + } + + // repeated .google.protobuf.EnumDescriptorProto enum_type = 5; + total_size += 1UL * this->_internal_enum_type_size(); + for (const auto& msg : this->enum_type_) { + total_size += + ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::MessageSize(msg); + } + + // repeated .google.protobuf.ServiceDescriptorProto service = 6; + total_size += 1UL * this->_internal_service_size(); + for (const auto& msg : this->service_) { + total_size += + ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::MessageSize(msg); + } + + // repeated .google.protobuf.FieldDescriptorProto extension = 7; + total_size += 1UL * this->_internal_extension_size(); + for (const auto& msg : this->extension_) { + total_size += + ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::MessageSize(msg); + } + + // repeated int32 public_dependency = 10; + { + size_t data_size = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite:: + Int32Size(this->public_dependency_); + total_size += 1 * + ::PROTOBUF_NAMESPACE_ID::internal::FromIntSize(this->_internal_public_dependency_size()); + total_size += data_size; + } + + // repeated int32 weak_dependency = 11; + { + size_t data_size = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite:: + Int32Size(this->weak_dependency_); + total_size += 1 * + ::PROTOBUF_NAMESPACE_ID::internal::FromIntSize(this->_internal_weak_dependency_size()); + total_size += data_size; + } + + cached_has_bits = _has_bits_[0]; + if (cached_has_bits & 0x0000001fu) { + // optional string name = 1; + if (cached_has_bits & 0x00000001u) { + total_size += 1 + + ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::StringSize( + this->_internal_name()); + } + + // optional string package = 2; + if (cached_has_bits & 0x00000002u) { + total_size += 1 + + ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::StringSize( + this->_internal_package()); + } + + // optional string syntax = 12; + if (cached_has_bits & 0x00000004u) { + total_size += 1 + + ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::StringSize( + this->_internal_syntax()); + } + + // optional .google.protobuf.FileOptions options = 8; + if (cached_has_bits & 0x00000008u) { + total_size += 1 + + ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::MessageSize( + *options_); + } + + // optional .google.protobuf.SourceCodeInfo source_code_info = 9; + if (cached_has_bits & 0x00000010u) { + total_size += 1 + + ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::MessageSize( + *source_code_info_); + } + + } + return MaybeComputeUnknownFieldsSize(total_size, &_cached_size_); +} + +const ::PROTOBUF_NAMESPACE_ID::Message::ClassData FileDescriptorProto::_class_data_ = { + ::PROTOBUF_NAMESPACE_ID::Message::CopyWithSizeCheck, + FileDescriptorProto::MergeImpl +}; +const ::PROTOBUF_NAMESPACE_ID::Message::ClassData*FileDescriptorProto::GetClassData() const { return &_class_data_; } + +void FileDescriptorProto::MergeImpl(::PROTOBUF_NAMESPACE_ID::Message* to, + const ::PROTOBUF_NAMESPACE_ID::Message& from) { + static_cast<FileDescriptorProto *>(to)->MergeFrom( + static_cast<const FileDescriptorProto &>(from)); +} + + +void FileDescriptorProto::MergeFrom(const FileDescriptorProto& from) { +// @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.FileDescriptorProto) + GOOGLE_DCHECK_NE(&from, this); + arc_ui32 cached_has_bits = 0; + (void) cached_has_bits; + + dependency_.MergeFrom(from.dependency_); + message_type_.MergeFrom(from.message_type_); + enum_type_.MergeFrom(from.enum_type_); + service_.MergeFrom(from.service_); + extension_.MergeFrom(from.extension_); + public_dependency_.MergeFrom(from.public_dependency_); + weak_dependency_.MergeFrom(from.weak_dependency_); + cached_has_bits = from._has_bits_[0]; + if (cached_has_bits & 0x0000001fu) { + if (cached_has_bits & 0x00000001u) { + _internal_set_name(from._internal_name()); + } + if (cached_has_bits & 0x00000002u) { + _internal_set_package(from._internal_package()); + } + if (cached_has_bits & 0x00000004u) { + _internal_set_syntax(from._internal_syntax()); + } + if (cached_has_bits & 0x00000008u) { + _internal_mutable_options()->::PROTOBUF_NAMESPACE_ID::FileOptions::MergeFrom(from._internal_options()); + } + if (cached_has_bits & 0x00000010u) { + _internal_mutable_source_code_info()->::PROTOBUF_NAMESPACE_ID::SourceCodeInfo::MergeFrom(from._internal_source_code_info()); + } + } + _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_); +} + +void FileDescriptorProto::CopyFrom(const FileDescriptorProto& from) { +// @@protoc_insertion_point(class_specific_copy_from_start:google.protobuf.FileDescriptorProto) + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool FileDescriptorProto::IsInitialized() const { + if (!::PROTOBUF_NAMESPACE_ID::internal::AllAreInitialized(message_type_)) + return false; + if (!::PROTOBUF_NAMESPACE_ID::internal::AllAreInitialized(enum_type_)) + return false; + if (!::PROTOBUF_NAMESPACE_ID::internal::AllAreInitialized(service_)) + return false; + if (!::PROTOBUF_NAMESPACE_ID::internal::AllAreInitialized(extension_)) + return false; + if (_internal_has_options()) { + if (!options_->IsInitialized()) return false; + } + return true; +} + +void FileDescriptorProto::InternalSwap(FileDescriptorProto* other) { + using std::swap; + auto* lhs_arena = GetArenaForAllocation(); + auto* rhs_arena = other->GetArenaForAllocation(); + _internal_metadata_.InternalSwap(&other->_internal_metadata_); + swap(_has_bits_[0], other->_has_bits_[0]); + dependency_.InternalSwap(&other->dependency_); + message_type_.InternalSwap(&other->message_type_); + enum_type_.InternalSwap(&other->enum_type_); + service_.InternalSwap(&other->service_); + extension_.InternalSwap(&other->extension_); + public_dependency_.InternalSwap(&other->public_dependency_); + weak_dependency_.InternalSwap(&other->weak_dependency_); + ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::InternalSwap( + &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), + &name_, lhs_arena, + &other->name_, rhs_arena + ); + ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::InternalSwap( + &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), + &package_, lhs_arena, + &other->package_, rhs_arena + ); + ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::InternalSwap( + &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), + &syntax_, lhs_arena, + &other->syntax_, rhs_arena + ); + ::PROTOBUF_NAMESPACE_ID::internal::memswap< + PROTOBUF_FIELD_OFFSET(FileDescriptorProto, source_code_info_) + + sizeof(FileDescriptorProto::source_code_info_) + - PROTOBUF_FIELD_OFFSET(FileDescriptorProto, options_)>( + reinterpret_cast<char*>(&options_), + reinterpret_cast<char*>(&other->options_)); +} + +::PROTOBUF_NAMESPACE_ID::Metadata FileDescriptorProto::GetMetadata() const { + return ::PROTOBUF_NAMESPACE_ID::internal::AssignDescriptors( + &descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_getter, &descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_once, + file_level_metadata_google_2fprotobuf_2fdescriptor_2eproto[1]); +} + +// =================================================================== + +class DescriptorProto_ExtensionRange::_Internal { + public: + using HasBits = decltype(std::declval<DescriptorProto_ExtensionRange>()._has_bits_); + static void set_has_start(HasBits* has_bits) { + (*has_bits)[0] |= 2u; + } + static void set_has_end(HasBits* has_bits) { + (*has_bits)[0] |= 4u; + } + static const ::PROTOBUF_NAMESPACE_ID::ExtensionRangeOptions& options(const DescriptorProto_ExtensionRange* msg); + static void set_has_options(HasBits* has_bits) { + (*has_bits)[0] |= 1u; + } +}; + +const ::PROTOBUF_NAMESPACE_ID::ExtensionRangeOptions& +DescriptorProto_ExtensionRange::_Internal::options(const DescriptorProto_ExtensionRange* msg) { + return *msg->options_; +} +DescriptorProto_ExtensionRange::DescriptorProto_ExtensionRange(::PROTOBUF_NAMESPACE_ID::Arena* arena, + bool is_message_owned) + : ::PROTOBUF_NAMESPACE_ID::Message(arena, is_message_owned) { + SharedCtor(); + if (!is_message_owned) { + RegisterArenaDtor(arena); + } + // @@protoc_insertion_point(arena_constructor:google.protobuf.DescriptorProto.ExtensionRange) +} +DescriptorProto_ExtensionRange::DescriptorProto_ExtensionRange(const DescriptorProto_ExtensionRange& from) + : ::PROTOBUF_NAMESPACE_ID::Message(), + _has_bits_(from._has_bits_) { + _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_); + if (from._internal_has_options()) { + options_ = new ::PROTOBUF_NAMESPACE_ID::ExtensionRangeOptions(*from.options_); + } else { + options_ = nullptr; + } + ::memcpy(&start_, &from.start_, + static_cast<size_t>(reinterpret_cast<char*>(&end_) - + reinterpret_cast<char*>(&start_)) + sizeof(end_)); + // @@protoc_insertion_point(copy_constructor:google.protobuf.DescriptorProto.ExtensionRange) +} + +inline void DescriptorProto_ExtensionRange::SharedCtor() { +::memset(reinterpret_cast<char*>(this) + static_cast<size_t>( + reinterpret_cast<char*>(&options_) - reinterpret_cast<char*>(this)), + 0, static_cast<size_t>(reinterpret_cast<char*>(&end_) - + reinterpret_cast<char*>(&options_)) + sizeof(end_)); +} + +DescriptorProto_ExtensionRange::~DescriptorProto_ExtensionRange() { + // @@protoc_insertion_point(destructor:google.protobuf.DescriptorProto.ExtensionRange) + if (GetArenaForAllocation() != nullptr) return; + SharedDtor(); + _internal_metadata_.Delete<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(); +} + +inline void DescriptorProto_ExtensionRange::SharedDtor() { + GOOGLE_DCHECK(GetArenaForAllocation() == nullptr); + if (this != internal_default_instance()) delete options_; +} + +void DescriptorProto_ExtensionRange::ArenaDtor(void* object) { + DescriptorProto_ExtensionRange* _this = reinterpret_cast< DescriptorProto_ExtensionRange* >(object); + (void)_this; +} +void DescriptorProto_ExtensionRange::RegisterArenaDtor(::PROTOBUF_NAMESPACE_ID::Arena*) { +} +void DescriptorProto_ExtensionRange::SetCachedSize(int size) const { + _cached_size_.Set(size); +} + +void DescriptorProto_ExtensionRange::Clear() { +// @@protoc_insertion_point(message_clear_start:google.protobuf.DescriptorProto.ExtensionRange) + arc_ui32 cached_has_bits = 0; + // Prevent compiler warnings about cached_has_bits being unused + (void) cached_has_bits; + + cached_has_bits = _has_bits_[0]; + if (cached_has_bits & 0x00000001u) { + GOOGLE_DCHECK(options_ != nullptr); + options_->Clear(); + } + if (cached_has_bits & 0x00000006u) { + ::memset(&start_, 0, static_cast<size_t>( + reinterpret_cast<char*>(&end_) - + reinterpret_cast<char*>(&start_)) + sizeof(end_)); + } + _has_bits_.Clear(); + _internal_metadata_.Clear<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(); +} + +const char* DescriptorProto_ExtensionRange::_InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) { +#define CHK_(x) if (PROTOBUF_PREDICT_FALSE(!(x))) goto failure + _Internal::HasBits has_bits{}; + while (!ctx->Done(&ptr)) { + arc_ui32 tag; + ptr = ::PROTOBUF_NAMESPACE_ID::internal::ReadTag(ptr, &tag); + switch (tag >> 3) { + // optional int32 start = 1; + case 1: + if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 8)) { + _Internal::set_has_start(&has_bits); + start_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint32(&ptr); + CHK_(ptr); + } else + goto handle_unusual; + continue; + // optional int32 end = 2; + case 2: + if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 16)) { + _Internal::set_has_end(&has_bits); + end_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint32(&ptr); + CHK_(ptr); + } else + goto handle_unusual; + continue; + // optional .google.protobuf.ExtensionRangeOptions options = 3; + case 3: + if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 26)) { + ptr = ctx->ParseMessage(_internal_mutable_options(), ptr); + CHK_(ptr); + } else + goto handle_unusual; + continue; + default: + goto handle_unusual; + } // switch + handle_unusual: + if ((tag == 0) || ((tag & 7) == 4)) { + CHK_(ptr); + ctx->SetLastTag(tag); + goto message_done; + } + ptr = UnknownFieldParse( + tag, + _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(), + ptr, ctx); + CHK_(ptr != nullptr); + } // while +message_done: + _has_bits_.Or(has_bits); + return ptr; +failure: + ptr = nullptr; + goto message_done; +#undef CHK_ +} + +uint8_t* DescriptorProto_ExtensionRange::_InternalSerialize( + uint8_t* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const { + // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.DescriptorProto.ExtensionRange) + arc_ui32 cached_has_bits = 0; + (void) cached_has_bits; + + cached_has_bits = _has_bits_[0]; + // optional int32 start = 1; + if (cached_has_bits & 0x00000002u) { + target = stream->EnsureSpace(target); + target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteInt32ToArray(1, this->_internal_start(), target); + } + + // optional int32 end = 2; + if (cached_has_bits & 0x00000004u) { + target = stream->EnsureSpace(target); + target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteInt32ToArray(2, this->_internal_end(), target); + } + + // optional .google.protobuf.ExtensionRangeOptions options = 3; + if (cached_has_bits & 0x00000001u) { + target = stream->EnsureSpace(target); + target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite:: + InternalWriteMessage( + 3, _Internal::options(this), target, stream); + } + + if (PROTOBUF_PREDICT_FALSE(_internal_metadata_.have_unknown_fields())) { + target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::InternalSerializeUnknownFieldsToArray( + _internal_metadata_.unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(::PROTOBUF_NAMESPACE_ID::UnknownFieldSet::default_instance), target, stream); + } + // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.DescriptorProto.ExtensionRange) + return target; +} + +size_t DescriptorProto_ExtensionRange::ByteSizeLong() const { +// @@protoc_insertion_point(message_byte_size_start:google.protobuf.DescriptorProto.ExtensionRange) + size_t total_size = 0; + + arc_ui32 cached_has_bits = 0; + // Prevent compiler warnings about cached_has_bits being unused + (void) cached_has_bits; + + cached_has_bits = _has_bits_[0]; + if (cached_has_bits & 0x00000007u) { + // optional .google.protobuf.ExtensionRangeOptions options = 3; + if (cached_has_bits & 0x00000001u) { + total_size += 1 + + ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::MessageSize( + *options_); + } + + // optional int32 start = 1; + if (cached_has_bits & 0x00000002u) { + total_size += ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::Int32SizePlusOne(this->_internal_start()); + } + + // optional int32 end = 2; + if (cached_has_bits & 0x00000004u) { + total_size += ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::Int32SizePlusOne(this->_internal_end()); + } + + } + return MaybeComputeUnknownFieldsSize(total_size, &_cached_size_); +} + +const ::PROTOBUF_NAMESPACE_ID::Message::ClassData DescriptorProto_ExtensionRange::_class_data_ = { + ::PROTOBUF_NAMESPACE_ID::Message::CopyWithSizeCheck, + DescriptorProto_ExtensionRange::MergeImpl +}; +const ::PROTOBUF_NAMESPACE_ID::Message::ClassData*DescriptorProto_ExtensionRange::GetClassData() const { return &_class_data_; } + +void DescriptorProto_ExtensionRange::MergeImpl(::PROTOBUF_NAMESPACE_ID::Message* to, + const ::PROTOBUF_NAMESPACE_ID::Message& from) { + static_cast<DescriptorProto_ExtensionRange *>(to)->MergeFrom( + static_cast<const DescriptorProto_ExtensionRange &>(from)); +} + + +void DescriptorProto_ExtensionRange::MergeFrom(const DescriptorProto_ExtensionRange& from) { +// @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.DescriptorProto.ExtensionRange) + GOOGLE_DCHECK_NE(&from, this); + arc_ui32 cached_has_bits = 0; + (void) cached_has_bits; + + cached_has_bits = from._has_bits_[0]; + if (cached_has_bits & 0x00000007u) { + if (cached_has_bits & 0x00000001u) { + _internal_mutable_options()->::PROTOBUF_NAMESPACE_ID::ExtensionRangeOptions::MergeFrom(from._internal_options()); + } + if (cached_has_bits & 0x00000002u) { + start_ = from.start_; + } + if (cached_has_bits & 0x00000004u) { + end_ = from.end_; + } + _has_bits_[0] |= cached_has_bits; + } + _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_); +} + +void DescriptorProto_ExtensionRange::CopyFrom(const DescriptorProto_ExtensionRange& from) { +// @@protoc_insertion_point(class_specific_copy_from_start:google.protobuf.DescriptorProto.ExtensionRange) + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool DescriptorProto_ExtensionRange::IsInitialized() const { + if (_internal_has_options()) { + if (!options_->IsInitialized()) return false; + } + return true; +} + +void DescriptorProto_ExtensionRange::InternalSwap(DescriptorProto_ExtensionRange* other) { + using std::swap; + _internal_metadata_.InternalSwap(&other->_internal_metadata_); + swap(_has_bits_[0], other->_has_bits_[0]); + ::PROTOBUF_NAMESPACE_ID::internal::memswap< + PROTOBUF_FIELD_OFFSET(DescriptorProto_ExtensionRange, end_) + + sizeof(DescriptorProto_ExtensionRange::end_) + - PROTOBUF_FIELD_OFFSET(DescriptorProto_ExtensionRange, options_)>( + reinterpret_cast<char*>(&options_), + reinterpret_cast<char*>(&other->options_)); +} + +::PROTOBUF_NAMESPACE_ID::Metadata DescriptorProto_ExtensionRange::GetMetadata() const { + return ::PROTOBUF_NAMESPACE_ID::internal::AssignDescriptors( + &descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_getter, &descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_once, + file_level_metadata_google_2fprotobuf_2fdescriptor_2eproto[2]); +} + +// =================================================================== + +class DescriptorProto_ReservedRange::_Internal { + public: + using HasBits = decltype(std::declval<DescriptorProto_ReservedRange>()._has_bits_); + static void set_has_start(HasBits* has_bits) { + (*has_bits)[0] |= 1u; + } + static void set_has_end(HasBits* has_bits) { + (*has_bits)[0] |= 2u; + } +}; + +DescriptorProto_ReservedRange::DescriptorProto_ReservedRange(::PROTOBUF_NAMESPACE_ID::Arena* arena, + bool is_message_owned) + : ::PROTOBUF_NAMESPACE_ID::Message(arena, is_message_owned) { + SharedCtor(); + if (!is_message_owned) { + RegisterArenaDtor(arena); + } + // @@protoc_insertion_point(arena_constructor:google.protobuf.DescriptorProto.ReservedRange) +} +DescriptorProto_ReservedRange::DescriptorProto_ReservedRange(const DescriptorProto_ReservedRange& from) + : ::PROTOBUF_NAMESPACE_ID::Message(), + _has_bits_(from._has_bits_) { + _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_); + ::memcpy(&start_, &from.start_, + static_cast<size_t>(reinterpret_cast<char*>(&end_) - + reinterpret_cast<char*>(&start_)) + sizeof(end_)); + // @@protoc_insertion_point(copy_constructor:google.protobuf.DescriptorProto.ReservedRange) +} + +inline void DescriptorProto_ReservedRange::SharedCtor() { +::memset(reinterpret_cast<char*>(this) + static_cast<size_t>( + reinterpret_cast<char*>(&start_) - reinterpret_cast<char*>(this)), + 0, static_cast<size_t>(reinterpret_cast<char*>(&end_) - + reinterpret_cast<char*>(&start_)) + sizeof(end_)); +} + +DescriptorProto_ReservedRange::~DescriptorProto_ReservedRange() { + // @@protoc_insertion_point(destructor:google.protobuf.DescriptorProto.ReservedRange) + if (GetArenaForAllocation() != nullptr) return; + SharedDtor(); + _internal_metadata_.Delete<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(); +} + +inline void DescriptorProto_ReservedRange::SharedDtor() { + GOOGLE_DCHECK(GetArenaForAllocation() == nullptr); +} + +void DescriptorProto_ReservedRange::ArenaDtor(void* object) { + DescriptorProto_ReservedRange* _this = reinterpret_cast< DescriptorProto_ReservedRange* >(object); + (void)_this; +} +void DescriptorProto_ReservedRange::RegisterArenaDtor(::PROTOBUF_NAMESPACE_ID::Arena*) { +} +void DescriptorProto_ReservedRange::SetCachedSize(int size) const { + _cached_size_.Set(size); +} + +void DescriptorProto_ReservedRange::Clear() { +// @@protoc_insertion_point(message_clear_start:google.protobuf.DescriptorProto.ReservedRange) + arc_ui32 cached_has_bits = 0; + // Prevent compiler warnings about cached_has_bits being unused + (void) cached_has_bits; + + cached_has_bits = _has_bits_[0]; + if (cached_has_bits & 0x00000003u) { + ::memset(&start_, 0, static_cast<size_t>( + reinterpret_cast<char*>(&end_) - + reinterpret_cast<char*>(&start_)) + sizeof(end_)); + } + _has_bits_.Clear(); + _internal_metadata_.Clear<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(); +} + +const char* DescriptorProto_ReservedRange::_InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) { +#define CHK_(x) if (PROTOBUF_PREDICT_FALSE(!(x))) goto failure + _Internal::HasBits has_bits{}; + while (!ctx->Done(&ptr)) { + arc_ui32 tag; + ptr = ::PROTOBUF_NAMESPACE_ID::internal::ReadTag(ptr, &tag); + switch (tag >> 3) { + // optional int32 start = 1; + case 1: + if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 8)) { + _Internal::set_has_start(&has_bits); + start_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint32(&ptr); + CHK_(ptr); + } else + goto handle_unusual; + continue; + // optional int32 end = 2; + case 2: + if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 16)) { + _Internal::set_has_end(&has_bits); + end_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint32(&ptr); + CHK_(ptr); + } else + goto handle_unusual; + continue; + default: + goto handle_unusual; + } // switch + handle_unusual: + if ((tag == 0) || ((tag & 7) == 4)) { + CHK_(ptr); + ctx->SetLastTag(tag); + goto message_done; + } + ptr = UnknownFieldParse( + tag, + _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(), + ptr, ctx); + CHK_(ptr != nullptr); + } // while +message_done: + _has_bits_.Or(has_bits); + return ptr; +failure: + ptr = nullptr; + goto message_done; +#undef CHK_ +} + +uint8_t* DescriptorProto_ReservedRange::_InternalSerialize( + uint8_t* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const { + // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.DescriptorProto.ReservedRange) + arc_ui32 cached_has_bits = 0; + (void) cached_has_bits; + + cached_has_bits = _has_bits_[0]; + // optional int32 start = 1; + if (cached_has_bits & 0x00000001u) { + target = stream->EnsureSpace(target); + target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteInt32ToArray(1, this->_internal_start(), target); + } + + // optional int32 end = 2; + if (cached_has_bits & 0x00000002u) { + target = stream->EnsureSpace(target); + target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteInt32ToArray(2, this->_internal_end(), target); + } + + if (PROTOBUF_PREDICT_FALSE(_internal_metadata_.have_unknown_fields())) { + target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::InternalSerializeUnknownFieldsToArray( + _internal_metadata_.unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(::PROTOBUF_NAMESPACE_ID::UnknownFieldSet::default_instance), target, stream); + } + // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.DescriptorProto.ReservedRange) + return target; +} + +size_t DescriptorProto_ReservedRange::ByteSizeLong() const { +// @@protoc_insertion_point(message_byte_size_start:google.protobuf.DescriptorProto.ReservedRange) + size_t total_size = 0; + + arc_ui32 cached_has_bits = 0; + // Prevent compiler warnings about cached_has_bits being unused + (void) cached_has_bits; + + cached_has_bits = _has_bits_[0]; + if (cached_has_bits & 0x00000003u) { + // optional int32 start = 1; + if (cached_has_bits & 0x00000001u) { + total_size += ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::Int32SizePlusOne(this->_internal_start()); + } + + // optional int32 end = 2; + if (cached_has_bits & 0x00000002u) { + total_size += ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::Int32SizePlusOne(this->_internal_end()); + } + + } + return MaybeComputeUnknownFieldsSize(total_size, &_cached_size_); +} + +const ::PROTOBUF_NAMESPACE_ID::Message::ClassData DescriptorProto_ReservedRange::_class_data_ = { + ::PROTOBUF_NAMESPACE_ID::Message::CopyWithSizeCheck, + DescriptorProto_ReservedRange::MergeImpl +}; +const ::PROTOBUF_NAMESPACE_ID::Message::ClassData*DescriptorProto_ReservedRange::GetClassData() const { return &_class_data_; } + +void DescriptorProto_ReservedRange::MergeImpl(::PROTOBUF_NAMESPACE_ID::Message* to, + const ::PROTOBUF_NAMESPACE_ID::Message& from) { + static_cast<DescriptorProto_ReservedRange *>(to)->MergeFrom( + static_cast<const DescriptorProto_ReservedRange &>(from)); +} + + +void DescriptorProto_ReservedRange::MergeFrom(const DescriptorProto_ReservedRange& from) { +// @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.DescriptorProto.ReservedRange) + GOOGLE_DCHECK_NE(&from, this); + arc_ui32 cached_has_bits = 0; + (void) cached_has_bits; + + cached_has_bits = from._has_bits_[0]; + if (cached_has_bits & 0x00000003u) { + if (cached_has_bits & 0x00000001u) { + start_ = from.start_; + } + if (cached_has_bits & 0x00000002u) { + end_ = from.end_; + } + _has_bits_[0] |= cached_has_bits; + } + _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_); +} + +void DescriptorProto_ReservedRange::CopyFrom(const DescriptorProto_ReservedRange& from) { +// @@protoc_insertion_point(class_specific_copy_from_start:google.protobuf.DescriptorProto.ReservedRange) + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool DescriptorProto_ReservedRange::IsInitialized() const { + return true; +} + +void DescriptorProto_ReservedRange::InternalSwap(DescriptorProto_ReservedRange* other) { + using std::swap; + _internal_metadata_.InternalSwap(&other->_internal_metadata_); + swap(_has_bits_[0], other->_has_bits_[0]); + ::PROTOBUF_NAMESPACE_ID::internal::memswap< + PROTOBUF_FIELD_OFFSET(DescriptorProto_ReservedRange, end_) + + sizeof(DescriptorProto_ReservedRange::end_) + - PROTOBUF_FIELD_OFFSET(DescriptorProto_ReservedRange, start_)>( + reinterpret_cast<char*>(&start_), + reinterpret_cast<char*>(&other->start_)); +} + +::PROTOBUF_NAMESPACE_ID::Metadata DescriptorProto_ReservedRange::GetMetadata() const { + return ::PROTOBUF_NAMESPACE_ID::internal::AssignDescriptors( + &descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_getter, &descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_once, + file_level_metadata_google_2fprotobuf_2fdescriptor_2eproto[3]); +} + +// =================================================================== + +class DescriptorProto::_Internal { + public: + using HasBits = decltype(std::declval<DescriptorProto>()._has_bits_); + static void set_has_name(HasBits* has_bits) { + (*has_bits)[0] |= 1u; + } + static const ::PROTOBUF_NAMESPACE_ID::MessageOptions& options(const DescriptorProto* msg); + static void set_has_options(HasBits* has_bits) { + (*has_bits)[0] |= 2u; + } +}; + +const ::PROTOBUF_NAMESPACE_ID::MessageOptions& +DescriptorProto::_Internal::options(const DescriptorProto* msg) { + return *msg->options_; +} +DescriptorProto::DescriptorProto(::PROTOBUF_NAMESPACE_ID::Arena* arena, + bool is_message_owned) + : ::PROTOBUF_NAMESPACE_ID::Message(arena, is_message_owned), + field_(arena), + nested_type_(arena), + enum_type_(arena), + extension_range_(arena), + extension_(arena), + oneof_decl_(arena), + reserved_range_(arena), + reserved_name_(arena) { + SharedCtor(); + if (!is_message_owned) { + RegisterArenaDtor(arena); + } + // @@protoc_insertion_point(arena_constructor:google.protobuf.DescriptorProto) +} +DescriptorProto::DescriptorProto(const DescriptorProto& from) + : ::PROTOBUF_NAMESPACE_ID::Message(), + _has_bits_(from._has_bits_), + field_(from.field_), + nested_type_(from.nested_type_), + enum_type_(from.enum_type_), + extension_range_(from.extension_range_), + extension_(from.extension_), + oneof_decl_(from.oneof_decl_), + reserved_range_(from.reserved_range_), + reserved_name_(from.reserved_name_) { + _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_); + name_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); + #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING + name_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation()); + #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING + if (from._internal_has_name()) { + name_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, from._internal_name(), + GetArenaForAllocation()); + } + if (from._internal_has_options()) { + options_ = new ::PROTOBUF_NAMESPACE_ID::MessageOptions(*from.options_); + } else { + options_ = nullptr; + } + // @@protoc_insertion_point(copy_constructor:google.protobuf.DescriptorProto) +} + +inline void DescriptorProto::SharedCtor() { +name_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); +#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING + name_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation()); +#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING +options_ = nullptr; +} + +DescriptorProto::~DescriptorProto() { + // @@protoc_insertion_point(destructor:google.protobuf.DescriptorProto) + if (GetArenaForAllocation() != nullptr) return; + SharedDtor(); + _internal_metadata_.Delete<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(); +} + +inline void DescriptorProto::SharedDtor() { + GOOGLE_DCHECK(GetArenaForAllocation() == nullptr); + name_.DestroyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); + if (this != internal_default_instance()) delete options_; +} + +void DescriptorProto::ArenaDtor(void* object) { + DescriptorProto* _this = reinterpret_cast< DescriptorProto* >(object); + (void)_this; +} +void DescriptorProto::RegisterArenaDtor(::PROTOBUF_NAMESPACE_ID::Arena*) { +} +void DescriptorProto::SetCachedSize(int size) const { + _cached_size_.Set(size); +} + +void DescriptorProto::Clear() { +// @@protoc_insertion_point(message_clear_start:google.protobuf.DescriptorProto) + arc_ui32 cached_has_bits = 0; + // Prevent compiler warnings about cached_has_bits being unused + (void) cached_has_bits; + + field_.Clear(); + nested_type_.Clear(); + enum_type_.Clear(); + extension_range_.Clear(); + extension_.Clear(); + oneof_decl_.Clear(); + reserved_range_.Clear(); + reserved_name_.Clear(); + cached_has_bits = _has_bits_[0]; + if (cached_has_bits & 0x00000003u) { + if (cached_has_bits & 0x00000001u) { + name_.ClearNonDefaultToEmpty(); + } + if (cached_has_bits & 0x00000002u) { + GOOGLE_DCHECK(options_ != nullptr); + options_->Clear(); + } + } + _has_bits_.Clear(); + _internal_metadata_.Clear<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(); +} + +const char* DescriptorProto::_InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) { +#define CHK_(x) if (PROTOBUF_PREDICT_FALSE(!(x))) goto failure + _Internal::HasBits has_bits{}; + while (!ctx->Done(&ptr)) { + arc_ui32 tag; + ptr = ::PROTOBUF_NAMESPACE_ID::internal::ReadTag(ptr, &tag); + switch (tag >> 3) { + // optional string name = 1; + case 1: + if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 10)) { + auto str = _internal_mutable_name(); + ptr = ::PROTOBUF_NAMESPACE_ID::internal::InlineGreedyStringParser(str, ptr, ctx); + #ifndef NDEBUG + ::PROTOBUF_NAMESPACE_ID::internal::VerifyUTF8(str, "google.protobuf.DescriptorProto.name"); + #endif // !NDEBUG + CHK_(ptr); + } else + goto handle_unusual; + continue; + // repeated .google.protobuf.FieldDescriptorProto field = 2; + case 2: + if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 18)) { + ptr -= 1; + do { + ptr += 1; + ptr = ctx->ParseMessage(_internal_add_field(), ptr); + CHK_(ptr); + if (!ctx->DataAvailable(ptr)) break; + } while (::PROTOBUF_NAMESPACE_ID::internal::ExpectTag<18>(ptr)); + } else + goto handle_unusual; + continue; + // repeated .google.protobuf.DescriptorProto nested_type = 3; + case 3: + if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 26)) { + ptr -= 1; + do { + ptr += 1; + ptr = ctx->ParseMessage(_internal_add_nested_type(), ptr); + CHK_(ptr); + if (!ctx->DataAvailable(ptr)) break; + } while (::PROTOBUF_NAMESPACE_ID::internal::ExpectTag<26>(ptr)); + } else + goto handle_unusual; + continue; + // repeated .google.protobuf.EnumDescriptorProto enum_type = 4; + case 4: + if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 34)) { + ptr -= 1; + do { + ptr += 1; + ptr = ctx->ParseMessage(_internal_add_enum_type(), ptr); + CHK_(ptr); + if (!ctx->DataAvailable(ptr)) break; + } while (::PROTOBUF_NAMESPACE_ID::internal::ExpectTag<34>(ptr)); + } else + goto handle_unusual; + continue; + // repeated .google.protobuf.DescriptorProto.ExtensionRange extension_range = 5; + case 5: + if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 42)) { + ptr -= 1; + do { + ptr += 1; + ptr = ctx->ParseMessage(_internal_add_extension_range(), ptr); + CHK_(ptr); + if (!ctx->DataAvailable(ptr)) break; + } while (::PROTOBUF_NAMESPACE_ID::internal::ExpectTag<42>(ptr)); + } else + goto handle_unusual; + continue; + // repeated .google.protobuf.FieldDescriptorProto extension = 6; + case 6: + if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 50)) { + ptr -= 1; + do { + ptr += 1; + ptr = ctx->ParseMessage(_internal_add_extension(), ptr); + CHK_(ptr); + if (!ctx->DataAvailable(ptr)) break; + } while (::PROTOBUF_NAMESPACE_ID::internal::ExpectTag<50>(ptr)); + } else + goto handle_unusual; + continue; + // optional .google.protobuf.MessageOptions options = 7; + case 7: + if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 58)) { + ptr = ctx->ParseMessage(_internal_mutable_options(), ptr); + CHK_(ptr); + } else + goto handle_unusual; + continue; + // repeated .google.protobuf.OneofDescriptorProto oneof_decl = 8; + case 8: + if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 66)) { + ptr -= 1; + do { + ptr += 1; + ptr = ctx->ParseMessage(_internal_add_oneof_decl(), ptr); + CHK_(ptr); + if (!ctx->DataAvailable(ptr)) break; + } while (::PROTOBUF_NAMESPACE_ID::internal::ExpectTag<66>(ptr)); + } else + goto handle_unusual; + continue; + // repeated .google.protobuf.DescriptorProto.ReservedRange reserved_range = 9; + case 9: + if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 74)) { + ptr -= 1; + do { + ptr += 1; + ptr = ctx->ParseMessage(_internal_add_reserved_range(), ptr); + CHK_(ptr); + if (!ctx->DataAvailable(ptr)) break; + } while (::PROTOBUF_NAMESPACE_ID::internal::ExpectTag<74>(ptr)); + } else + goto handle_unusual; + continue; + // repeated string reserved_name = 10; + case 10: + if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 82)) { + ptr -= 1; + do { + ptr += 1; + auto str = _internal_add_reserved_name(); + ptr = ::PROTOBUF_NAMESPACE_ID::internal::InlineGreedyStringParser(str, ptr, ctx); + #ifndef NDEBUG + ::PROTOBUF_NAMESPACE_ID::internal::VerifyUTF8(str, "google.protobuf.DescriptorProto.reserved_name"); + #endif // !NDEBUG + CHK_(ptr); + if (!ctx->DataAvailable(ptr)) break; + } while (::PROTOBUF_NAMESPACE_ID::internal::ExpectTag<82>(ptr)); + } else + goto handle_unusual; + continue; + default: + goto handle_unusual; + } // switch + handle_unusual: + if ((tag == 0) || ((tag & 7) == 4)) { + CHK_(ptr); + ctx->SetLastTag(tag); + goto message_done; + } + ptr = UnknownFieldParse( + tag, + _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(), + ptr, ctx); + CHK_(ptr != nullptr); + } // while +message_done: + _has_bits_.Or(has_bits); + return ptr; +failure: + ptr = nullptr; + goto message_done; +#undef CHK_ +} + +uint8_t* DescriptorProto::_InternalSerialize( + uint8_t* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const { + // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.DescriptorProto) + arc_ui32 cached_has_bits = 0; + (void) cached_has_bits; + + cached_has_bits = _has_bits_[0]; + // optional string name = 1; + if (cached_has_bits & 0x00000001u) { + ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::VerifyUTF8StringNamedField( + this->_internal_name().data(), static_cast<int>(this->_internal_name().length()), + ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::SERIALIZE, + "google.protobuf.DescriptorProto.name"); + target = stream->WriteStringMaybeAliased( + 1, this->_internal_name(), target); + } + + // repeated .google.protobuf.FieldDescriptorProto field = 2; + for (unsigned int i = 0, + n = static_cast<unsigned int>(this->_internal_field_size()); i < n; i++) { + target = stream->EnsureSpace(target); + target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite:: + InternalWriteMessage(2, this->_internal_field(i), target, stream); + } + + // repeated .google.protobuf.DescriptorProto nested_type = 3; + for (unsigned int i = 0, + n = static_cast<unsigned int>(this->_internal_nested_type_size()); i < n; i++) { + target = stream->EnsureSpace(target); + target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite:: + InternalWriteMessage(3, this->_internal_nested_type(i), target, stream); + } + + // repeated .google.protobuf.EnumDescriptorProto enum_type = 4; + for (unsigned int i = 0, + n = static_cast<unsigned int>(this->_internal_enum_type_size()); i < n; i++) { + target = stream->EnsureSpace(target); + target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite:: + InternalWriteMessage(4, this->_internal_enum_type(i), target, stream); + } + + // repeated .google.protobuf.DescriptorProto.ExtensionRange extension_range = 5; + for (unsigned int i = 0, + n = static_cast<unsigned int>(this->_internal_extension_range_size()); i < n; i++) { + target = stream->EnsureSpace(target); + target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite:: + InternalWriteMessage(5, this->_internal_extension_range(i), target, stream); + } + + // repeated .google.protobuf.FieldDescriptorProto extension = 6; + for (unsigned int i = 0, + n = static_cast<unsigned int>(this->_internal_extension_size()); i < n; i++) { + target = stream->EnsureSpace(target); + target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite:: + InternalWriteMessage(6, this->_internal_extension(i), target, stream); + } + + // optional .google.protobuf.MessageOptions options = 7; + if (cached_has_bits & 0x00000002u) { + target = stream->EnsureSpace(target); + target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite:: + InternalWriteMessage( + 7, _Internal::options(this), target, stream); + } + + // repeated .google.protobuf.OneofDescriptorProto oneof_decl = 8; + for (unsigned int i = 0, + n = static_cast<unsigned int>(this->_internal_oneof_decl_size()); i < n; i++) { + target = stream->EnsureSpace(target); + target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite:: + InternalWriteMessage(8, this->_internal_oneof_decl(i), target, stream); + } + + // repeated .google.protobuf.DescriptorProto.ReservedRange reserved_range = 9; + for (unsigned int i = 0, + n = static_cast<unsigned int>(this->_internal_reserved_range_size()); i < n; i++) { + target = stream->EnsureSpace(target); + target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite:: + InternalWriteMessage(9, this->_internal_reserved_range(i), target, stream); + } + + // repeated string reserved_name = 10; + for (int i = 0, n = this->_internal_reserved_name_size(); i < n; i++) { + const auto& s = this->_internal_reserved_name(i); + ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::VerifyUTF8StringNamedField( + s.data(), static_cast<int>(s.length()), + ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::SERIALIZE, + "google.protobuf.DescriptorProto.reserved_name"); + target = stream->WriteString(10, s, target); + } + + if (PROTOBUF_PREDICT_FALSE(_internal_metadata_.have_unknown_fields())) { + target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::InternalSerializeUnknownFieldsToArray( + _internal_metadata_.unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(::PROTOBUF_NAMESPACE_ID::UnknownFieldSet::default_instance), target, stream); + } + // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.DescriptorProto) + return target; +} + +size_t DescriptorProto::ByteSizeLong() const { +// @@protoc_insertion_point(message_byte_size_start:google.protobuf.DescriptorProto) + size_t total_size = 0; + + arc_ui32 cached_has_bits = 0; + // Prevent compiler warnings about cached_has_bits being unused + (void) cached_has_bits; + + // repeated .google.protobuf.FieldDescriptorProto field = 2; + total_size += 1UL * this->_internal_field_size(); + for (const auto& msg : this->field_) { + total_size += + ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::MessageSize(msg); + } + + // repeated .google.protobuf.DescriptorProto nested_type = 3; + total_size += 1UL * this->_internal_nested_type_size(); + for (const auto& msg : this->nested_type_) { + total_size += + ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::MessageSize(msg); + } + + // repeated .google.protobuf.EnumDescriptorProto enum_type = 4; + total_size += 1UL * this->_internal_enum_type_size(); + for (const auto& msg : this->enum_type_) { + total_size += + ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::MessageSize(msg); + } + + // repeated .google.protobuf.DescriptorProto.ExtensionRange extension_range = 5; + total_size += 1UL * this->_internal_extension_range_size(); + for (const auto& msg : this->extension_range_) { + total_size += + ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::MessageSize(msg); + } + + // repeated .google.protobuf.FieldDescriptorProto extension = 6; + total_size += 1UL * this->_internal_extension_size(); + for (const auto& msg : this->extension_) { + total_size += + ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::MessageSize(msg); + } + + // repeated .google.protobuf.OneofDescriptorProto oneof_decl = 8; + total_size += 1UL * this->_internal_oneof_decl_size(); + for (const auto& msg : this->oneof_decl_) { + total_size += + ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::MessageSize(msg); + } + + // repeated .google.protobuf.DescriptorProto.ReservedRange reserved_range = 9; + total_size += 1UL * this->_internal_reserved_range_size(); + for (const auto& msg : this->reserved_range_) { + total_size += + ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::MessageSize(msg); + } + + // repeated string reserved_name = 10; + total_size += 1 * + ::PROTOBUF_NAMESPACE_ID::internal::FromIntSize(reserved_name_.size()); + for (int i = 0, n = reserved_name_.size(); i < n; i++) { + total_size += ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::StringSize( + reserved_name_.Get(i)); + } + + cached_has_bits = _has_bits_[0]; + if (cached_has_bits & 0x00000003u) { + // optional string name = 1; + if (cached_has_bits & 0x00000001u) { + total_size += 1 + + ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::StringSize( + this->_internal_name()); + } + + // optional .google.protobuf.MessageOptions options = 7; + if (cached_has_bits & 0x00000002u) { + total_size += 1 + + ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::MessageSize( + *options_); + } + + } + return MaybeComputeUnknownFieldsSize(total_size, &_cached_size_); +} + +const ::PROTOBUF_NAMESPACE_ID::Message::ClassData DescriptorProto::_class_data_ = { + ::PROTOBUF_NAMESPACE_ID::Message::CopyWithSizeCheck, + DescriptorProto::MergeImpl +}; +const ::PROTOBUF_NAMESPACE_ID::Message::ClassData*DescriptorProto::GetClassData() const { return &_class_data_; } + +void DescriptorProto::MergeImpl(::PROTOBUF_NAMESPACE_ID::Message* to, + const ::PROTOBUF_NAMESPACE_ID::Message& from) { + static_cast<DescriptorProto *>(to)->MergeFrom( + static_cast<const DescriptorProto &>(from)); +} + + +void DescriptorProto::MergeFrom(const DescriptorProto& from) { +// @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.DescriptorProto) + GOOGLE_DCHECK_NE(&from, this); + arc_ui32 cached_has_bits = 0; + (void) cached_has_bits; + + field_.MergeFrom(from.field_); + nested_type_.MergeFrom(from.nested_type_); + enum_type_.MergeFrom(from.enum_type_); + extension_range_.MergeFrom(from.extension_range_); + extension_.MergeFrom(from.extension_); + oneof_decl_.MergeFrom(from.oneof_decl_); + reserved_range_.MergeFrom(from.reserved_range_); + reserved_name_.MergeFrom(from.reserved_name_); + cached_has_bits = from._has_bits_[0]; + if (cached_has_bits & 0x00000003u) { + if (cached_has_bits & 0x00000001u) { + _internal_set_name(from._internal_name()); + } + if (cached_has_bits & 0x00000002u) { + _internal_mutable_options()->::PROTOBUF_NAMESPACE_ID::MessageOptions::MergeFrom(from._internal_options()); + } + } + _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_); +} + +void DescriptorProto::CopyFrom(const DescriptorProto& from) { +// @@protoc_insertion_point(class_specific_copy_from_start:google.protobuf.DescriptorProto) + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool DescriptorProto::IsInitialized() const { + if (!::PROTOBUF_NAMESPACE_ID::internal::AllAreInitialized(field_)) + return false; + if (!::PROTOBUF_NAMESPACE_ID::internal::AllAreInitialized(nested_type_)) + return false; + if (!::PROTOBUF_NAMESPACE_ID::internal::AllAreInitialized(enum_type_)) + return false; + if (!::PROTOBUF_NAMESPACE_ID::internal::AllAreInitialized(extension_range_)) + return false; + if (!::PROTOBUF_NAMESPACE_ID::internal::AllAreInitialized(extension_)) + return false; + if (!::PROTOBUF_NAMESPACE_ID::internal::AllAreInitialized(oneof_decl_)) + return false; + if (_internal_has_options()) { + if (!options_->IsInitialized()) return false; + } + return true; +} + +void DescriptorProto::InternalSwap(DescriptorProto* other) { + using std::swap; + auto* lhs_arena = GetArenaForAllocation(); + auto* rhs_arena = other->GetArenaForAllocation(); + _internal_metadata_.InternalSwap(&other->_internal_metadata_); + swap(_has_bits_[0], other->_has_bits_[0]); + field_.InternalSwap(&other->field_); + nested_type_.InternalSwap(&other->nested_type_); + enum_type_.InternalSwap(&other->enum_type_); + extension_range_.InternalSwap(&other->extension_range_); + extension_.InternalSwap(&other->extension_); + oneof_decl_.InternalSwap(&other->oneof_decl_); + reserved_range_.InternalSwap(&other->reserved_range_); + reserved_name_.InternalSwap(&other->reserved_name_); + ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::InternalSwap( + &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), + &name_, lhs_arena, + &other->name_, rhs_arena + ); + swap(options_, other->options_); +} + +::PROTOBUF_NAMESPACE_ID::Metadata DescriptorProto::GetMetadata() const { + return ::PROTOBUF_NAMESPACE_ID::internal::AssignDescriptors( + &descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_getter, &descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_once, + file_level_metadata_google_2fprotobuf_2fdescriptor_2eproto[4]); +} + +// =================================================================== + +class ExtensionRangeOptions::_Internal { + public: +}; + +ExtensionRangeOptions::ExtensionRangeOptions(::PROTOBUF_NAMESPACE_ID::Arena* arena, + bool is_message_owned) + : ::PROTOBUF_NAMESPACE_ID::Message(arena, is_message_owned), + _extensions_(arena), + uninterpreted_option_(arena) { + SharedCtor(); + if (!is_message_owned) { + RegisterArenaDtor(arena); + } + // @@protoc_insertion_point(arena_constructor:google.protobuf.ExtensionRangeOptions) +} +ExtensionRangeOptions::ExtensionRangeOptions(const ExtensionRangeOptions& from) + : ::PROTOBUF_NAMESPACE_ID::Message(), + uninterpreted_option_(from.uninterpreted_option_) { + _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_); + _extensions_.MergeFrom(internal_default_instance(), from._extensions_); + // @@protoc_insertion_point(copy_constructor:google.protobuf.ExtensionRangeOptions) +} + +inline void ExtensionRangeOptions::SharedCtor() { +} + +ExtensionRangeOptions::~ExtensionRangeOptions() { + // @@protoc_insertion_point(destructor:google.protobuf.ExtensionRangeOptions) + if (GetArenaForAllocation() != nullptr) return; + SharedDtor(); + _internal_metadata_.Delete<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(); +} + +inline void ExtensionRangeOptions::SharedDtor() { + GOOGLE_DCHECK(GetArenaForAllocation() == nullptr); +} + +void ExtensionRangeOptions::ArenaDtor(void* object) { + ExtensionRangeOptions* _this = reinterpret_cast< ExtensionRangeOptions* >(object); + (void)_this; +} +void ExtensionRangeOptions::RegisterArenaDtor(::PROTOBUF_NAMESPACE_ID::Arena*) { +} +void ExtensionRangeOptions::SetCachedSize(int size) const { + _cached_size_.Set(size); +} + +void ExtensionRangeOptions::Clear() { +// @@protoc_insertion_point(message_clear_start:google.protobuf.ExtensionRangeOptions) + arc_ui32 cached_has_bits = 0; + // Prevent compiler warnings about cached_has_bits being unused + (void) cached_has_bits; + + _extensions_.Clear(); + uninterpreted_option_.Clear(); + _internal_metadata_.Clear<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(); +} + +const char* ExtensionRangeOptions::_InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) { +#define CHK_(x) if (PROTOBUF_PREDICT_FALSE(!(x))) goto failure + while (!ctx->Done(&ptr)) { + arc_ui32 tag; + ptr = ::PROTOBUF_NAMESPACE_ID::internal::ReadTag(ptr, &tag); + switch (tag >> 3) { + // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999; + case 999: + if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 58)) { + ptr -= 2; + do { + ptr += 2; + ptr = ctx->ParseMessage(_internal_add_uninterpreted_option(), ptr); + CHK_(ptr); + if (!ctx->DataAvailable(ptr)) break; + } while (::PROTOBUF_NAMESPACE_ID::internal::ExpectTag<7994>(ptr)); + } else + goto handle_unusual; + continue; + default: + goto handle_unusual; + } // switch + handle_unusual: + if ((tag == 0) || ((tag & 7) == 4)) { + CHK_(ptr); + ctx->SetLastTag(tag); + goto message_done; + } + if ((8000u <= tag)) { + ptr = _extensions_.ParseField(tag, ptr, internal_default_instance(), &_internal_metadata_, ctx); + CHK_(ptr != nullptr); + continue; + } + ptr = UnknownFieldParse( + tag, + _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(), + ptr, ctx); + CHK_(ptr != nullptr); + } // while +message_done: + return ptr; +failure: + ptr = nullptr; + goto message_done; +#undef CHK_ +} + +uint8_t* ExtensionRangeOptions::_InternalSerialize( + uint8_t* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const { + // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.ExtensionRangeOptions) + arc_ui32 cached_has_bits = 0; + (void) cached_has_bits; + + // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999; + for (unsigned int i = 0, + n = static_cast<unsigned int>(this->_internal_uninterpreted_option_size()); i < n; i++) { + target = stream->EnsureSpace(target); + target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite:: + InternalWriteMessage(999, this->_internal_uninterpreted_option(i), target, stream); + } + + // Extension range [1000, 536870912) + target = _extensions_._InternalSerialize( + internal_default_instance(), 1000, 536870912, target, stream); + + if (PROTOBUF_PREDICT_FALSE(_internal_metadata_.have_unknown_fields())) { + target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::InternalSerializeUnknownFieldsToArray( + _internal_metadata_.unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(::PROTOBUF_NAMESPACE_ID::UnknownFieldSet::default_instance), target, stream); + } + // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.ExtensionRangeOptions) + return target; +} + +size_t ExtensionRangeOptions::ByteSizeLong() const { +// @@protoc_insertion_point(message_byte_size_start:google.protobuf.ExtensionRangeOptions) + size_t total_size = 0; + + total_size += _extensions_.ByteSize(); + + arc_ui32 cached_has_bits = 0; + // Prevent compiler warnings about cached_has_bits being unused + (void) cached_has_bits; + + // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999; + total_size += 2UL * this->_internal_uninterpreted_option_size(); + for (const auto& msg : this->uninterpreted_option_) { + total_size += + ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::MessageSize(msg); + } + + return MaybeComputeUnknownFieldsSize(total_size, &_cached_size_); +} + +const ::PROTOBUF_NAMESPACE_ID::Message::ClassData ExtensionRangeOptions::_class_data_ = { + ::PROTOBUF_NAMESPACE_ID::Message::CopyWithSizeCheck, + ExtensionRangeOptions::MergeImpl +}; +const ::PROTOBUF_NAMESPACE_ID::Message::ClassData*ExtensionRangeOptions::GetClassData() const { return &_class_data_; } + +void ExtensionRangeOptions::MergeImpl(::PROTOBUF_NAMESPACE_ID::Message* to, + const ::PROTOBUF_NAMESPACE_ID::Message& from) { + static_cast<ExtensionRangeOptions *>(to)->MergeFrom( + static_cast<const ExtensionRangeOptions &>(from)); +} + + +void ExtensionRangeOptions::MergeFrom(const ExtensionRangeOptions& from) { +// @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.ExtensionRangeOptions) + GOOGLE_DCHECK_NE(&from, this); + arc_ui32 cached_has_bits = 0; + (void) cached_has_bits; + + uninterpreted_option_.MergeFrom(from.uninterpreted_option_); + _extensions_.MergeFrom(internal_default_instance(), from._extensions_); + _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_); +} + +void ExtensionRangeOptions::CopyFrom(const ExtensionRangeOptions& from) { +// @@protoc_insertion_point(class_specific_copy_from_start:google.protobuf.ExtensionRangeOptions) + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool ExtensionRangeOptions::IsInitialized() const { + if (!_extensions_.IsInitialized()) { + return false; + } + + if (!::PROTOBUF_NAMESPACE_ID::internal::AllAreInitialized(uninterpreted_option_)) + return false; + return true; +} + +void ExtensionRangeOptions::InternalSwap(ExtensionRangeOptions* other) { + using std::swap; + _extensions_.InternalSwap(&other->_extensions_); + _internal_metadata_.InternalSwap(&other->_internal_metadata_); + uninterpreted_option_.InternalSwap(&other->uninterpreted_option_); +} + +::PROTOBUF_NAMESPACE_ID::Metadata ExtensionRangeOptions::GetMetadata() const { + return ::PROTOBUF_NAMESPACE_ID::internal::AssignDescriptors( + &descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_getter, &descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_once, + file_level_metadata_google_2fprotobuf_2fdescriptor_2eproto[5]); +} + +// =================================================================== + +class FieldDescriptorProto::_Internal { + public: + using HasBits = decltype(std::declval<FieldDescriptorProto>()._has_bits_); + static void set_has_name(HasBits* has_bits) { + (*has_bits)[0] |= 1u; + } + static void set_has_number(HasBits* has_bits) { + (*has_bits)[0] |= 64u; + } + static void set_has_label(HasBits* has_bits) { + (*has_bits)[0] |= 512u; + } + static void set_has_type(HasBits* has_bits) { + (*has_bits)[0] |= 1024u; + } + static void set_has_type_name(HasBits* has_bits) { + (*has_bits)[0] |= 4u; + } + static void set_has_extendee(HasBits* has_bits) { + (*has_bits)[0] |= 2u; + } + static void set_has_default_value(HasBits* has_bits) { + (*has_bits)[0] |= 8u; + } + static void set_has_oneof_index(HasBits* has_bits) { + (*has_bits)[0] |= 128u; + } + static void set_has_json_name(HasBits* has_bits) { + (*has_bits)[0] |= 16u; + } + static const ::PROTOBUF_NAMESPACE_ID::FieldOptions& options(const FieldDescriptorProto* msg); + static void set_has_options(HasBits* has_bits) { + (*has_bits)[0] |= 32u; + } + static void set_has_proto3_optional(HasBits* has_bits) { + (*has_bits)[0] |= 256u; + } +}; + +const ::PROTOBUF_NAMESPACE_ID::FieldOptions& +FieldDescriptorProto::_Internal::options(const FieldDescriptorProto* msg) { + return *msg->options_; +} +FieldDescriptorProto::FieldDescriptorProto(::PROTOBUF_NAMESPACE_ID::Arena* arena, + bool is_message_owned) + : ::PROTOBUF_NAMESPACE_ID::Message(arena, is_message_owned) { + SharedCtor(); + if (!is_message_owned) { + RegisterArenaDtor(arena); + } + // @@protoc_insertion_point(arena_constructor:google.protobuf.FieldDescriptorProto) +} +FieldDescriptorProto::FieldDescriptorProto(const FieldDescriptorProto& from) + : ::PROTOBUF_NAMESPACE_ID::Message(), + _has_bits_(from._has_bits_) { + _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_); + name_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); + #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING + name_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation()); + #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING + if (from._internal_has_name()) { + name_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, from._internal_name(), + GetArenaForAllocation()); + } + extendee_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); + #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING + extendee_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation()); + #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING + if (from._internal_has_extendee()) { + extendee_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, from._internal_extendee(), + GetArenaForAllocation()); + } + type_name_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); + #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING + type_name_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation()); + #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING + if (from._internal_has_type_name()) { + type_name_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, from._internal_type_name(), + GetArenaForAllocation()); + } + default_value_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); + #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING + default_value_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation()); + #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING + if (from._internal_has_default_value()) { + default_value_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, from._internal_default_value(), + GetArenaForAllocation()); + } + json_name_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); + #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING + json_name_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation()); + #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING + if (from._internal_has_json_name()) { + json_name_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, from._internal_json_name(), + GetArenaForAllocation()); + } + if (from._internal_has_options()) { + options_ = new ::PROTOBUF_NAMESPACE_ID::FieldOptions(*from.options_); + } else { + options_ = nullptr; + } + ::memcpy(&number_, &from.number_, + static_cast<size_t>(reinterpret_cast<char*>(&type_) - + reinterpret_cast<char*>(&number_)) + sizeof(type_)); + // @@protoc_insertion_point(copy_constructor:google.protobuf.FieldDescriptorProto) +} + +inline void FieldDescriptorProto::SharedCtor() { +name_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); +#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING + name_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation()); +#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING +extendee_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); +#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING + extendee_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation()); +#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING +type_name_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); +#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING + type_name_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation()); +#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING +default_value_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); +#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING + default_value_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation()); +#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING +json_name_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); +#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING + json_name_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation()); +#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING +::memset(reinterpret_cast<char*>(this) + static_cast<size_t>( + reinterpret_cast<char*>(&options_) - reinterpret_cast<char*>(this)), + 0, static_cast<size_t>(reinterpret_cast<char*>(&proto3_optional_) - + reinterpret_cast<char*>(&options_)) + sizeof(proto3_optional_)); +label_ = 1; +type_ = 1; +} + +FieldDescriptorProto::~FieldDescriptorProto() { + // @@protoc_insertion_point(destructor:google.protobuf.FieldDescriptorProto) + if (GetArenaForAllocation() != nullptr) return; + SharedDtor(); + _internal_metadata_.Delete<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(); +} + +inline void FieldDescriptorProto::SharedDtor() { + GOOGLE_DCHECK(GetArenaForAllocation() == nullptr); + name_.DestroyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); + extendee_.DestroyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); + type_name_.DestroyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); + default_value_.DestroyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); + json_name_.DestroyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); + if (this != internal_default_instance()) delete options_; +} + +void FieldDescriptorProto::ArenaDtor(void* object) { + FieldDescriptorProto* _this = reinterpret_cast< FieldDescriptorProto* >(object); + (void)_this; +} +void FieldDescriptorProto::RegisterArenaDtor(::PROTOBUF_NAMESPACE_ID::Arena*) { +} +void FieldDescriptorProto::SetCachedSize(int size) const { + _cached_size_.Set(size); +} + +void FieldDescriptorProto::Clear() { +// @@protoc_insertion_point(message_clear_start:google.protobuf.FieldDescriptorProto) + arc_ui32 cached_has_bits = 0; + // Prevent compiler warnings about cached_has_bits being unused + (void) cached_has_bits; + + cached_has_bits = _has_bits_[0]; + if (cached_has_bits & 0x0000003fu) { + if (cached_has_bits & 0x00000001u) { + name_.ClearNonDefaultToEmpty(); + } + if (cached_has_bits & 0x00000002u) { + extendee_.ClearNonDefaultToEmpty(); + } + if (cached_has_bits & 0x00000004u) { + type_name_.ClearNonDefaultToEmpty(); + } + if (cached_has_bits & 0x00000008u) { + default_value_.ClearNonDefaultToEmpty(); + } + if (cached_has_bits & 0x00000010u) { + json_name_.ClearNonDefaultToEmpty(); + } + if (cached_has_bits & 0x00000020u) { + GOOGLE_DCHECK(options_ != nullptr); + options_->Clear(); + } + } + if (cached_has_bits & 0x000000c0u) { + ::memset(&number_, 0, static_cast<size_t>( + reinterpret_cast<char*>(&oneof_index_) - + reinterpret_cast<char*>(&number_)) + sizeof(oneof_index_)); + } + if (cached_has_bits & 0x00000700u) { + proto3_optional_ = false; + label_ = 1; + type_ = 1; + } + _has_bits_.Clear(); + _internal_metadata_.Clear<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(); +} + +const char* FieldDescriptorProto::_InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) { +#define CHK_(x) if (PROTOBUF_PREDICT_FALSE(!(x))) goto failure + _Internal::HasBits has_bits{}; + while (!ctx->Done(&ptr)) { + arc_ui32 tag; + ptr = ::PROTOBUF_NAMESPACE_ID::internal::ReadTag(ptr, &tag); + switch (tag >> 3) { + // optional string name = 1; + case 1: + if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 10)) { + auto str = _internal_mutable_name(); + ptr = ::PROTOBUF_NAMESPACE_ID::internal::InlineGreedyStringParser(str, ptr, ctx); + #ifndef NDEBUG + ::PROTOBUF_NAMESPACE_ID::internal::VerifyUTF8(str, "google.protobuf.FieldDescriptorProto.name"); + #endif // !NDEBUG + CHK_(ptr); + } else + goto handle_unusual; + continue; + // optional string extendee = 2; + case 2: + if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 18)) { + auto str = _internal_mutable_extendee(); + ptr = ::PROTOBUF_NAMESPACE_ID::internal::InlineGreedyStringParser(str, ptr, ctx); + #ifndef NDEBUG + ::PROTOBUF_NAMESPACE_ID::internal::VerifyUTF8(str, "google.protobuf.FieldDescriptorProto.extendee"); + #endif // !NDEBUG + CHK_(ptr); + } else + goto handle_unusual; + continue; + // optional int32 number = 3; + case 3: + if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 24)) { + _Internal::set_has_number(&has_bits); + number_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint32(&ptr); + CHK_(ptr); + } else + goto handle_unusual; + continue; + // optional .google.protobuf.FieldDescriptorProto.Label label = 4; + case 4: + if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 32)) { + arc_ui64 val = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint64(&ptr); + CHK_(ptr); + if (PROTOBUF_PREDICT_TRUE(::PROTOBUF_NAMESPACE_ID::FieldDescriptorProto_Label_IsValid(val))) { + _internal_set_label(static_cast<::PROTOBUF_NAMESPACE_ID::FieldDescriptorProto_Label>(val)); + } else { + ::PROTOBUF_NAMESPACE_ID::internal::WriteVarint(4, val, mutable_unknown_fields()); + } + } else + goto handle_unusual; + continue; + // optional .google.protobuf.FieldDescriptorProto.Type type = 5; + case 5: + if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 40)) { + arc_ui64 val = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint64(&ptr); + CHK_(ptr); + if (PROTOBUF_PREDICT_TRUE(::PROTOBUF_NAMESPACE_ID::FieldDescriptorProto_Type_IsValid(val))) { + _internal_set_type(static_cast<::PROTOBUF_NAMESPACE_ID::FieldDescriptorProto_Type>(val)); + } else { + ::PROTOBUF_NAMESPACE_ID::internal::WriteVarint(5, val, mutable_unknown_fields()); + } + } else + goto handle_unusual; + continue; + // optional string type_name = 6; + case 6: + if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 50)) { + auto str = _internal_mutable_type_name(); + ptr = ::PROTOBUF_NAMESPACE_ID::internal::InlineGreedyStringParser(str, ptr, ctx); + #ifndef NDEBUG + ::PROTOBUF_NAMESPACE_ID::internal::VerifyUTF8(str, "google.protobuf.FieldDescriptorProto.type_name"); + #endif // !NDEBUG + CHK_(ptr); + } else + goto handle_unusual; + continue; + // optional string default_value = 7; + case 7: + if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 58)) { + auto str = _internal_mutable_default_value(); + ptr = ::PROTOBUF_NAMESPACE_ID::internal::InlineGreedyStringParser(str, ptr, ctx); + #ifndef NDEBUG + ::PROTOBUF_NAMESPACE_ID::internal::VerifyUTF8(str, "google.protobuf.FieldDescriptorProto.default_value"); + #endif // !NDEBUG + CHK_(ptr); + } else + goto handle_unusual; + continue; + // optional .google.protobuf.FieldOptions options = 8; + case 8: + if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 66)) { + ptr = ctx->ParseMessage(_internal_mutable_options(), ptr); + CHK_(ptr); + } else + goto handle_unusual; + continue; + // optional int32 oneof_index = 9; + case 9: + if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 72)) { + _Internal::set_has_oneof_index(&has_bits); + oneof_index_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint32(&ptr); + CHK_(ptr); + } else + goto handle_unusual; + continue; + // optional string json_name = 10; + case 10: + if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 82)) { + auto str = _internal_mutable_json_name(); + ptr = ::PROTOBUF_NAMESPACE_ID::internal::InlineGreedyStringParser(str, ptr, ctx); + #ifndef NDEBUG + ::PROTOBUF_NAMESPACE_ID::internal::VerifyUTF8(str, "google.protobuf.FieldDescriptorProto.json_name"); + #endif // !NDEBUG + CHK_(ptr); + } else + goto handle_unusual; + continue; + // optional bool proto3_optional = 17; + case 17: + if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 136)) { + _Internal::set_has_proto3_optional(&has_bits); + proto3_optional_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint64(&ptr); + CHK_(ptr); + } else + goto handle_unusual; + continue; + default: + goto handle_unusual; + } // switch + handle_unusual: + if ((tag == 0) || ((tag & 7) == 4)) { + CHK_(ptr); + ctx->SetLastTag(tag); + goto message_done; + } + ptr = UnknownFieldParse( + tag, + _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(), + ptr, ctx); + CHK_(ptr != nullptr); + } // while +message_done: + _has_bits_.Or(has_bits); + return ptr; +failure: + ptr = nullptr; + goto message_done; +#undef CHK_ +} + +uint8_t* FieldDescriptorProto::_InternalSerialize( + uint8_t* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const { + // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.FieldDescriptorProto) + arc_ui32 cached_has_bits = 0; + (void) cached_has_bits; + + cached_has_bits = _has_bits_[0]; + // optional string name = 1; + if (cached_has_bits & 0x00000001u) { + ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::VerifyUTF8StringNamedField( + this->_internal_name().data(), static_cast<int>(this->_internal_name().length()), + ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::SERIALIZE, + "google.protobuf.FieldDescriptorProto.name"); + target = stream->WriteStringMaybeAliased( + 1, this->_internal_name(), target); + } + + // optional string extendee = 2; + if (cached_has_bits & 0x00000002u) { + ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::VerifyUTF8StringNamedField( + this->_internal_extendee().data(), static_cast<int>(this->_internal_extendee().length()), + ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::SERIALIZE, + "google.protobuf.FieldDescriptorProto.extendee"); + target = stream->WriteStringMaybeAliased( + 2, this->_internal_extendee(), target); + } + + // optional int32 number = 3; + if (cached_has_bits & 0x00000040u) { + target = stream->EnsureSpace(target); + target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteInt32ToArray(3, this->_internal_number(), target); + } + + // optional .google.protobuf.FieldDescriptorProto.Label label = 4; + if (cached_has_bits & 0x00000200u) { + target = stream->EnsureSpace(target); + target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteEnumToArray( + 4, this->_internal_label(), target); + } + + // optional .google.protobuf.FieldDescriptorProto.Type type = 5; + if (cached_has_bits & 0x00000400u) { + target = stream->EnsureSpace(target); + target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteEnumToArray( + 5, this->_internal_type(), target); + } + + // optional string type_name = 6; + if (cached_has_bits & 0x00000004u) { + ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::VerifyUTF8StringNamedField( + this->_internal_type_name().data(), static_cast<int>(this->_internal_type_name().length()), + ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::SERIALIZE, + "google.protobuf.FieldDescriptorProto.type_name"); + target = stream->WriteStringMaybeAliased( + 6, this->_internal_type_name(), target); + } + + // optional string default_value = 7; + if (cached_has_bits & 0x00000008u) { + ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::VerifyUTF8StringNamedField( + this->_internal_default_value().data(), static_cast<int>(this->_internal_default_value().length()), + ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::SERIALIZE, + "google.protobuf.FieldDescriptorProto.default_value"); + target = stream->WriteStringMaybeAliased( + 7, this->_internal_default_value(), target); + } + + // optional .google.protobuf.FieldOptions options = 8; + if (cached_has_bits & 0x00000020u) { + target = stream->EnsureSpace(target); + target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite:: + InternalWriteMessage( + 8, _Internal::options(this), target, stream); + } + + // optional int32 oneof_index = 9; + if (cached_has_bits & 0x00000080u) { + target = stream->EnsureSpace(target); + target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteInt32ToArray(9, this->_internal_oneof_index(), target); + } + + // optional string json_name = 10; + if (cached_has_bits & 0x00000010u) { + ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::VerifyUTF8StringNamedField( + this->_internal_json_name().data(), static_cast<int>(this->_internal_json_name().length()), + ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::SERIALIZE, + "google.protobuf.FieldDescriptorProto.json_name"); + target = stream->WriteStringMaybeAliased( + 10, this->_internal_json_name(), target); + } + + // optional bool proto3_optional = 17; + if (cached_has_bits & 0x00000100u) { + target = stream->EnsureSpace(target); + target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteBoolToArray(17, this->_internal_proto3_optional(), target); + } + + if (PROTOBUF_PREDICT_FALSE(_internal_metadata_.have_unknown_fields())) { + target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::InternalSerializeUnknownFieldsToArray( + _internal_metadata_.unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(::PROTOBUF_NAMESPACE_ID::UnknownFieldSet::default_instance), target, stream); + } + // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.FieldDescriptorProto) + return target; +} + +size_t FieldDescriptorProto::ByteSizeLong() const { +// @@protoc_insertion_point(message_byte_size_start:google.protobuf.FieldDescriptorProto) + size_t total_size = 0; + + arc_ui32 cached_has_bits = 0; + // Prevent compiler warnings about cached_has_bits being unused + (void) cached_has_bits; + + cached_has_bits = _has_bits_[0]; + if (cached_has_bits & 0x000000ffu) { + // optional string name = 1; + if (cached_has_bits & 0x00000001u) { + total_size += 1 + + ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::StringSize( + this->_internal_name()); + } + + // optional string extendee = 2; + if (cached_has_bits & 0x00000002u) { + total_size += 1 + + ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::StringSize( + this->_internal_extendee()); + } + + // optional string type_name = 6; + if (cached_has_bits & 0x00000004u) { + total_size += 1 + + ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::StringSize( + this->_internal_type_name()); + } + + // optional string default_value = 7; + if (cached_has_bits & 0x00000008u) { + total_size += 1 + + ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::StringSize( + this->_internal_default_value()); + } + + // optional string json_name = 10; + if (cached_has_bits & 0x00000010u) { + total_size += 1 + + ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::StringSize( + this->_internal_json_name()); + } + + // optional .google.protobuf.FieldOptions options = 8; + if (cached_has_bits & 0x00000020u) { + total_size += 1 + + ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::MessageSize( + *options_); + } + + // optional int32 number = 3; + if (cached_has_bits & 0x00000040u) { + total_size += ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::Int32SizePlusOne(this->_internal_number()); + } + + // optional int32 oneof_index = 9; + if (cached_has_bits & 0x00000080u) { + total_size += ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::Int32SizePlusOne(this->_internal_oneof_index()); + } + + } + if (cached_has_bits & 0x00000700u) { + // optional bool proto3_optional = 17; + if (cached_has_bits & 0x00000100u) { + total_size += 2 + 1; + } + + // optional .google.protobuf.FieldDescriptorProto.Label label = 4; + if (cached_has_bits & 0x00000200u) { + total_size += 1 + + ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::EnumSize(this->_internal_label()); + } + + // optional .google.protobuf.FieldDescriptorProto.Type type = 5; + if (cached_has_bits & 0x00000400u) { + total_size += 1 + + ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::EnumSize(this->_internal_type()); + } + + } + return MaybeComputeUnknownFieldsSize(total_size, &_cached_size_); +} + +const ::PROTOBUF_NAMESPACE_ID::Message::ClassData FieldDescriptorProto::_class_data_ = { + ::PROTOBUF_NAMESPACE_ID::Message::CopyWithSizeCheck, + FieldDescriptorProto::MergeImpl +}; +const ::PROTOBUF_NAMESPACE_ID::Message::ClassData*FieldDescriptorProto::GetClassData() const { return &_class_data_; } + +void FieldDescriptorProto::MergeImpl(::PROTOBUF_NAMESPACE_ID::Message* to, + const ::PROTOBUF_NAMESPACE_ID::Message& from) { + static_cast<FieldDescriptorProto *>(to)->MergeFrom( + static_cast<const FieldDescriptorProto &>(from)); +} + + +void FieldDescriptorProto::MergeFrom(const FieldDescriptorProto& from) { +// @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.FieldDescriptorProto) + GOOGLE_DCHECK_NE(&from, this); + arc_ui32 cached_has_bits = 0; + (void) cached_has_bits; + + cached_has_bits = from._has_bits_[0]; + if (cached_has_bits & 0x000000ffu) { + if (cached_has_bits & 0x00000001u) { + _internal_set_name(from._internal_name()); + } + if (cached_has_bits & 0x00000002u) { + _internal_set_extendee(from._internal_extendee()); + } + if (cached_has_bits & 0x00000004u) { + _internal_set_type_name(from._internal_type_name()); + } + if (cached_has_bits & 0x00000008u) { + _internal_set_default_value(from._internal_default_value()); + } + if (cached_has_bits & 0x00000010u) { + _internal_set_json_name(from._internal_json_name()); + } + if (cached_has_bits & 0x00000020u) { + _internal_mutable_options()->::PROTOBUF_NAMESPACE_ID::FieldOptions::MergeFrom(from._internal_options()); + } + if (cached_has_bits & 0x00000040u) { + number_ = from.number_; + } + if (cached_has_bits & 0x00000080u) { + oneof_index_ = from.oneof_index_; + } + _has_bits_[0] |= cached_has_bits; + } + if (cached_has_bits & 0x00000700u) { + if (cached_has_bits & 0x00000100u) { + proto3_optional_ = from.proto3_optional_; + } + if (cached_has_bits & 0x00000200u) { + label_ = from.label_; + } + if (cached_has_bits & 0x00000400u) { + type_ = from.type_; + } + _has_bits_[0] |= cached_has_bits; + } + _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_); +} + +void FieldDescriptorProto::CopyFrom(const FieldDescriptorProto& from) { +// @@protoc_insertion_point(class_specific_copy_from_start:google.protobuf.FieldDescriptorProto) + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool FieldDescriptorProto::IsInitialized() const { + if (_internal_has_options()) { + if (!options_->IsInitialized()) return false; + } + return true; +} + +void FieldDescriptorProto::InternalSwap(FieldDescriptorProto* other) { + using std::swap; + auto* lhs_arena = GetArenaForAllocation(); + auto* rhs_arena = other->GetArenaForAllocation(); + _internal_metadata_.InternalSwap(&other->_internal_metadata_); + swap(_has_bits_[0], other->_has_bits_[0]); + ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::InternalSwap( + &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), + &name_, lhs_arena, + &other->name_, rhs_arena + ); + ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::InternalSwap( + &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), + &extendee_, lhs_arena, + &other->extendee_, rhs_arena + ); + ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::InternalSwap( + &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), + &type_name_, lhs_arena, + &other->type_name_, rhs_arena + ); + ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::InternalSwap( + &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), + &default_value_, lhs_arena, + &other->default_value_, rhs_arena + ); + ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::InternalSwap( + &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), + &json_name_, lhs_arena, + &other->json_name_, rhs_arena + ); + ::PROTOBUF_NAMESPACE_ID::internal::memswap< + PROTOBUF_FIELD_OFFSET(FieldDescriptorProto, proto3_optional_) + + sizeof(FieldDescriptorProto::proto3_optional_) + - PROTOBUF_FIELD_OFFSET(FieldDescriptorProto, options_)>( + reinterpret_cast<char*>(&options_), + reinterpret_cast<char*>(&other->options_)); + swap(label_, other->label_); + swap(type_, other->type_); +} + +::PROTOBUF_NAMESPACE_ID::Metadata FieldDescriptorProto::GetMetadata() const { + return ::PROTOBUF_NAMESPACE_ID::internal::AssignDescriptors( + &descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_getter, &descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_once, + file_level_metadata_google_2fprotobuf_2fdescriptor_2eproto[6]); +} + +// =================================================================== + +class OneofDescriptorProto::_Internal { + public: + using HasBits = decltype(std::declval<OneofDescriptorProto>()._has_bits_); + static void set_has_name(HasBits* has_bits) { + (*has_bits)[0] |= 1u; + } + static const ::PROTOBUF_NAMESPACE_ID::OneofOptions& options(const OneofDescriptorProto* msg); + static void set_has_options(HasBits* has_bits) { + (*has_bits)[0] |= 2u; + } +}; + +const ::PROTOBUF_NAMESPACE_ID::OneofOptions& +OneofDescriptorProto::_Internal::options(const OneofDescriptorProto* msg) { + return *msg->options_; +} +OneofDescriptorProto::OneofDescriptorProto(::PROTOBUF_NAMESPACE_ID::Arena* arena, + bool is_message_owned) + : ::PROTOBUF_NAMESPACE_ID::Message(arena, is_message_owned) { + SharedCtor(); + if (!is_message_owned) { + RegisterArenaDtor(arena); + } + // @@protoc_insertion_point(arena_constructor:google.protobuf.OneofDescriptorProto) +} +OneofDescriptorProto::OneofDescriptorProto(const OneofDescriptorProto& from) + : ::PROTOBUF_NAMESPACE_ID::Message(), + _has_bits_(from._has_bits_) { + _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_); + name_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); + #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING + name_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation()); + #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING + if (from._internal_has_name()) { + name_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, from._internal_name(), + GetArenaForAllocation()); + } + if (from._internal_has_options()) { + options_ = new ::PROTOBUF_NAMESPACE_ID::OneofOptions(*from.options_); + } else { + options_ = nullptr; + } + // @@protoc_insertion_point(copy_constructor:google.protobuf.OneofDescriptorProto) +} + +inline void OneofDescriptorProto::SharedCtor() { +name_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); +#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING + name_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation()); +#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING +options_ = nullptr; +} + +OneofDescriptorProto::~OneofDescriptorProto() { + // @@protoc_insertion_point(destructor:google.protobuf.OneofDescriptorProto) + if (GetArenaForAllocation() != nullptr) return; + SharedDtor(); + _internal_metadata_.Delete<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(); +} + +inline void OneofDescriptorProto::SharedDtor() { + GOOGLE_DCHECK(GetArenaForAllocation() == nullptr); + name_.DestroyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); + if (this != internal_default_instance()) delete options_; +} + +void OneofDescriptorProto::ArenaDtor(void* object) { + OneofDescriptorProto* _this = reinterpret_cast< OneofDescriptorProto* >(object); + (void)_this; +} +void OneofDescriptorProto::RegisterArenaDtor(::PROTOBUF_NAMESPACE_ID::Arena*) { +} +void OneofDescriptorProto::SetCachedSize(int size) const { + _cached_size_.Set(size); +} + +void OneofDescriptorProto::Clear() { +// @@protoc_insertion_point(message_clear_start:google.protobuf.OneofDescriptorProto) + arc_ui32 cached_has_bits = 0; + // Prevent compiler warnings about cached_has_bits being unused + (void) cached_has_bits; + + cached_has_bits = _has_bits_[0]; + if (cached_has_bits & 0x00000003u) { + if (cached_has_bits & 0x00000001u) { + name_.ClearNonDefaultToEmpty(); + } + if (cached_has_bits & 0x00000002u) { + GOOGLE_DCHECK(options_ != nullptr); + options_->Clear(); + } + } + _has_bits_.Clear(); + _internal_metadata_.Clear<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(); +} + +const char* OneofDescriptorProto::_InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) { +#define CHK_(x) if (PROTOBUF_PREDICT_FALSE(!(x))) goto failure + _Internal::HasBits has_bits{}; + while (!ctx->Done(&ptr)) { + arc_ui32 tag; + ptr = ::PROTOBUF_NAMESPACE_ID::internal::ReadTag(ptr, &tag); + switch (tag >> 3) { + // optional string name = 1; + case 1: + if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 10)) { + auto str = _internal_mutable_name(); + ptr = ::PROTOBUF_NAMESPACE_ID::internal::InlineGreedyStringParser(str, ptr, ctx); + #ifndef NDEBUG + ::PROTOBUF_NAMESPACE_ID::internal::VerifyUTF8(str, "google.protobuf.OneofDescriptorProto.name"); + #endif // !NDEBUG + CHK_(ptr); + } else + goto handle_unusual; + continue; + // optional .google.protobuf.OneofOptions options = 2; + case 2: + if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 18)) { + ptr = ctx->ParseMessage(_internal_mutable_options(), ptr); + CHK_(ptr); + } else + goto handle_unusual; + continue; + default: + goto handle_unusual; + } // switch + handle_unusual: + if ((tag == 0) || ((tag & 7) == 4)) { + CHK_(ptr); + ctx->SetLastTag(tag); + goto message_done; + } + ptr = UnknownFieldParse( + tag, + _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(), + ptr, ctx); + CHK_(ptr != nullptr); + } // while +message_done: + _has_bits_.Or(has_bits); + return ptr; +failure: + ptr = nullptr; + goto message_done; +#undef CHK_ +} + +uint8_t* OneofDescriptorProto::_InternalSerialize( + uint8_t* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const { + // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.OneofDescriptorProto) + arc_ui32 cached_has_bits = 0; + (void) cached_has_bits; + + cached_has_bits = _has_bits_[0]; + // optional string name = 1; + if (cached_has_bits & 0x00000001u) { + ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::VerifyUTF8StringNamedField( + this->_internal_name().data(), static_cast<int>(this->_internal_name().length()), + ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::SERIALIZE, + "google.protobuf.OneofDescriptorProto.name"); + target = stream->WriteStringMaybeAliased( + 1, this->_internal_name(), target); + } + + // optional .google.protobuf.OneofOptions options = 2; + if (cached_has_bits & 0x00000002u) { + target = stream->EnsureSpace(target); + target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite:: + InternalWriteMessage( + 2, _Internal::options(this), target, stream); + } + + if (PROTOBUF_PREDICT_FALSE(_internal_metadata_.have_unknown_fields())) { + target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::InternalSerializeUnknownFieldsToArray( + _internal_metadata_.unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(::PROTOBUF_NAMESPACE_ID::UnknownFieldSet::default_instance), target, stream); + } + // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.OneofDescriptorProto) + return target; +} + +size_t OneofDescriptorProto::ByteSizeLong() const { +// @@protoc_insertion_point(message_byte_size_start:google.protobuf.OneofDescriptorProto) + size_t total_size = 0; + + arc_ui32 cached_has_bits = 0; + // Prevent compiler warnings about cached_has_bits being unused + (void) cached_has_bits; + + cached_has_bits = _has_bits_[0]; + if (cached_has_bits & 0x00000003u) { + // optional string name = 1; + if (cached_has_bits & 0x00000001u) { + total_size += 1 + + ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::StringSize( + this->_internal_name()); + } + + // optional .google.protobuf.OneofOptions options = 2; + if (cached_has_bits & 0x00000002u) { + total_size += 1 + + ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::MessageSize( + *options_); + } + + } + return MaybeComputeUnknownFieldsSize(total_size, &_cached_size_); +} + +const ::PROTOBUF_NAMESPACE_ID::Message::ClassData OneofDescriptorProto::_class_data_ = { + ::PROTOBUF_NAMESPACE_ID::Message::CopyWithSizeCheck, + OneofDescriptorProto::MergeImpl +}; +const ::PROTOBUF_NAMESPACE_ID::Message::ClassData*OneofDescriptorProto::GetClassData() const { return &_class_data_; } + +void OneofDescriptorProto::MergeImpl(::PROTOBUF_NAMESPACE_ID::Message* to, + const ::PROTOBUF_NAMESPACE_ID::Message& from) { + static_cast<OneofDescriptorProto *>(to)->MergeFrom( + static_cast<const OneofDescriptorProto &>(from)); +} + + +void OneofDescriptorProto::MergeFrom(const OneofDescriptorProto& from) { +// @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.OneofDescriptorProto) + GOOGLE_DCHECK_NE(&from, this); + arc_ui32 cached_has_bits = 0; + (void) cached_has_bits; + + cached_has_bits = from._has_bits_[0]; + if (cached_has_bits & 0x00000003u) { + if (cached_has_bits & 0x00000001u) { + _internal_set_name(from._internal_name()); + } + if (cached_has_bits & 0x00000002u) { + _internal_mutable_options()->::PROTOBUF_NAMESPACE_ID::OneofOptions::MergeFrom(from._internal_options()); + } + } + _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_); +} + +void OneofDescriptorProto::CopyFrom(const OneofDescriptorProto& from) { +// @@protoc_insertion_point(class_specific_copy_from_start:google.protobuf.OneofDescriptorProto) + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool OneofDescriptorProto::IsInitialized() const { + if (_internal_has_options()) { + if (!options_->IsInitialized()) return false; + } + return true; +} + +void OneofDescriptorProto::InternalSwap(OneofDescriptorProto* other) { + using std::swap; + auto* lhs_arena = GetArenaForAllocation(); + auto* rhs_arena = other->GetArenaForAllocation(); + _internal_metadata_.InternalSwap(&other->_internal_metadata_); + swap(_has_bits_[0], other->_has_bits_[0]); + ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::InternalSwap( + &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), + &name_, lhs_arena, + &other->name_, rhs_arena + ); + swap(options_, other->options_); +} + +::PROTOBUF_NAMESPACE_ID::Metadata OneofDescriptorProto::GetMetadata() const { + return ::PROTOBUF_NAMESPACE_ID::internal::AssignDescriptors( + &descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_getter, &descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_once, + file_level_metadata_google_2fprotobuf_2fdescriptor_2eproto[7]); +} + +// =================================================================== + +class EnumDescriptorProto_EnumReservedRange::_Internal { + public: + using HasBits = decltype(std::declval<EnumDescriptorProto_EnumReservedRange>()._has_bits_); + static void set_has_start(HasBits* has_bits) { + (*has_bits)[0] |= 1u; + } + static void set_has_end(HasBits* has_bits) { + (*has_bits)[0] |= 2u; + } +}; + +EnumDescriptorProto_EnumReservedRange::EnumDescriptorProto_EnumReservedRange(::PROTOBUF_NAMESPACE_ID::Arena* arena, + bool is_message_owned) + : ::PROTOBUF_NAMESPACE_ID::Message(arena, is_message_owned) { + SharedCtor(); + if (!is_message_owned) { + RegisterArenaDtor(arena); + } + // @@protoc_insertion_point(arena_constructor:google.protobuf.EnumDescriptorProto.EnumReservedRange) +} +EnumDescriptorProto_EnumReservedRange::EnumDescriptorProto_EnumReservedRange(const EnumDescriptorProto_EnumReservedRange& from) + : ::PROTOBUF_NAMESPACE_ID::Message(), + _has_bits_(from._has_bits_) { + _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_); + ::memcpy(&start_, &from.start_, + static_cast<size_t>(reinterpret_cast<char*>(&end_) - + reinterpret_cast<char*>(&start_)) + sizeof(end_)); + // @@protoc_insertion_point(copy_constructor:google.protobuf.EnumDescriptorProto.EnumReservedRange) +} + +inline void EnumDescriptorProto_EnumReservedRange::SharedCtor() { +::memset(reinterpret_cast<char*>(this) + static_cast<size_t>( + reinterpret_cast<char*>(&start_) - reinterpret_cast<char*>(this)), + 0, static_cast<size_t>(reinterpret_cast<char*>(&end_) - + reinterpret_cast<char*>(&start_)) + sizeof(end_)); +} + +EnumDescriptorProto_EnumReservedRange::~EnumDescriptorProto_EnumReservedRange() { + // @@protoc_insertion_point(destructor:google.protobuf.EnumDescriptorProto.EnumReservedRange) + if (GetArenaForAllocation() != nullptr) return; + SharedDtor(); + _internal_metadata_.Delete<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(); +} + +inline void EnumDescriptorProto_EnumReservedRange::SharedDtor() { + GOOGLE_DCHECK(GetArenaForAllocation() == nullptr); +} + +void EnumDescriptorProto_EnumReservedRange::ArenaDtor(void* object) { + EnumDescriptorProto_EnumReservedRange* _this = reinterpret_cast< EnumDescriptorProto_EnumReservedRange* >(object); + (void)_this; +} +void EnumDescriptorProto_EnumReservedRange::RegisterArenaDtor(::PROTOBUF_NAMESPACE_ID::Arena*) { +} +void EnumDescriptorProto_EnumReservedRange::SetCachedSize(int size) const { + _cached_size_.Set(size); +} + +void EnumDescriptorProto_EnumReservedRange::Clear() { +// @@protoc_insertion_point(message_clear_start:google.protobuf.EnumDescriptorProto.EnumReservedRange) + arc_ui32 cached_has_bits = 0; + // Prevent compiler warnings about cached_has_bits being unused + (void) cached_has_bits; + + cached_has_bits = _has_bits_[0]; + if (cached_has_bits & 0x00000003u) { + ::memset(&start_, 0, static_cast<size_t>( + reinterpret_cast<char*>(&end_) - + reinterpret_cast<char*>(&start_)) + sizeof(end_)); + } + _has_bits_.Clear(); + _internal_metadata_.Clear<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(); +} + +const char* EnumDescriptorProto_EnumReservedRange::_InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) { +#define CHK_(x) if (PROTOBUF_PREDICT_FALSE(!(x))) goto failure + _Internal::HasBits has_bits{}; + while (!ctx->Done(&ptr)) { + arc_ui32 tag; + ptr = ::PROTOBUF_NAMESPACE_ID::internal::ReadTag(ptr, &tag); + switch (tag >> 3) { + // optional int32 start = 1; + case 1: + if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 8)) { + _Internal::set_has_start(&has_bits); + start_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint32(&ptr); + CHK_(ptr); + } else + goto handle_unusual; + continue; + // optional int32 end = 2; + case 2: + if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 16)) { + _Internal::set_has_end(&has_bits); + end_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint32(&ptr); + CHK_(ptr); + } else + goto handle_unusual; + continue; + default: + goto handle_unusual; + } // switch + handle_unusual: + if ((tag == 0) || ((tag & 7) == 4)) { + CHK_(ptr); + ctx->SetLastTag(tag); + goto message_done; + } + ptr = UnknownFieldParse( + tag, + _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(), + ptr, ctx); + CHK_(ptr != nullptr); + } // while +message_done: + _has_bits_.Or(has_bits); + return ptr; +failure: + ptr = nullptr; + goto message_done; +#undef CHK_ +} + +uint8_t* EnumDescriptorProto_EnumReservedRange::_InternalSerialize( + uint8_t* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const { + // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.EnumDescriptorProto.EnumReservedRange) + arc_ui32 cached_has_bits = 0; + (void) cached_has_bits; + + cached_has_bits = _has_bits_[0]; + // optional int32 start = 1; + if (cached_has_bits & 0x00000001u) { + target = stream->EnsureSpace(target); + target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteInt32ToArray(1, this->_internal_start(), target); + } + + // optional int32 end = 2; + if (cached_has_bits & 0x00000002u) { + target = stream->EnsureSpace(target); + target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteInt32ToArray(2, this->_internal_end(), target); + } + + if (PROTOBUF_PREDICT_FALSE(_internal_metadata_.have_unknown_fields())) { + target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::InternalSerializeUnknownFieldsToArray( + _internal_metadata_.unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(::PROTOBUF_NAMESPACE_ID::UnknownFieldSet::default_instance), target, stream); + } + // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.EnumDescriptorProto.EnumReservedRange) + return target; +} + +size_t EnumDescriptorProto_EnumReservedRange::ByteSizeLong() const { +// @@protoc_insertion_point(message_byte_size_start:google.protobuf.EnumDescriptorProto.EnumReservedRange) + size_t total_size = 0; + + arc_ui32 cached_has_bits = 0; + // Prevent compiler warnings about cached_has_bits being unused + (void) cached_has_bits; + + cached_has_bits = _has_bits_[0]; + if (cached_has_bits & 0x00000003u) { + // optional int32 start = 1; + if (cached_has_bits & 0x00000001u) { + total_size += ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::Int32SizePlusOne(this->_internal_start()); + } + + // optional int32 end = 2; + if (cached_has_bits & 0x00000002u) { + total_size += ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::Int32SizePlusOne(this->_internal_end()); + } + + } + return MaybeComputeUnknownFieldsSize(total_size, &_cached_size_); +} + +const ::PROTOBUF_NAMESPACE_ID::Message::ClassData EnumDescriptorProto_EnumReservedRange::_class_data_ = { + ::PROTOBUF_NAMESPACE_ID::Message::CopyWithSizeCheck, + EnumDescriptorProto_EnumReservedRange::MergeImpl +}; +const ::PROTOBUF_NAMESPACE_ID::Message::ClassData*EnumDescriptorProto_EnumReservedRange::GetClassData() const { return &_class_data_; } + +void EnumDescriptorProto_EnumReservedRange::MergeImpl(::PROTOBUF_NAMESPACE_ID::Message* to, + const ::PROTOBUF_NAMESPACE_ID::Message& from) { + static_cast<EnumDescriptorProto_EnumReservedRange *>(to)->MergeFrom( + static_cast<const EnumDescriptorProto_EnumReservedRange &>(from)); +} + + +void EnumDescriptorProto_EnumReservedRange::MergeFrom(const EnumDescriptorProto_EnumReservedRange& from) { +// @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.EnumDescriptorProto.EnumReservedRange) + GOOGLE_DCHECK_NE(&from, this); + arc_ui32 cached_has_bits = 0; + (void) cached_has_bits; + + cached_has_bits = from._has_bits_[0]; + if (cached_has_bits & 0x00000003u) { + if (cached_has_bits & 0x00000001u) { + start_ = from.start_; + } + if (cached_has_bits & 0x00000002u) { + end_ = from.end_; + } + _has_bits_[0] |= cached_has_bits; + } + _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_); +} + +void EnumDescriptorProto_EnumReservedRange::CopyFrom(const EnumDescriptorProto_EnumReservedRange& from) { +// @@protoc_insertion_point(class_specific_copy_from_start:google.protobuf.EnumDescriptorProto.EnumReservedRange) + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool EnumDescriptorProto_EnumReservedRange::IsInitialized() const { + return true; +} + +void EnumDescriptorProto_EnumReservedRange::InternalSwap(EnumDescriptorProto_EnumReservedRange* other) { + using std::swap; + _internal_metadata_.InternalSwap(&other->_internal_metadata_); + swap(_has_bits_[0], other->_has_bits_[0]); + ::PROTOBUF_NAMESPACE_ID::internal::memswap< + PROTOBUF_FIELD_OFFSET(EnumDescriptorProto_EnumReservedRange, end_) + + sizeof(EnumDescriptorProto_EnumReservedRange::end_) + - PROTOBUF_FIELD_OFFSET(EnumDescriptorProto_EnumReservedRange, start_)>( + reinterpret_cast<char*>(&start_), + reinterpret_cast<char*>(&other->start_)); +} + +::PROTOBUF_NAMESPACE_ID::Metadata EnumDescriptorProto_EnumReservedRange::GetMetadata() const { + return ::PROTOBUF_NAMESPACE_ID::internal::AssignDescriptors( + &descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_getter, &descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_once, + file_level_metadata_google_2fprotobuf_2fdescriptor_2eproto[8]); +} + +// =================================================================== + +class EnumDescriptorProto::_Internal { + public: + using HasBits = decltype(std::declval<EnumDescriptorProto>()._has_bits_); + static void set_has_name(HasBits* has_bits) { + (*has_bits)[0] |= 1u; + } + static const ::PROTOBUF_NAMESPACE_ID::EnumOptions& options(const EnumDescriptorProto* msg); + static void set_has_options(HasBits* has_bits) { + (*has_bits)[0] |= 2u; + } +}; + +const ::PROTOBUF_NAMESPACE_ID::EnumOptions& +EnumDescriptorProto::_Internal::options(const EnumDescriptorProto* msg) { + return *msg->options_; +} +EnumDescriptorProto::EnumDescriptorProto(::PROTOBUF_NAMESPACE_ID::Arena* arena, + bool is_message_owned) + : ::PROTOBUF_NAMESPACE_ID::Message(arena, is_message_owned), + value_(arena), + reserved_range_(arena), + reserved_name_(arena) { + SharedCtor(); + if (!is_message_owned) { + RegisterArenaDtor(arena); + } + // @@protoc_insertion_point(arena_constructor:google.protobuf.EnumDescriptorProto) +} +EnumDescriptorProto::EnumDescriptorProto(const EnumDescriptorProto& from) + : ::PROTOBUF_NAMESPACE_ID::Message(), + _has_bits_(from._has_bits_), + value_(from.value_), + reserved_range_(from.reserved_range_), + reserved_name_(from.reserved_name_) { + _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_); + name_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); + #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING + name_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation()); + #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING + if (from._internal_has_name()) { + name_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, from._internal_name(), + GetArenaForAllocation()); + } + if (from._internal_has_options()) { + options_ = new ::PROTOBUF_NAMESPACE_ID::EnumOptions(*from.options_); + } else { + options_ = nullptr; + } + // @@protoc_insertion_point(copy_constructor:google.protobuf.EnumDescriptorProto) +} + +inline void EnumDescriptorProto::SharedCtor() { +name_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); +#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING + name_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation()); +#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING +options_ = nullptr; +} + +EnumDescriptorProto::~EnumDescriptorProto() { + // @@protoc_insertion_point(destructor:google.protobuf.EnumDescriptorProto) + if (GetArenaForAllocation() != nullptr) return; + SharedDtor(); + _internal_metadata_.Delete<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(); +} + +inline void EnumDescriptorProto::SharedDtor() { + GOOGLE_DCHECK(GetArenaForAllocation() == nullptr); + name_.DestroyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); + if (this != internal_default_instance()) delete options_; +} + +void EnumDescriptorProto::ArenaDtor(void* object) { + EnumDescriptorProto* _this = reinterpret_cast< EnumDescriptorProto* >(object); + (void)_this; +} +void EnumDescriptorProto::RegisterArenaDtor(::PROTOBUF_NAMESPACE_ID::Arena*) { +} +void EnumDescriptorProto::SetCachedSize(int size) const { + _cached_size_.Set(size); +} + +void EnumDescriptorProto::Clear() { +// @@protoc_insertion_point(message_clear_start:google.protobuf.EnumDescriptorProto) + arc_ui32 cached_has_bits = 0; + // Prevent compiler warnings about cached_has_bits being unused + (void) cached_has_bits; + + value_.Clear(); + reserved_range_.Clear(); + reserved_name_.Clear(); + cached_has_bits = _has_bits_[0]; + if (cached_has_bits & 0x00000003u) { + if (cached_has_bits & 0x00000001u) { + name_.ClearNonDefaultToEmpty(); + } + if (cached_has_bits & 0x00000002u) { + GOOGLE_DCHECK(options_ != nullptr); + options_->Clear(); + } + } + _has_bits_.Clear(); + _internal_metadata_.Clear<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(); +} + +const char* EnumDescriptorProto::_InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) { +#define CHK_(x) if (PROTOBUF_PREDICT_FALSE(!(x))) goto failure + _Internal::HasBits has_bits{}; + while (!ctx->Done(&ptr)) { + arc_ui32 tag; + ptr = ::PROTOBUF_NAMESPACE_ID::internal::ReadTag(ptr, &tag); + switch (tag >> 3) { + // optional string name = 1; + case 1: + if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 10)) { + auto str = _internal_mutable_name(); + ptr = ::PROTOBUF_NAMESPACE_ID::internal::InlineGreedyStringParser(str, ptr, ctx); + #ifndef NDEBUG + ::PROTOBUF_NAMESPACE_ID::internal::VerifyUTF8(str, "google.protobuf.EnumDescriptorProto.name"); + #endif // !NDEBUG + CHK_(ptr); + } else + goto handle_unusual; + continue; + // repeated .google.protobuf.EnumValueDescriptorProto value = 2; + case 2: + if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 18)) { + ptr -= 1; + do { + ptr += 1; + ptr = ctx->ParseMessage(_internal_add_value(), ptr); + CHK_(ptr); + if (!ctx->DataAvailable(ptr)) break; + } while (::PROTOBUF_NAMESPACE_ID::internal::ExpectTag<18>(ptr)); + } else + goto handle_unusual; + continue; + // optional .google.protobuf.EnumOptions options = 3; + case 3: + if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 26)) { + ptr = ctx->ParseMessage(_internal_mutable_options(), ptr); + CHK_(ptr); + } else + goto handle_unusual; + continue; + // repeated .google.protobuf.EnumDescriptorProto.EnumReservedRange reserved_range = 4; + case 4: + if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 34)) { + ptr -= 1; + do { + ptr += 1; + ptr = ctx->ParseMessage(_internal_add_reserved_range(), ptr); + CHK_(ptr); + if (!ctx->DataAvailable(ptr)) break; + } while (::PROTOBUF_NAMESPACE_ID::internal::ExpectTag<34>(ptr)); + } else + goto handle_unusual; + continue; + // repeated string reserved_name = 5; + case 5: + if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 42)) { + ptr -= 1; + do { + ptr += 1; + auto str = _internal_add_reserved_name(); + ptr = ::PROTOBUF_NAMESPACE_ID::internal::InlineGreedyStringParser(str, ptr, ctx); + #ifndef NDEBUG + ::PROTOBUF_NAMESPACE_ID::internal::VerifyUTF8(str, "google.protobuf.EnumDescriptorProto.reserved_name"); + #endif // !NDEBUG + CHK_(ptr); + if (!ctx->DataAvailable(ptr)) break; + } while (::PROTOBUF_NAMESPACE_ID::internal::ExpectTag<42>(ptr)); + } else + goto handle_unusual; + continue; + default: + goto handle_unusual; + } // switch + handle_unusual: + if ((tag == 0) || ((tag & 7) == 4)) { + CHK_(ptr); + ctx->SetLastTag(tag); + goto message_done; + } + ptr = UnknownFieldParse( + tag, + _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(), + ptr, ctx); + CHK_(ptr != nullptr); + } // while +message_done: + _has_bits_.Or(has_bits); + return ptr; +failure: + ptr = nullptr; + goto message_done; +#undef CHK_ +} + +uint8_t* EnumDescriptorProto::_InternalSerialize( + uint8_t* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const { + // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.EnumDescriptorProto) + arc_ui32 cached_has_bits = 0; + (void) cached_has_bits; + + cached_has_bits = _has_bits_[0]; + // optional string name = 1; + if (cached_has_bits & 0x00000001u) { + ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::VerifyUTF8StringNamedField( + this->_internal_name().data(), static_cast<int>(this->_internal_name().length()), + ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::SERIALIZE, + "google.protobuf.EnumDescriptorProto.name"); + target = stream->WriteStringMaybeAliased( + 1, this->_internal_name(), target); + } + + // repeated .google.protobuf.EnumValueDescriptorProto value = 2; + for (unsigned int i = 0, + n = static_cast<unsigned int>(this->_internal_value_size()); i < n; i++) { + target = stream->EnsureSpace(target); + target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite:: + InternalWriteMessage(2, this->_internal_value(i), target, stream); + } + + // optional .google.protobuf.EnumOptions options = 3; + if (cached_has_bits & 0x00000002u) { + target = stream->EnsureSpace(target); + target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite:: + InternalWriteMessage( + 3, _Internal::options(this), target, stream); + } + + // repeated .google.protobuf.EnumDescriptorProto.EnumReservedRange reserved_range = 4; + for (unsigned int i = 0, + n = static_cast<unsigned int>(this->_internal_reserved_range_size()); i < n; i++) { + target = stream->EnsureSpace(target); + target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite:: + InternalWriteMessage(4, this->_internal_reserved_range(i), target, stream); + } + + // repeated string reserved_name = 5; + for (int i = 0, n = this->_internal_reserved_name_size(); i < n; i++) { + const auto& s = this->_internal_reserved_name(i); + ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::VerifyUTF8StringNamedField( + s.data(), static_cast<int>(s.length()), + ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::SERIALIZE, + "google.protobuf.EnumDescriptorProto.reserved_name"); + target = stream->WriteString(5, s, target); + } + + if (PROTOBUF_PREDICT_FALSE(_internal_metadata_.have_unknown_fields())) { + target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::InternalSerializeUnknownFieldsToArray( + _internal_metadata_.unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(::PROTOBUF_NAMESPACE_ID::UnknownFieldSet::default_instance), target, stream); + } + // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.EnumDescriptorProto) + return target; +} + +size_t EnumDescriptorProto::ByteSizeLong() const { +// @@protoc_insertion_point(message_byte_size_start:google.protobuf.EnumDescriptorProto) + size_t total_size = 0; + + arc_ui32 cached_has_bits = 0; + // Prevent compiler warnings about cached_has_bits being unused + (void) cached_has_bits; + + // repeated .google.protobuf.EnumValueDescriptorProto value = 2; + total_size += 1UL * this->_internal_value_size(); + for (const auto& msg : this->value_) { + total_size += + ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::MessageSize(msg); + } + + // repeated .google.protobuf.EnumDescriptorProto.EnumReservedRange reserved_range = 4; + total_size += 1UL * this->_internal_reserved_range_size(); + for (const auto& msg : this->reserved_range_) { + total_size += + ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::MessageSize(msg); + } + + // repeated string reserved_name = 5; + total_size += 1 * + ::PROTOBUF_NAMESPACE_ID::internal::FromIntSize(reserved_name_.size()); + for (int i = 0, n = reserved_name_.size(); i < n; i++) { + total_size += ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::StringSize( + reserved_name_.Get(i)); + } + + cached_has_bits = _has_bits_[0]; + if (cached_has_bits & 0x00000003u) { + // optional string name = 1; + if (cached_has_bits & 0x00000001u) { + total_size += 1 + + ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::StringSize( + this->_internal_name()); + } + + // optional .google.protobuf.EnumOptions options = 3; + if (cached_has_bits & 0x00000002u) { + total_size += 1 + + ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::MessageSize( + *options_); + } + + } + return MaybeComputeUnknownFieldsSize(total_size, &_cached_size_); +} + +const ::PROTOBUF_NAMESPACE_ID::Message::ClassData EnumDescriptorProto::_class_data_ = { + ::PROTOBUF_NAMESPACE_ID::Message::CopyWithSizeCheck, + EnumDescriptorProto::MergeImpl +}; +const ::PROTOBUF_NAMESPACE_ID::Message::ClassData*EnumDescriptorProto::GetClassData() const { return &_class_data_; } + +void EnumDescriptorProto::MergeImpl(::PROTOBUF_NAMESPACE_ID::Message* to, + const ::PROTOBUF_NAMESPACE_ID::Message& from) { + static_cast<EnumDescriptorProto *>(to)->MergeFrom( + static_cast<const EnumDescriptorProto &>(from)); +} + + +void EnumDescriptorProto::MergeFrom(const EnumDescriptorProto& from) { +// @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.EnumDescriptorProto) + GOOGLE_DCHECK_NE(&from, this); + arc_ui32 cached_has_bits = 0; + (void) cached_has_bits; + + value_.MergeFrom(from.value_); + reserved_range_.MergeFrom(from.reserved_range_); + reserved_name_.MergeFrom(from.reserved_name_); + cached_has_bits = from._has_bits_[0]; + if (cached_has_bits & 0x00000003u) { + if (cached_has_bits & 0x00000001u) { + _internal_set_name(from._internal_name()); + } + if (cached_has_bits & 0x00000002u) { + _internal_mutable_options()->::PROTOBUF_NAMESPACE_ID::EnumOptions::MergeFrom(from._internal_options()); + } + } + _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_); +} + +void EnumDescriptorProto::CopyFrom(const EnumDescriptorProto& from) { +// @@protoc_insertion_point(class_specific_copy_from_start:google.protobuf.EnumDescriptorProto) + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool EnumDescriptorProto::IsInitialized() const { + if (!::PROTOBUF_NAMESPACE_ID::internal::AllAreInitialized(value_)) + return false; + if (_internal_has_options()) { + if (!options_->IsInitialized()) return false; + } + return true; +} + +void EnumDescriptorProto::InternalSwap(EnumDescriptorProto* other) { + using std::swap; + auto* lhs_arena = GetArenaForAllocation(); + auto* rhs_arena = other->GetArenaForAllocation(); + _internal_metadata_.InternalSwap(&other->_internal_metadata_); + swap(_has_bits_[0], other->_has_bits_[0]); + value_.InternalSwap(&other->value_); + reserved_range_.InternalSwap(&other->reserved_range_); + reserved_name_.InternalSwap(&other->reserved_name_); + ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::InternalSwap( + &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), + &name_, lhs_arena, + &other->name_, rhs_arena + ); + swap(options_, other->options_); +} + +::PROTOBUF_NAMESPACE_ID::Metadata EnumDescriptorProto::GetMetadata() const { + return ::PROTOBUF_NAMESPACE_ID::internal::AssignDescriptors( + &descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_getter, &descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_once, + file_level_metadata_google_2fprotobuf_2fdescriptor_2eproto[9]); +} + +// =================================================================== + +class EnumValueDescriptorProto::_Internal { + public: + using HasBits = decltype(std::declval<EnumValueDescriptorProto>()._has_bits_); + static void set_has_name(HasBits* has_bits) { + (*has_bits)[0] |= 1u; + } + static void set_has_number(HasBits* has_bits) { + (*has_bits)[0] |= 4u; + } + static const ::PROTOBUF_NAMESPACE_ID::EnumValueOptions& options(const EnumValueDescriptorProto* msg); + static void set_has_options(HasBits* has_bits) { + (*has_bits)[0] |= 2u; + } +}; + +const ::PROTOBUF_NAMESPACE_ID::EnumValueOptions& +EnumValueDescriptorProto::_Internal::options(const EnumValueDescriptorProto* msg) { + return *msg->options_; +} +EnumValueDescriptorProto::EnumValueDescriptorProto(::PROTOBUF_NAMESPACE_ID::Arena* arena, + bool is_message_owned) + : ::PROTOBUF_NAMESPACE_ID::Message(arena, is_message_owned) { + SharedCtor(); + if (!is_message_owned) { + RegisterArenaDtor(arena); + } + // @@protoc_insertion_point(arena_constructor:google.protobuf.EnumValueDescriptorProto) +} +EnumValueDescriptorProto::EnumValueDescriptorProto(const EnumValueDescriptorProto& from) + : ::PROTOBUF_NAMESPACE_ID::Message(), + _has_bits_(from._has_bits_) { + _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_); + name_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); + #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING + name_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation()); + #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING + if (from._internal_has_name()) { + name_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, from._internal_name(), + GetArenaForAllocation()); + } + if (from._internal_has_options()) { + options_ = new ::PROTOBUF_NAMESPACE_ID::EnumValueOptions(*from.options_); + } else { + options_ = nullptr; + } + number_ = from.number_; + // @@protoc_insertion_point(copy_constructor:google.protobuf.EnumValueDescriptorProto) +} + +inline void EnumValueDescriptorProto::SharedCtor() { +name_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); +#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING + name_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation()); +#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING +::memset(reinterpret_cast<char*>(this) + static_cast<size_t>( + reinterpret_cast<char*>(&options_) - reinterpret_cast<char*>(this)), + 0, static_cast<size_t>(reinterpret_cast<char*>(&number_) - + reinterpret_cast<char*>(&options_)) + sizeof(number_)); +} + +EnumValueDescriptorProto::~EnumValueDescriptorProto() { + // @@protoc_insertion_point(destructor:google.protobuf.EnumValueDescriptorProto) + if (GetArenaForAllocation() != nullptr) return; + SharedDtor(); + _internal_metadata_.Delete<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(); +} + +inline void EnumValueDescriptorProto::SharedDtor() { + GOOGLE_DCHECK(GetArenaForAllocation() == nullptr); + name_.DestroyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); + if (this != internal_default_instance()) delete options_; +} + +void EnumValueDescriptorProto::ArenaDtor(void* object) { + EnumValueDescriptorProto* _this = reinterpret_cast< EnumValueDescriptorProto* >(object); + (void)_this; +} +void EnumValueDescriptorProto::RegisterArenaDtor(::PROTOBUF_NAMESPACE_ID::Arena*) { +} +void EnumValueDescriptorProto::SetCachedSize(int size) const { + _cached_size_.Set(size); +} + +void EnumValueDescriptorProto::Clear() { +// @@protoc_insertion_point(message_clear_start:google.protobuf.EnumValueDescriptorProto) + arc_ui32 cached_has_bits = 0; + // Prevent compiler warnings about cached_has_bits being unused + (void) cached_has_bits; + + cached_has_bits = _has_bits_[0]; + if (cached_has_bits & 0x00000003u) { + if (cached_has_bits & 0x00000001u) { + name_.ClearNonDefaultToEmpty(); + } + if (cached_has_bits & 0x00000002u) { + GOOGLE_DCHECK(options_ != nullptr); + options_->Clear(); + } + } + number_ = 0; + _has_bits_.Clear(); + _internal_metadata_.Clear<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(); +} + +const char* EnumValueDescriptorProto::_InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) { +#define CHK_(x) if (PROTOBUF_PREDICT_FALSE(!(x))) goto failure + _Internal::HasBits has_bits{}; + while (!ctx->Done(&ptr)) { + arc_ui32 tag; + ptr = ::PROTOBUF_NAMESPACE_ID::internal::ReadTag(ptr, &tag); + switch (tag >> 3) { + // optional string name = 1; + case 1: + if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 10)) { + auto str = _internal_mutable_name(); + ptr = ::PROTOBUF_NAMESPACE_ID::internal::InlineGreedyStringParser(str, ptr, ctx); + #ifndef NDEBUG + ::PROTOBUF_NAMESPACE_ID::internal::VerifyUTF8(str, "google.protobuf.EnumValueDescriptorProto.name"); + #endif // !NDEBUG + CHK_(ptr); + } else + goto handle_unusual; + continue; + // optional int32 number = 2; + case 2: + if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 16)) { + _Internal::set_has_number(&has_bits); + number_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint32(&ptr); + CHK_(ptr); + } else + goto handle_unusual; + continue; + // optional .google.protobuf.EnumValueOptions options = 3; + case 3: + if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 26)) { + ptr = ctx->ParseMessage(_internal_mutable_options(), ptr); + CHK_(ptr); + } else + goto handle_unusual; + continue; + default: + goto handle_unusual; + } // switch + handle_unusual: + if ((tag == 0) || ((tag & 7) == 4)) { + CHK_(ptr); + ctx->SetLastTag(tag); + goto message_done; + } + ptr = UnknownFieldParse( + tag, + _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(), + ptr, ctx); + CHK_(ptr != nullptr); + } // while +message_done: + _has_bits_.Or(has_bits); + return ptr; +failure: + ptr = nullptr; + goto message_done; +#undef CHK_ +} + +uint8_t* EnumValueDescriptorProto::_InternalSerialize( + uint8_t* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const { + // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.EnumValueDescriptorProto) + arc_ui32 cached_has_bits = 0; + (void) cached_has_bits; + + cached_has_bits = _has_bits_[0]; + // optional string name = 1; + if (cached_has_bits & 0x00000001u) { + ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::VerifyUTF8StringNamedField( + this->_internal_name().data(), static_cast<int>(this->_internal_name().length()), + ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::SERIALIZE, + "google.protobuf.EnumValueDescriptorProto.name"); + target = stream->WriteStringMaybeAliased( + 1, this->_internal_name(), target); + } + + // optional int32 number = 2; + if (cached_has_bits & 0x00000004u) { + target = stream->EnsureSpace(target); + target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteInt32ToArray(2, this->_internal_number(), target); + } + + // optional .google.protobuf.EnumValueOptions options = 3; + if (cached_has_bits & 0x00000002u) { + target = stream->EnsureSpace(target); + target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite:: + InternalWriteMessage( + 3, _Internal::options(this), target, stream); + } + + if (PROTOBUF_PREDICT_FALSE(_internal_metadata_.have_unknown_fields())) { + target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::InternalSerializeUnknownFieldsToArray( + _internal_metadata_.unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(::PROTOBUF_NAMESPACE_ID::UnknownFieldSet::default_instance), target, stream); + } + // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.EnumValueDescriptorProto) + return target; +} + +size_t EnumValueDescriptorProto::ByteSizeLong() const { +// @@protoc_insertion_point(message_byte_size_start:google.protobuf.EnumValueDescriptorProto) + size_t total_size = 0; + + arc_ui32 cached_has_bits = 0; + // Prevent compiler warnings about cached_has_bits being unused + (void) cached_has_bits; + + cached_has_bits = _has_bits_[0]; + if (cached_has_bits & 0x00000007u) { + // optional string name = 1; + if (cached_has_bits & 0x00000001u) { + total_size += 1 + + ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::StringSize( + this->_internal_name()); + } + + // optional .google.protobuf.EnumValueOptions options = 3; + if (cached_has_bits & 0x00000002u) { + total_size += 1 + + ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::MessageSize( + *options_); + } + + // optional int32 number = 2; + if (cached_has_bits & 0x00000004u) { + total_size += ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::Int32SizePlusOne(this->_internal_number()); + } + + } + return MaybeComputeUnknownFieldsSize(total_size, &_cached_size_); +} + +const ::PROTOBUF_NAMESPACE_ID::Message::ClassData EnumValueDescriptorProto::_class_data_ = { + ::PROTOBUF_NAMESPACE_ID::Message::CopyWithSizeCheck, + EnumValueDescriptorProto::MergeImpl +}; +const ::PROTOBUF_NAMESPACE_ID::Message::ClassData*EnumValueDescriptorProto::GetClassData() const { return &_class_data_; } + +void EnumValueDescriptorProto::MergeImpl(::PROTOBUF_NAMESPACE_ID::Message* to, + const ::PROTOBUF_NAMESPACE_ID::Message& from) { + static_cast<EnumValueDescriptorProto *>(to)->MergeFrom( + static_cast<const EnumValueDescriptorProto &>(from)); +} + + +void EnumValueDescriptorProto::MergeFrom(const EnumValueDescriptorProto& from) { +// @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.EnumValueDescriptorProto) + GOOGLE_DCHECK_NE(&from, this); + arc_ui32 cached_has_bits = 0; + (void) cached_has_bits; + + cached_has_bits = from._has_bits_[0]; + if (cached_has_bits & 0x00000007u) { + if (cached_has_bits & 0x00000001u) { + _internal_set_name(from._internal_name()); + } + if (cached_has_bits & 0x00000002u) { + _internal_mutable_options()->::PROTOBUF_NAMESPACE_ID::EnumValueOptions::MergeFrom(from._internal_options()); + } + if (cached_has_bits & 0x00000004u) { + number_ = from.number_; + } + _has_bits_[0] |= cached_has_bits; + } + _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_); +} + +void EnumValueDescriptorProto::CopyFrom(const EnumValueDescriptorProto& from) { +// @@protoc_insertion_point(class_specific_copy_from_start:google.protobuf.EnumValueDescriptorProto) + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool EnumValueDescriptorProto::IsInitialized() const { + if (_internal_has_options()) { + if (!options_->IsInitialized()) return false; + } + return true; +} + +void EnumValueDescriptorProto::InternalSwap(EnumValueDescriptorProto* other) { + using std::swap; + auto* lhs_arena = GetArenaForAllocation(); + auto* rhs_arena = other->GetArenaForAllocation(); + _internal_metadata_.InternalSwap(&other->_internal_metadata_); + swap(_has_bits_[0], other->_has_bits_[0]); + ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::InternalSwap( + &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), + &name_, lhs_arena, + &other->name_, rhs_arena + ); + ::PROTOBUF_NAMESPACE_ID::internal::memswap< + PROTOBUF_FIELD_OFFSET(EnumValueDescriptorProto, number_) + + sizeof(EnumValueDescriptorProto::number_) + - PROTOBUF_FIELD_OFFSET(EnumValueDescriptorProto, options_)>( + reinterpret_cast<char*>(&options_), + reinterpret_cast<char*>(&other->options_)); +} + +::PROTOBUF_NAMESPACE_ID::Metadata EnumValueDescriptorProto::GetMetadata() const { + return ::PROTOBUF_NAMESPACE_ID::internal::AssignDescriptors( + &descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_getter, &descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_once, + file_level_metadata_google_2fprotobuf_2fdescriptor_2eproto[10]); +} + +// =================================================================== + +class ServiceDescriptorProto::_Internal { + public: + using HasBits = decltype(std::declval<ServiceDescriptorProto>()._has_bits_); + static void set_has_name(HasBits* has_bits) { + (*has_bits)[0] |= 1u; + } + static const ::PROTOBUF_NAMESPACE_ID::ServiceOptions& options(const ServiceDescriptorProto* msg); + static void set_has_options(HasBits* has_bits) { + (*has_bits)[0] |= 2u; + } +}; + +const ::PROTOBUF_NAMESPACE_ID::ServiceOptions& +ServiceDescriptorProto::_Internal::options(const ServiceDescriptorProto* msg) { + return *msg->options_; +} +ServiceDescriptorProto::ServiceDescriptorProto(::PROTOBUF_NAMESPACE_ID::Arena* arena, + bool is_message_owned) + : ::PROTOBUF_NAMESPACE_ID::Message(arena, is_message_owned), + method_(arena) { + SharedCtor(); + if (!is_message_owned) { + RegisterArenaDtor(arena); + } + // @@protoc_insertion_point(arena_constructor:google.protobuf.ServiceDescriptorProto) +} +ServiceDescriptorProto::ServiceDescriptorProto(const ServiceDescriptorProto& from) + : ::PROTOBUF_NAMESPACE_ID::Message(), + _has_bits_(from._has_bits_), + method_(from.method_) { + _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_); + name_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); + #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING + name_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation()); + #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING + if (from._internal_has_name()) { + name_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, from._internal_name(), + GetArenaForAllocation()); + } + if (from._internal_has_options()) { + options_ = new ::PROTOBUF_NAMESPACE_ID::ServiceOptions(*from.options_); + } else { + options_ = nullptr; + } + // @@protoc_insertion_point(copy_constructor:google.protobuf.ServiceDescriptorProto) +} + +inline void ServiceDescriptorProto::SharedCtor() { +name_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); +#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING + name_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation()); +#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING +options_ = nullptr; +} + +ServiceDescriptorProto::~ServiceDescriptorProto() { + // @@protoc_insertion_point(destructor:google.protobuf.ServiceDescriptorProto) + if (GetArenaForAllocation() != nullptr) return; + SharedDtor(); + _internal_metadata_.Delete<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(); +} + +inline void ServiceDescriptorProto::SharedDtor() { + GOOGLE_DCHECK(GetArenaForAllocation() == nullptr); + name_.DestroyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); + if (this != internal_default_instance()) delete options_; +} + +void ServiceDescriptorProto::ArenaDtor(void* object) { + ServiceDescriptorProto* _this = reinterpret_cast< ServiceDescriptorProto* >(object); + (void)_this; +} +void ServiceDescriptorProto::RegisterArenaDtor(::PROTOBUF_NAMESPACE_ID::Arena*) { +} +void ServiceDescriptorProto::SetCachedSize(int size) const { + _cached_size_.Set(size); +} + +void ServiceDescriptorProto::Clear() { +// @@protoc_insertion_point(message_clear_start:google.protobuf.ServiceDescriptorProto) + arc_ui32 cached_has_bits = 0; + // Prevent compiler warnings about cached_has_bits being unused + (void) cached_has_bits; + + method_.Clear(); + cached_has_bits = _has_bits_[0]; + if (cached_has_bits & 0x00000003u) { + if (cached_has_bits & 0x00000001u) { + name_.ClearNonDefaultToEmpty(); + } + if (cached_has_bits & 0x00000002u) { + GOOGLE_DCHECK(options_ != nullptr); + options_->Clear(); + } + } + _has_bits_.Clear(); + _internal_metadata_.Clear<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(); +} + +const char* ServiceDescriptorProto::_InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) { +#define CHK_(x) if (PROTOBUF_PREDICT_FALSE(!(x))) goto failure + _Internal::HasBits has_bits{}; + while (!ctx->Done(&ptr)) { + arc_ui32 tag; + ptr = ::PROTOBUF_NAMESPACE_ID::internal::ReadTag(ptr, &tag); + switch (tag >> 3) { + // optional string name = 1; + case 1: + if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 10)) { + auto str = _internal_mutable_name(); + ptr = ::PROTOBUF_NAMESPACE_ID::internal::InlineGreedyStringParser(str, ptr, ctx); + #ifndef NDEBUG + ::PROTOBUF_NAMESPACE_ID::internal::VerifyUTF8(str, "google.protobuf.ServiceDescriptorProto.name"); + #endif // !NDEBUG + CHK_(ptr); + } else + goto handle_unusual; + continue; + // repeated .google.protobuf.MethodDescriptorProto method = 2; + case 2: + if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 18)) { + ptr -= 1; + do { + ptr += 1; + ptr = ctx->ParseMessage(_internal_add_method(), ptr); + CHK_(ptr); + if (!ctx->DataAvailable(ptr)) break; + } while (::PROTOBUF_NAMESPACE_ID::internal::ExpectTag<18>(ptr)); + } else + goto handle_unusual; + continue; + // optional .google.protobuf.ServiceOptions options = 3; + case 3: + if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 26)) { + ptr = ctx->ParseMessage(_internal_mutable_options(), ptr); + CHK_(ptr); + } else + goto handle_unusual; + continue; + default: + goto handle_unusual; + } // switch + handle_unusual: + if ((tag == 0) || ((tag & 7) == 4)) { + CHK_(ptr); + ctx->SetLastTag(tag); + goto message_done; + } + ptr = UnknownFieldParse( + tag, + _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(), + ptr, ctx); + CHK_(ptr != nullptr); + } // while +message_done: + _has_bits_.Or(has_bits); + return ptr; +failure: + ptr = nullptr; + goto message_done; +#undef CHK_ +} + +uint8_t* ServiceDescriptorProto::_InternalSerialize( + uint8_t* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const { + // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.ServiceDescriptorProto) + arc_ui32 cached_has_bits = 0; + (void) cached_has_bits; + + cached_has_bits = _has_bits_[0]; + // optional string name = 1; + if (cached_has_bits & 0x00000001u) { + ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::VerifyUTF8StringNamedField( + this->_internal_name().data(), static_cast<int>(this->_internal_name().length()), + ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::SERIALIZE, + "google.protobuf.ServiceDescriptorProto.name"); + target = stream->WriteStringMaybeAliased( + 1, this->_internal_name(), target); + } + + // repeated .google.protobuf.MethodDescriptorProto method = 2; + for (unsigned int i = 0, + n = static_cast<unsigned int>(this->_internal_method_size()); i < n; i++) { + target = stream->EnsureSpace(target); + target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite:: + InternalWriteMessage(2, this->_internal_method(i), target, stream); + } + + // optional .google.protobuf.ServiceOptions options = 3; + if (cached_has_bits & 0x00000002u) { + target = stream->EnsureSpace(target); + target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite:: + InternalWriteMessage( + 3, _Internal::options(this), target, stream); + } + + if (PROTOBUF_PREDICT_FALSE(_internal_metadata_.have_unknown_fields())) { + target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::InternalSerializeUnknownFieldsToArray( + _internal_metadata_.unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(::PROTOBUF_NAMESPACE_ID::UnknownFieldSet::default_instance), target, stream); + } + // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.ServiceDescriptorProto) + return target; +} + +size_t ServiceDescriptorProto::ByteSizeLong() const { +// @@protoc_insertion_point(message_byte_size_start:google.protobuf.ServiceDescriptorProto) + size_t total_size = 0; + + arc_ui32 cached_has_bits = 0; + // Prevent compiler warnings about cached_has_bits being unused + (void) cached_has_bits; + + // repeated .google.protobuf.MethodDescriptorProto method = 2; + total_size += 1UL * this->_internal_method_size(); + for (const auto& msg : this->method_) { + total_size += + ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::MessageSize(msg); + } + + cached_has_bits = _has_bits_[0]; + if (cached_has_bits & 0x00000003u) { + // optional string name = 1; + if (cached_has_bits & 0x00000001u) { + total_size += 1 + + ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::StringSize( + this->_internal_name()); + } + + // optional .google.protobuf.ServiceOptions options = 3; + if (cached_has_bits & 0x00000002u) { + total_size += 1 + + ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::MessageSize( + *options_); + } + + } + return MaybeComputeUnknownFieldsSize(total_size, &_cached_size_); +} + +const ::PROTOBUF_NAMESPACE_ID::Message::ClassData ServiceDescriptorProto::_class_data_ = { + ::PROTOBUF_NAMESPACE_ID::Message::CopyWithSizeCheck, + ServiceDescriptorProto::MergeImpl +}; +const ::PROTOBUF_NAMESPACE_ID::Message::ClassData*ServiceDescriptorProto::GetClassData() const { return &_class_data_; } + +void ServiceDescriptorProto::MergeImpl(::PROTOBUF_NAMESPACE_ID::Message* to, + const ::PROTOBUF_NAMESPACE_ID::Message& from) { + static_cast<ServiceDescriptorProto *>(to)->MergeFrom( + static_cast<const ServiceDescriptorProto &>(from)); +} + + +void ServiceDescriptorProto::MergeFrom(const ServiceDescriptorProto& from) { +// @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.ServiceDescriptorProto) + GOOGLE_DCHECK_NE(&from, this); + arc_ui32 cached_has_bits = 0; + (void) cached_has_bits; + + method_.MergeFrom(from.method_); + cached_has_bits = from._has_bits_[0]; + if (cached_has_bits & 0x00000003u) { + if (cached_has_bits & 0x00000001u) { + _internal_set_name(from._internal_name()); + } + if (cached_has_bits & 0x00000002u) { + _internal_mutable_options()->::PROTOBUF_NAMESPACE_ID::ServiceOptions::MergeFrom(from._internal_options()); + } + } + _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_); +} + +void ServiceDescriptorProto::CopyFrom(const ServiceDescriptorProto& from) { +// @@protoc_insertion_point(class_specific_copy_from_start:google.protobuf.ServiceDescriptorProto) + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool ServiceDescriptorProto::IsInitialized() const { + if (!::PROTOBUF_NAMESPACE_ID::internal::AllAreInitialized(method_)) + return false; + if (_internal_has_options()) { + if (!options_->IsInitialized()) return false; + } + return true; +} + +void ServiceDescriptorProto::InternalSwap(ServiceDescriptorProto* other) { + using std::swap; + auto* lhs_arena = GetArenaForAllocation(); + auto* rhs_arena = other->GetArenaForAllocation(); + _internal_metadata_.InternalSwap(&other->_internal_metadata_); + swap(_has_bits_[0], other->_has_bits_[0]); + method_.InternalSwap(&other->method_); + ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::InternalSwap( + &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), + &name_, lhs_arena, + &other->name_, rhs_arena + ); + swap(options_, other->options_); +} + +::PROTOBUF_NAMESPACE_ID::Metadata ServiceDescriptorProto::GetMetadata() const { + return ::PROTOBUF_NAMESPACE_ID::internal::AssignDescriptors( + &descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_getter, &descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_once, + file_level_metadata_google_2fprotobuf_2fdescriptor_2eproto[11]); +} + +// =================================================================== + +class MethodDescriptorProto::_Internal { + public: + using HasBits = decltype(std::declval<MethodDescriptorProto>()._has_bits_); + static void set_has_name(HasBits* has_bits) { + (*has_bits)[0] |= 1u; + } + static void set_has_input_type(HasBits* has_bits) { + (*has_bits)[0] |= 2u; + } + static void set_has_output_type(HasBits* has_bits) { + (*has_bits)[0] |= 4u; + } + static const ::PROTOBUF_NAMESPACE_ID::MethodOptions& options(const MethodDescriptorProto* msg); + static void set_has_options(HasBits* has_bits) { + (*has_bits)[0] |= 8u; + } + static void set_has_client_streaming(HasBits* has_bits) { + (*has_bits)[0] |= 16u; + } + static void set_has_server_streaming(HasBits* has_bits) { + (*has_bits)[0] |= 32u; + } +}; + +const ::PROTOBUF_NAMESPACE_ID::MethodOptions& +MethodDescriptorProto::_Internal::options(const MethodDescriptorProto* msg) { + return *msg->options_; +} +MethodDescriptorProto::MethodDescriptorProto(::PROTOBUF_NAMESPACE_ID::Arena* arena, + bool is_message_owned) + : ::PROTOBUF_NAMESPACE_ID::Message(arena, is_message_owned) { + SharedCtor(); + if (!is_message_owned) { + RegisterArenaDtor(arena); + } + // @@protoc_insertion_point(arena_constructor:google.protobuf.MethodDescriptorProto) +} +MethodDescriptorProto::MethodDescriptorProto(const MethodDescriptorProto& from) + : ::PROTOBUF_NAMESPACE_ID::Message(), + _has_bits_(from._has_bits_) { + _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_); + name_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); + #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING + name_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation()); + #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING + if (from._internal_has_name()) { + name_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, from._internal_name(), + GetArenaForAllocation()); + } + input_type_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); + #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING + input_type_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation()); + #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING + if (from._internal_has_input_type()) { + input_type_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, from._internal_input_type(), + GetArenaForAllocation()); + } + output_type_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); + #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING + output_type_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation()); + #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING + if (from._internal_has_output_type()) { + output_type_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, from._internal_output_type(), + GetArenaForAllocation()); + } + if (from._internal_has_options()) { + options_ = new ::PROTOBUF_NAMESPACE_ID::MethodOptions(*from.options_); + } else { + options_ = nullptr; + } + ::memcpy(&client_streaming_, &from.client_streaming_, + static_cast<size_t>(reinterpret_cast<char*>(&server_streaming_) - + reinterpret_cast<char*>(&client_streaming_)) + sizeof(server_streaming_)); + // @@protoc_insertion_point(copy_constructor:google.protobuf.MethodDescriptorProto) +} + +inline void MethodDescriptorProto::SharedCtor() { +name_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); +#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING + name_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation()); +#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING +input_type_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); +#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING + input_type_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation()); +#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING +output_type_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); +#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING + output_type_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation()); +#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING +::memset(reinterpret_cast<char*>(this) + static_cast<size_t>( + reinterpret_cast<char*>(&options_) - reinterpret_cast<char*>(this)), + 0, static_cast<size_t>(reinterpret_cast<char*>(&server_streaming_) - + reinterpret_cast<char*>(&options_)) + sizeof(server_streaming_)); +} + +MethodDescriptorProto::~MethodDescriptorProto() { + // @@protoc_insertion_point(destructor:google.protobuf.MethodDescriptorProto) + if (GetArenaForAllocation() != nullptr) return; + SharedDtor(); + _internal_metadata_.Delete<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(); +} + +inline void MethodDescriptorProto::SharedDtor() { + GOOGLE_DCHECK(GetArenaForAllocation() == nullptr); + name_.DestroyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); + input_type_.DestroyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); + output_type_.DestroyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); + if (this != internal_default_instance()) delete options_; +} + +void MethodDescriptorProto::ArenaDtor(void* object) { + MethodDescriptorProto* _this = reinterpret_cast< MethodDescriptorProto* >(object); + (void)_this; +} +void MethodDescriptorProto::RegisterArenaDtor(::PROTOBUF_NAMESPACE_ID::Arena*) { +} +void MethodDescriptorProto::SetCachedSize(int size) const { + _cached_size_.Set(size); +} + +void MethodDescriptorProto::Clear() { +// @@protoc_insertion_point(message_clear_start:google.protobuf.MethodDescriptorProto) + arc_ui32 cached_has_bits = 0; + // Prevent compiler warnings about cached_has_bits being unused + (void) cached_has_bits; + + cached_has_bits = _has_bits_[0]; + if (cached_has_bits & 0x0000000fu) { + if (cached_has_bits & 0x00000001u) { + name_.ClearNonDefaultToEmpty(); + } + if (cached_has_bits & 0x00000002u) { + input_type_.ClearNonDefaultToEmpty(); + } + if (cached_has_bits & 0x00000004u) { + output_type_.ClearNonDefaultToEmpty(); + } + if (cached_has_bits & 0x00000008u) { + GOOGLE_DCHECK(options_ != nullptr); + options_->Clear(); + } + } + ::memset(&client_streaming_, 0, static_cast<size_t>( + reinterpret_cast<char*>(&server_streaming_) - + reinterpret_cast<char*>(&client_streaming_)) + sizeof(server_streaming_)); + _has_bits_.Clear(); + _internal_metadata_.Clear<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(); +} + +const char* MethodDescriptorProto::_InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) { +#define CHK_(x) if (PROTOBUF_PREDICT_FALSE(!(x))) goto failure + _Internal::HasBits has_bits{}; + while (!ctx->Done(&ptr)) { + arc_ui32 tag; + ptr = ::PROTOBUF_NAMESPACE_ID::internal::ReadTag(ptr, &tag); + switch (tag >> 3) { + // optional string name = 1; + case 1: + if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 10)) { + auto str = _internal_mutable_name(); + ptr = ::PROTOBUF_NAMESPACE_ID::internal::InlineGreedyStringParser(str, ptr, ctx); + #ifndef NDEBUG + ::PROTOBUF_NAMESPACE_ID::internal::VerifyUTF8(str, "google.protobuf.MethodDescriptorProto.name"); + #endif // !NDEBUG + CHK_(ptr); + } else + goto handle_unusual; + continue; + // optional string input_type = 2; + case 2: + if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 18)) { + auto str = _internal_mutable_input_type(); + ptr = ::PROTOBUF_NAMESPACE_ID::internal::InlineGreedyStringParser(str, ptr, ctx); + #ifndef NDEBUG + ::PROTOBUF_NAMESPACE_ID::internal::VerifyUTF8(str, "google.protobuf.MethodDescriptorProto.input_type"); + #endif // !NDEBUG + CHK_(ptr); + } else + goto handle_unusual; + continue; + // optional string output_type = 3; + case 3: + if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 26)) { + auto str = _internal_mutable_output_type(); + ptr = ::PROTOBUF_NAMESPACE_ID::internal::InlineGreedyStringParser(str, ptr, ctx); + #ifndef NDEBUG + ::PROTOBUF_NAMESPACE_ID::internal::VerifyUTF8(str, "google.protobuf.MethodDescriptorProto.output_type"); + #endif // !NDEBUG + CHK_(ptr); + } else + goto handle_unusual; + continue; + // optional .google.protobuf.MethodOptions options = 4; + case 4: + if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 34)) { + ptr = ctx->ParseMessage(_internal_mutable_options(), ptr); + CHK_(ptr); + } else + goto handle_unusual; + continue; + // optional bool client_streaming = 5 [default = false]; + case 5: + if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 40)) { + _Internal::set_has_client_streaming(&has_bits); + client_streaming_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint64(&ptr); + CHK_(ptr); + } else + goto handle_unusual; + continue; + // optional bool server_streaming = 6 [default = false]; + case 6: + if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 48)) { + _Internal::set_has_server_streaming(&has_bits); + server_streaming_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint64(&ptr); + CHK_(ptr); + } else + goto handle_unusual; + continue; + default: + goto handle_unusual; + } // switch + handle_unusual: + if ((tag == 0) || ((tag & 7) == 4)) { + CHK_(ptr); + ctx->SetLastTag(tag); + goto message_done; + } + ptr = UnknownFieldParse( + tag, + _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(), + ptr, ctx); + CHK_(ptr != nullptr); + } // while +message_done: + _has_bits_.Or(has_bits); + return ptr; +failure: + ptr = nullptr; + goto message_done; +#undef CHK_ +} + +uint8_t* MethodDescriptorProto::_InternalSerialize( + uint8_t* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const { + // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.MethodDescriptorProto) + arc_ui32 cached_has_bits = 0; + (void) cached_has_bits; + + cached_has_bits = _has_bits_[0]; + // optional string name = 1; + if (cached_has_bits & 0x00000001u) { + ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::VerifyUTF8StringNamedField( + this->_internal_name().data(), static_cast<int>(this->_internal_name().length()), + ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::SERIALIZE, + "google.protobuf.MethodDescriptorProto.name"); + target = stream->WriteStringMaybeAliased( + 1, this->_internal_name(), target); + } + + // optional string input_type = 2; + if (cached_has_bits & 0x00000002u) { + ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::VerifyUTF8StringNamedField( + this->_internal_input_type().data(), static_cast<int>(this->_internal_input_type().length()), + ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::SERIALIZE, + "google.protobuf.MethodDescriptorProto.input_type"); + target = stream->WriteStringMaybeAliased( + 2, this->_internal_input_type(), target); + } + + // optional string output_type = 3; + if (cached_has_bits & 0x00000004u) { + ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::VerifyUTF8StringNamedField( + this->_internal_output_type().data(), static_cast<int>(this->_internal_output_type().length()), + ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::SERIALIZE, + "google.protobuf.MethodDescriptorProto.output_type"); + target = stream->WriteStringMaybeAliased( + 3, this->_internal_output_type(), target); + } + + // optional .google.protobuf.MethodOptions options = 4; + if (cached_has_bits & 0x00000008u) { + target = stream->EnsureSpace(target); + target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite:: + InternalWriteMessage( + 4, _Internal::options(this), target, stream); + } + + // optional bool client_streaming = 5 [default = false]; + if (cached_has_bits & 0x00000010u) { + target = stream->EnsureSpace(target); + target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteBoolToArray(5, this->_internal_client_streaming(), target); + } + + // optional bool server_streaming = 6 [default = false]; + if (cached_has_bits & 0x00000020u) { + target = stream->EnsureSpace(target); + target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteBoolToArray(6, this->_internal_server_streaming(), target); + } + + if (PROTOBUF_PREDICT_FALSE(_internal_metadata_.have_unknown_fields())) { + target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::InternalSerializeUnknownFieldsToArray( + _internal_metadata_.unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(::PROTOBUF_NAMESPACE_ID::UnknownFieldSet::default_instance), target, stream); + } + // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.MethodDescriptorProto) + return target; +} + +size_t MethodDescriptorProto::ByteSizeLong() const { +// @@protoc_insertion_point(message_byte_size_start:google.protobuf.MethodDescriptorProto) + size_t total_size = 0; + + arc_ui32 cached_has_bits = 0; + // Prevent compiler warnings about cached_has_bits being unused + (void) cached_has_bits; + + cached_has_bits = _has_bits_[0]; + if (cached_has_bits & 0x0000003fu) { + // optional string name = 1; + if (cached_has_bits & 0x00000001u) { + total_size += 1 + + ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::StringSize( + this->_internal_name()); + } + + // optional string input_type = 2; + if (cached_has_bits & 0x00000002u) { + total_size += 1 + + ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::StringSize( + this->_internal_input_type()); + } + + // optional string output_type = 3; + if (cached_has_bits & 0x00000004u) { + total_size += 1 + + ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::StringSize( + this->_internal_output_type()); + } + + // optional .google.protobuf.MethodOptions options = 4; + if (cached_has_bits & 0x00000008u) { + total_size += 1 + + ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::MessageSize( + *options_); + } + + // optional bool client_streaming = 5 [default = false]; + if (cached_has_bits & 0x00000010u) { + total_size += 1 + 1; + } + + // optional bool server_streaming = 6 [default = false]; + if (cached_has_bits & 0x00000020u) { + total_size += 1 + 1; + } + + } + return MaybeComputeUnknownFieldsSize(total_size, &_cached_size_); +} + +const ::PROTOBUF_NAMESPACE_ID::Message::ClassData MethodDescriptorProto::_class_data_ = { + ::PROTOBUF_NAMESPACE_ID::Message::CopyWithSizeCheck, + MethodDescriptorProto::MergeImpl +}; +const ::PROTOBUF_NAMESPACE_ID::Message::ClassData*MethodDescriptorProto::GetClassData() const { return &_class_data_; } + +void MethodDescriptorProto::MergeImpl(::PROTOBUF_NAMESPACE_ID::Message* to, + const ::PROTOBUF_NAMESPACE_ID::Message& from) { + static_cast<MethodDescriptorProto *>(to)->MergeFrom( + static_cast<const MethodDescriptorProto &>(from)); +} + + +void MethodDescriptorProto::MergeFrom(const MethodDescriptorProto& from) { +// @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.MethodDescriptorProto) + GOOGLE_DCHECK_NE(&from, this); + arc_ui32 cached_has_bits = 0; + (void) cached_has_bits; + + cached_has_bits = from._has_bits_[0]; + if (cached_has_bits & 0x0000003fu) { + if (cached_has_bits & 0x00000001u) { + _internal_set_name(from._internal_name()); + } + if (cached_has_bits & 0x00000002u) { + _internal_set_input_type(from._internal_input_type()); + } + if (cached_has_bits & 0x00000004u) { + _internal_set_output_type(from._internal_output_type()); + } + if (cached_has_bits & 0x00000008u) { + _internal_mutable_options()->::PROTOBUF_NAMESPACE_ID::MethodOptions::MergeFrom(from._internal_options()); + } + if (cached_has_bits & 0x00000010u) { + client_streaming_ = from.client_streaming_; + } + if (cached_has_bits & 0x00000020u) { + server_streaming_ = from.server_streaming_; + } + _has_bits_[0] |= cached_has_bits; + } + _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_); +} + +void MethodDescriptorProto::CopyFrom(const MethodDescriptorProto& from) { +// @@protoc_insertion_point(class_specific_copy_from_start:google.protobuf.MethodDescriptorProto) + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool MethodDescriptorProto::IsInitialized() const { + if (_internal_has_options()) { + if (!options_->IsInitialized()) return false; + } + return true; +} + +void MethodDescriptorProto::InternalSwap(MethodDescriptorProto* other) { + using std::swap; + auto* lhs_arena = GetArenaForAllocation(); + auto* rhs_arena = other->GetArenaForAllocation(); + _internal_metadata_.InternalSwap(&other->_internal_metadata_); + swap(_has_bits_[0], other->_has_bits_[0]); + ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::InternalSwap( + &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), + &name_, lhs_arena, + &other->name_, rhs_arena + ); + ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::InternalSwap( + &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), + &input_type_, lhs_arena, + &other->input_type_, rhs_arena + ); + ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::InternalSwap( + &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), + &output_type_, lhs_arena, + &other->output_type_, rhs_arena + ); + ::PROTOBUF_NAMESPACE_ID::internal::memswap< + PROTOBUF_FIELD_OFFSET(MethodDescriptorProto, server_streaming_) + + sizeof(MethodDescriptorProto::server_streaming_) + - PROTOBUF_FIELD_OFFSET(MethodDescriptorProto, options_)>( + reinterpret_cast<char*>(&options_), + reinterpret_cast<char*>(&other->options_)); +} + +::PROTOBUF_NAMESPACE_ID::Metadata MethodDescriptorProto::GetMetadata() const { + return ::PROTOBUF_NAMESPACE_ID::internal::AssignDescriptors( + &descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_getter, &descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_once, + file_level_metadata_google_2fprotobuf_2fdescriptor_2eproto[12]); +} + +// =================================================================== + +class FileOptions::_Internal { + public: + using HasBits = decltype(std::declval<FileOptions>()._has_bits_); + static void set_has_java_package(HasBits* has_bits) { + (*has_bits)[0] |= 1u; + } + static void set_has_java_outer_classname(HasBits* has_bits) { + (*has_bits)[0] |= 2u; + } + static void set_has_java_multiple_files(HasBits* has_bits) { + (*has_bits)[0] |= 1024u; + } + static void set_has_java_generate_equals_and_hash(HasBits* has_bits) { + (*has_bits)[0] |= 2048u; + } + static void set_has_java_string_check_utf8(HasBits* has_bits) { + (*has_bits)[0] |= 4096u; + } + static void set_has_optimize_for(HasBits* has_bits) { + (*has_bits)[0] |= 262144u; + } + static void set_has_go_package(HasBits* has_bits) { + (*has_bits)[0] |= 4u; + } + static void set_has_cc_generic_services(HasBits* has_bits) { + (*has_bits)[0] |= 8192u; + } + static void set_has_java_generic_services(HasBits* has_bits) { + (*has_bits)[0] |= 16384u; + } + static void set_has_py_generic_services(HasBits* has_bits) { + (*has_bits)[0] |= 32768u; + } + static void set_has_php_generic_services(HasBits* has_bits) { + (*has_bits)[0] |= 65536u; + } + static void set_has_deprecated(HasBits* has_bits) { + (*has_bits)[0] |= 131072u; + } + static void set_has_cc_enable_arenas(HasBits* has_bits) { + (*has_bits)[0] |= 524288u; + } + static void set_has_objc_class_prefix(HasBits* has_bits) { + (*has_bits)[0] |= 8u; + } + static void set_has_csharp_namespace(HasBits* has_bits) { + (*has_bits)[0] |= 16u; + } + static void set_has_swift_prefix(HasBits* has_bits) { + (*has_bits)[0] |= 32u; + } + static void set_has_php_class_prefix(HasBits* has_bits) { + (*has_bits)[0] |= 64u; + } + static void set_has_php_namespace(HasBits* has_bits) { + (*has_bits)[0] |= 128u; + } + static void set_has_php_metadata_namespace(HasBits* has_bits) { + (*has_bits)[0] |= 256u; + } + static void set_has_ruby_package(HasBits* has_bits) { + (*has_bits)[0] |= 512u; + } +}; + +FileOptions::FileOptions(::PROTOBUF_NAMESPACE_ID::Arena* arena, + bool is_message_owned) + : ::PROTOBUF_NAMESPACE_ID::Message(arena, is_message_owned), + _extensions_(arena), + uninterpreted_option_(arena) { + SharedCtor(); + if (!is_message_owned) { + RegisterArenaDtor(arena); + } + // @@protoc_insertion_point(arena_constructor:google.protobuf.FileOptions) +} +FileOptions::FileOptions(const FileOptions& from) + : ::PROTOBUF_NAMESPACE_ID::Message(), + _has_bits_(from._has_bits_), + uninterpreted_option_(from.uninterpreted_option_) { + _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_); + _extensions_.MergeFrom(internal_default_instance(), from._extensions_); + java_package_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); + #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING + java_package_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation()); + #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING + if (from._internal_has_java_package()) { + java_package_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, from._internal_java_package(), + GetArenaForAllocation()); + } + java_outer_classname_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); + #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING + java_outer_classname_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation()); + #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING + if (from._internal_has_java_outer_classname()) { + java_outer_classname_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, from._internal_java_outer_classname(), + GetArenaForAllocation()); + } + go_package_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); + #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING + go_package_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation()); + #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING + if (from._internal_has_go_package()) { + go_package_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, from._internal_go_package(), + GetArenaForAllocation()); + } + objc_class_prefix_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); + #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING + objc_class_prefix_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation()); + #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING + if (from._internal_has_objc_class_prefix()) { + objc_class_prefix_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, from._internal_objc_class_prefix(), + GetArenaForAllocation()); + } + csharp_namespace_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); + #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING + csharp_namespace_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation()); + #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING + if (from._internal_has_csharp_namespace()) { + csharp_namespace_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, from._internal_csharp_namespace(), + GetArenaForAllocation()); + } + swift_prefix_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); + #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING + swift_prefix_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation()); + #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING + if (from._internal_has_swift_prefix()) { + swift_prefix_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, from._internal_swift_prefix(), + GetArenaForAllocation()); + } + php_class_prefix_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); + #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING + php_class_prefix_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation()); + #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING + if (from._internal_has_php_class_prefix()) { + php_class_prefix_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, from._internal_php_class_prefix(), + GetArenaForAllocation()); + } + php_namespace_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); + #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING + php_namespace_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation()); + #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING + if (from._internal_has_php_namespace()) { + php_namespace_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, from._internal_php_namespace(), + GetArenaForAllocation()); + } + php_metadata_namespace_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); + #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING + php_metadata_namespace_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation()); + #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING + if (from._internal_has_php_metadata_namespace()) { + php_metadata_namespace_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, from._internal_php_metadata_namespace(), + GetArenaForAllocation()); + } + ruby_package_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); + #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING + ruby_package_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation()); + #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING + if (from._internal_has_ruby_package()) { + ruby_package_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, from._internal_ruby_package(), + GetArenaForAllocation()); + } + ::memcpy(&java_multiple_files_, &from.java_multiple_files_, + static_cast<size_t>(reinterpret_cast<char*>(&cc_enable_arenas_) - + reinterpret_cast<char*>(&java_multiple_files_)) + sizeof(cc_enable_arenas_)); + // @@protoc_insertion_point(copy_constructor:google.protobuf.FileOptions) +} + +inline void FileOptions::SharedCtor() { +java_package_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); +#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING + java_package_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation()); +#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING +java_outer_classname_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); +#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING + java_outer_classname_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation()); +#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING +go_package_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); +#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING + go_package_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation()); +#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING +objc_class_prefix_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); +#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING + objc_class_prefix_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation()); +#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING +csharp_namespace_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); +#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING + csharp_namespace_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation()); +#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING +swift_prefix_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); +#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING + swift_prefix_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation()); +#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING +php_class_prefix_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); +#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING + php_class_prefix_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation()); +#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING +php_namespace_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); +#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING + php_namespace_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation()); +#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING +php_metadata_namespace_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); +#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING + php_metadata_namespace_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation()); +#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING +ruby_package_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); +#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING + ruby_package_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation()); +#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING +::memset(reinterpret_cast<char*>(this) + static_cast<size_t>( + reinterpret_cast<char*>(&java_multiple_files_) - reinterpret_cast<char*>(this)), + 0, static_cast<size_t>(reinterpret_cast<char*>(&deprecated_) - + reinterpret_cast<char*>(&java_multiple_files_)) + sizeof(deprecated_)); +optimize_for_ = 1; +cc_enable_arenas_ = true; +} + +FileOptions::~FileOptions() { + // @@protoc_insertion_point(destructor:google.protobuf.FileOptions) + if (GetArenaForAllocation() != nullptr) return; + SharedDtor(); + _internal_metadata_.Delete<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(); +} + +inline void FileOptions::SharedDtor() { + GOOGLE_DCHECK(GetArenaForAllocation() == nullptr); + java_package_.DestroyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); + java_outer_classname_.DestroyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); + go_package_.DestroyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); + objc_class_prefix_.DestroyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); + csharp_namespace_.DestroyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); + swift_prefix_.DestroyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); + php_class_prefix_.DestroyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); + php_namespace_.DestroyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); + php_metadata_namespace_.DestroyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); + ruby_package_.DestroyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); +} + +void FileOptions::ArenaDtor(void* object) { + FileOptions* _this = reinterpret_cast< FileOptions* >(object); + (void)_this; +} +void FileOptions::RegisterArenaDtor(::PROTOBUF_NAMESPACE_ID::Arena*) { +} +void FileOptions::SetCachedSize(int size) const { + _cached_size_.Set(size); +} + +void FileOptions::Clear() { +// @@protoc_insertion_point(message_clear_start:google.protobuf.FileOptions) + arc_ui32 cached_has_bits = 0; + // Prevent compiler warnings about cached_has_bits being unused + (void) cached_has_bits; + + _extensions_.Clear(); + uninterpreted_option_.Clear(); + cached_has_bits = _has_bits_[0]; + if (cached_has_bits & 0x000000ffu) { + if (cached_has_bits & 0x00000001u) { + java_package_.ClearNonDefaultToEmpty(); + } + if (cached_has_bits & 0x00000002u) { + java_outer_classname_.ClearNonDefaultToEmpty(); + } + if (cached_has_bits & 0x00000004u) { + go_package_.ClearNonDefaultToEmpty(); + } + if (cached_has_bits & 0x00000008u) { + objc_class_prefix_.ClearNonDefaultToEmpty(); + } + if (cached_has_bits & 0x00000010u) { + csharp_namespace_.ClearNonDefaultToEmpty(); + } + if (cached_has_bits & 0x00000020u) { + swift_prefix_.ClearNonDefaultToEmpty(); + } + if (cached_has_bits & 0x00000040u) { + php_class_prefix_.ClearNonDefaultToEmpty(); + } + if (cached_has_bits & 0x00000080u) { + php_namespace_.ClearNonDefaultToEmpty(); + } + } + if (cached_has_bits & 0x00000300u) { + if (cached_has_bits & 0x00000100u) { + php_metadata_namespace_.ClearNonDefaultToEmpty(); + } + if (cached_has_bits & 0x00000200u) { + ruby_package_.ClearNonDefaultToEmpty(); + } + } + if (cached_has_bits & 0x0000fc00u) { + ::memset(&java_multiple_files_, 0, static_cast<size_t>( + reinterpret_cast<char*>(&py_generic_services_) - + reinterpret_cast<char*>(&java_multiple_files_)) + sizeof(py_generic_services_)); + } + if (cached_has_bits & 0x000f0000u) { + ::memset(&php_generic_services_, 0, static_cast<size_t>( + reinterpret_cast<char*>(&deprecated_) - + reinterpret_cast<char*>(&php_generic_services_)) + sizeof(deprecated_)); + optimize_for_ = 1; + cc_enable_arenas_ = true; + } + _has_bits_.Clear(); + _internal_metadata_.Clear<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(); +} + +const char* FileOptions::_InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) { +#define CHK_(x) if (PROTOBUF_PREDICT_FALSE(!(x))) goto failure + _Internal::HasBits has_bits{}; + while (!ctx->Done(&ptr)) { + arc_ui32 tag; + ptr = ::PROTOBUF_NAMESPACE_ID::internal::ReadTag(ptr, &tag); + switch (tag >> 3) { + // optional string java_package = 1; + case 1: + if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 10)) { + auto str = _internal_mutable_java_package(); + ptr = ::PROTOBUF_NAMESPACE_ID::internal::InlineGreedyStringParser(str, ptr, ctx); + #ifndef NDEBUG + ::PROTOBUF_NAMESPACE_ID::internal::VerifyUTF8(str, "google.protobuf.FileOptions.java_package"); + #endif // !NDEBUG + CHK_(ptr); + } else + goto handle_unusual; + continue; + // optional string java_outer_classname = 8; + case 8: + if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 66)) { + auto str = _internal_mutable_java_outer_classname(); + ptr = ::PROTOBUF_NAMESPACE_ID::internal::InlineGreedyStringParser(str, ptr, ctx); + #ifndef NDEBUG + ::PROTOBUF_NAMESPACE_ID::internal::VerifyUTF8(str, "google.protobuf.FileOptions.java_outer_classname"); + #endif // !NDEBUG + CHK_(ptr); + } else + goto handle_unusual; + continue; + // optional .google.protobuf.FileOptions.OptimizeMode optimize_for = 9 [default = SPEED]; + case 9: + if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 72)) { + arc_ui64 val = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint64(&ptr); + CHK_(ptr); + if (PROTOBUF_PREDICT_TRUE(::PROTOBUF_NAMESPACE_ID::FileOptions_OptimizeMode_IsValid(val))) { + _internal_set_optimize_for(static_cast<::PROTOBUF_NAMESPACE_ID::FileOptions_OptimizeMode>(val)); + } else { + ::PROTOBUF_NAMESPACE_ID::internal::WriteVarint(9, val, mutable_unknown_fields()); + } + } else + goto handle_unusual; + continue; + // optional bool java_multiple_files = 10 [default = false]; + case 10: + if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 80)) { + _Internal::set_has_java_multiple_files(&has_bits); + java_multiple_files_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint64(&ptr); + CHK_(ptr); + } else + goto handle_unusual; + continue; + // optional string go_package = 11; + case 11: + if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 90)) { + auto str = _internal_mutable_go_package(); + ptr = ::PROTOBUF_NAMESPACE_ID::internal::InlineGreedyStringParser(str, ptr, ctx); + #ifndef NDEBUG + ::PROTOBUF_NAMESPACE_ID::internal::VerifyUTF8(str, "google.protobuf.FileOptions.go_package"); + #endif // !NDEBUG + CHK_(ptr); + } else + goto handle_unusual; + continue; + // optional bool cc_generic_services = 16 [default = false]; + case 16: + if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 128)) { + _Internal::set_has_cc_generic_services(&has_bits); + cc_generic_services_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint64(&ptr); + CHK_(ptr); + } else + goto handle_unusual; + continue; + // optional bool java_generic_services = 17 [default = false]; + case 17: + if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 136)) { + _Internal::set_has_java_generic_services(&has_bits); + java_generic_services_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint64(&ptr); + CHK_(ptr); + } else + goto handle_unusual; + continue; + // optional bool py_generic_services = 18 [default = false]; + case 18: + if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 144)) { + _Internal::set_has_py_generic_services(&has_bits); + py_generic_services_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint64(&ptr); + CHK_(ptr); + } else + goto handle_unusual; + continue; + // optional bool java_generate_equals_and_hash = 20 [deprecated = true]; + case 20: + if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 160)) { + _Internal::set_has_java_generate_equals_and_hash(&has_bits); + java_generate_equals_and_hash_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint64(&ptr); + CHK_(ptr); + } else + goto handle_unusual; + continue; + // optional bool deprecated = 23 [default = false]; + case 23: + if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 184)) { + _Internal::set_has_deprecated(&has_bits); + deprecated_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint64(&ptr); + CHK_(ptr); + } else + goto handle_unusual; + continue; + // optional bool java_string_check_utf8 = 27 [default = false]; + case 27: + if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 216)) { + _Internal::set_has_java_string_check_utf8(&has_bits); + java_string_check_utf8_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint64(&ptr); + CHK_(ptr); + } else + goto handle_unusual; + continue; + // optional bool cc_enable_arenas = 31 [default = true]; + case 31: + if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 248)) { + _Internal::set_has_cc_enable_arenas(&has_bits); + cc_enable_arenas_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint64(&ptr); + CHK_(ptr); + } else + goto handle_unusual; + continue; + // optional string objc_class_prefix = 36; + case 36: + if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 34)) { + auto str = _internal_mutable_objc_class_prefix(); + ptr = ::PROTOBUF_NAMESPACE_ID::internal::InlineGreedyStringParser(str, ptr, ctx); + #ifndef NDEBUG + ::PROTOBUF_NAMESPACE_ID::internal::VerifyUTF8(str, "google.protobuf.FileOptions.objc_class_prefix"); + #endif // !NDEBUG + CHK_(ptr); + } else + goto handle_unusual; + continue; + // optional string csharp_namespace = 37; + case 37: + if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 42)) { + auto str = _internal_mutable_csharp_namespace(); + ptr = ::PROTOBUF_NAMESPACE_ID::internal::InlineGreedyStringParser(str, ptr, ctx); + #ifndef NDEBUG + ::PROTOBUF_NAMESPACE_ID::internal::VerifyUTF8(str, "google.protobuf.FileOptions.csharp_namespace"); + #endif // !NDEBUG + CHK_(ptr); + } else + goto handle_unusual; + continue; + // optional string swift_prefix = 39; + case 39: + if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 58)) { + auto str = _internal_mutable_swift_prefix(); + ptr = ::PROTOBUF_NAMESPACE_ID::internal::InlineGreedyStringParser(str, ptr, ctx); + #ifndef NDEBUG + ::PROTOBUF_NAMESPACE_ID::internal::VerifyUTF8(str, "google.protobuf.FileOptions.swift_prefix"); + #endif // !NDEBUG + CHK_(ptr); + } else + goto handle_unusual; + continue; + // optional string php_class_prefix = 40; + case 40: + if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 66)) { + auto str = _internal_mutable_php_class_prefix(); + ptr = ::PROTOBUF_NAMESPACE_ID::internal::InlineGreedyStringParser(str, ptr, ctx); + #ifndef NDEBUG + ::PROTOBUF_NAMESPACE_ID::internal::VerifyUTF8(str, "google.protobuf.FileOptions.php_class_prefix"); + #endif // !NDEBUG + CHK_(ptr); + } else + goto handle_unusual; + continue; + // optional string php_namespace = 41; + case 41: + if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 74)) { + auto str = _internal_mutable_php_namespace(); + ptr = ::PROTOBUF_NAMESPACE_ID::internal::InlineGreedyStringParser(str, ptr, ctx); + #ifndef NDEBUG + ::PROTOBUF_NAMESPACE_ID::internal::VerifyUTF8(str, "google.protobuf.FileOptions.php_namespace"); + #endif // !NDEBUG + CHK_(ptr); + } else + goto handle_unusual; + continue; + // optional bool php_generic_services = 42 [default = false]; + case 42: + if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 80)) { + _Internal::set_has_php_generic_services(&has_bits); + php_generic_services_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint64(&ptr); + CHK_(ptr); + } else + goto handle_unusual; + continue; + // optional string php_metadata_namespace = 44; + case 44: + if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 98)) { + auto str = _internal_mutable_php_metadata_namespace(); + ptr = ::PROTOBUF_NAMESPACE_ID::internal::InlineGreedyStringParser(str, ptr, ctx); + #ifndef NDEBUG + ::PROTOBUF_NAMESPACE_ID::internal::VerifyUTF8(str, "google.protobuf.FileOptions.php_metadata_namespace"); + #endif // !NDEBUG + CHK_(ptr); + } else + goto handle_unusual; + continue; + // optional string ruby_package = 45; + case 45: + if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 106)) { + auto str = _internal_mutable_ruby_package(); + ptr = ::PROTOBUF_NAMESPACE_ID::internal::InlineGreedyStringParser(str, ptr, ctx); + #ifndef NDEBUG + ::PROTOBUF_NAMESPACE_ID::internal::VerifyUTF8(str, "google.protobuf.FileOptions.ruby_package"); + #endif // !NDEBUG + CHK_(ptr); + } else + goto handle_unusual; + continue; + // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999; + case 999: + if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 58)) { + ptr -= 2; + do { + ptr += 2; + ptr = ctx->ParseMessage(_internal_add_uninterpreted_option(), ptr); + CHK_(ptr); + if (!ctx->DataAvailable(ptr)) break; + } while (::PROTOBUF_NAMESPACE_ID::internal::ExpectTag<7994>(ptr)); + } else + goto handle_unusual; + continue; + default: + goto handle_unusual; + } // switch + handle_unusual: + if ((tag == 0) || ((tag & 7) == 4)) { + CHK_(ptr); + ctx->SetLastTag(tag); + goto message_done; + } + if ((8000u <= tag)) { + ptr = _extensions_.ParseField(tag, ptr, internal_default_instance(), &_internal_metadata_, ctx); + CHK_(ptr != nullptr); + continue; + } + ptr = UnknownFieldParse( + tag, + _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(), + ptr, ctx); + CHK_(ptr != nullptr); + } // while +message_done: + _has_bits_.Or(has_bits); + return ptr; +failure: + ptr = nullptr; + goto message_done; +#undef CHK_ +} + +uint8_t* FileOptions::_InternalSerialize( + uint8_t* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const { + // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.FileOptions) + arc_ui32 cached_has_bits = 0; + (void) cached_has_bits; + + cached_has_bits = _has_bits_[0]; + // optional string java_package = 1; + if (cached_has_bits & 0x00000001u) { + ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::VerifyUTF8StringNamedField( + this->_internal_java_package().data(), static_cast<int>(this->_internal_java_package().length()), + ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::SERIALIZE, + "google.protobuf.FileOptions.java_package"); + target = stream->WriteStringMaybeAliased( + 1, this->_internal_java_package(), target); + } + + // optional string java_outer_classname = 8; + if (cached_has_bits & 0x00000002u) { + ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::VerifyUTF8StringNamedField( + this->_internal_java_outer_classname().data(), static_cast<int>(this->_internal_java_outer_classname().length()), + ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::SERIALIZE, + "google.protobuf.FileOptions.java_outer_classname"); + target = stream->WriteStringMaybeAliased( + 8, this->_internal_java_outer_classname(), target); + } + + // optional .google.protobuf.FileOptions.OptimizeMode optimize_for = 9 [default = SPEED]; + if (cached_has_bits & 0x00040000u) { + target = stream->EnsureSpace(target); + target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteEnumToArray( + 9, this->_internal_optimize_for(), target); + } + + // optional bool java_multiple_files = 10 [default = false]; + if (cached_has_bits & 0x00000400u) { + target = stream->EnsureSpace(target); + target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteBoolToArray(10, this->_internal_java_multiple_files(), target); + } + + // optional string go_package = 11; + if (cached_has_bits & 0x00000004u) { + ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::VerifyUTF8StringNamedField( + this->_internal_go_package().data(), static_cast<int>(this->_internal_go_package().length()), + ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::SERIALIZE, + "google.protobuf.FileOptions.go_package"); + target = stream->WriteStringMaybeAliased( + 11, this->_internal_go_package(), target); + } + + // optional bool cc_generic_services = 16 [default = false]; + if (cached_has_bits & 0x00002000u) { + target = stream->EnsureSpace(target); + target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteBoolToArray(16, this->_internal_cc_generic_services(), target); + } + + // optional bool java_generic_services = 17 [default = false]; + if (cached_has_bits & 0x00004000u) { + target = stream->EnsureSpace(target); + target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteBoolToArray(17, this->_internal_java_generic_services(), target); + } + + // optional bool py_generic_services = 18 [default = false]; + if (cached_has_bits & 0x00008000u) { + target = stream->EnsureSpace(target); + target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteBoolToArray(18, this->_internal_py_generic_services(), target); + } + + // optional bool java_generate_equals_and_hash = 20 [deprecated = true]; + if (cached_has_bits & 0x00000800u) { + target = stream->EnsureSpace(target); + target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteBoolToArray(20, this->_internal_java_generate_equals_and_hash(), target); + } + + // optional bool deprecated = 23 [default = false]; + if (cached_has_bits & 0x00020000u) { + target = stream->EnsureSpace(target); + target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteBoolToArray(23, this->_internal_deprecated(), target); + } + + // optional bool java_string_check_utf8 = 27 [default = false]; + if (cached_has_bits & 0x00001000u) { + target = stream->EnsureSpace(target); + target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteBoolToArray(27, this->_internal_java_string_check_utf8(), target); + } + + // optional bool cc_enable_arenas = 31 [default = true]; + if (cached_has_bits & 0x00080000u) { + target = stream->EnsureSpace(target); + target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteBoolToArray(31, this->_internal_cc_enable_arenas(), target); + } + + // optional string objc_class_prefix = 36; + if (cached_has_bits & 0x00000008u) { + ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::VerifyUTF8StringNamedField( + this->_internal_objc_class_prefix().data(), static_cast<int>(this->_internal_objc_class_prefix().length()), + ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::SERIALIZE, + "google.protobuf.FileOptions.objc_class_prefix"); + target = stream->WriteStringMaybeAliased( + 36, this->_internal_objc_class_prefix(), target); + } + + // optional string csharp_namespace = 37; + if (cached_has_bits & 0x00000010u) { + ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::VerifyUTF8StringNamedField( + this->_internal_csharp_namespace().data(), static_cast<int>(this->_internal_csharp_namespace().length()), + ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::SERIALIZE, + "google.protobuf.FileOptions.csharp_namespace"); + target = stream->WriteStringMaybeAliased( + 37, this->_internal_csharp_namespace(), target); + } + + // optional string swift_prefix = 39; + if (cached_has_bits & 0x00000020u) { + ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::VerifyUTF8StringNamedField( + this->_internal_swift_prefix().data(), static_cast<int>(this->_internal_swift_prefix().length()), + ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::SERIALIZE, + "google.protobuf.FileOptions.swift_prefix"); + target = stream->WriteStringMaybeAliased( + 39, this->_internal_swift_prefix(), target); + } + + // optional string php_class_prefix = 40; + if (cached_has_bits & 0x00000040u) { + ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::VerifyUTF8StringNamedField( + this->_internal_php_class_prefix().data(), static_cast<int>(this->_internal_php_class_prefix().length()), + ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::SERIALIZE, + "google.protobuf.FileOptions.php_class_prefix"); + target = stream->WriteStringMaybeAliased( + 40, this->_internal_php_class_prefix(), target); + } + + // optional string php_namespace = 41; + if (cached_has_bits & 0x00000080u) { + ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::VerifyUTF8StringNamedField( + this->_internal_php_namespace().data(), static_cast<int>(this->_internal_php_namespace().length()), + ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::SERIALIZE, + "google.protobuf.FileOptions.php_namespace"); + target = stream->WriteStringMaybeAliased( + 41, this->_internal_php_namespace(), target); + } + + // optional bool php_generic_services = 42 [default = false]; + if (cached_has_bits & 0x00010000u) { + target = stream->EnsureSpace(target); + target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteBoolToArray(42, this->_internal_php_generic_services(), target); + } + + // optional string php_metadata_namespace = 44; + if (cached_has_bits & 0x00000100u) { + ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::VerifyUTF8StringNamedField( + this->_internal_php_metadata_namespace().data(), static_cast<int>(this->_internal_php_metadata_namespace().length()), + ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::SERIALIZE, + "google.protobuf.FileOptions.php_metadata_namespace"); + target = stream->WriteStringMaybeAliased( + 44, this->_internal_php_metadata_namespace(), target); + } + + // optional string ruby_package = 45; + if (cached_has_bits & 0x00000200u) { + ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::VerifyUTF8StringNamedField( + this->_internal_ruby_package().data(), static_cast<int>(this->_internal_ruby_package().length()), + ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::SERIALIZE, + "google.protobuf.FileOptions.ruby_package"); + target = stream->WriteStringMaybeAliased( + 45, this->_internal_ruby_package(), target); + } + + // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999; + for (unsigned int i = 0, + n = static_cast<unsigned int>(this->_internal_uninterpreted_option_size()); i < n; i++) { + target = stream->EnsureSpace(target); + target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite:: + InternalWriteMessage(999, this->_internal_uninterpreted_option(i), target, stream); + } + + // Extension range [1000, 536870912) + target = _extensions_._InternalSerialize( + internal_default_instance(), 1000, 536870912, target, stream); + + if (PROTOBUF_PREDICT_FALSE(_internal_metadata_.have_unknown_fields())) { + target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::InternalSerializeUnknownFieldsToArray( + _internal_metadata_.unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(::PROTOBUF_NAMESPACE_ID::UnknownFieldSet::default_instance), target, stream); + } + // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.FileOptions) + return target; +} + +size_t FileOptions::ByteSizeLong() const { +// @@protoc_insertion_point(message_byte_size_start:google.protobuf.FileOptions) + size_t total_size = 0; + + total_size += _extensions_.ByteSize(); + + arc_ui32 cached_has_bits = 0; + // Prevent compiler warnings about cached_has_bits being unused + (void) cached_has_bits; + + // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999; + total_size += 2UL * this->_internal_uninterpreted_option_size(); + for (const auto& msg : this->uninterpreted_option_) { + total_size += + ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::MessageSize(msg); + } + + cached_has_bits = _has_bits_[0]; + if (cached_has_bits & 0x000000ffu) { + // optional string java_package = 1; + if (cached_has_bits & 0x00000001u) { + total_size += 1 + + ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::StringSize( + this->_internal_java_package()); + } + + // optional string java_outer_classname = 8; + if (cached_has_bits & 0x00000002u) { + total_size += 1 + + ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::StringSize( + this->_internal_java_outer_classname()); + } + + // optional string go_package = 11; + if (cached_has_bits & 0x00000004u) { + total_size += 1 + + ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::StringSize( + this->_internal_go_package()); + } + + // optional string objc_class_prefix = 36; + if (cached_has_bits & 0x00000008u) { + total_size += 2 + + ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::StringSize( + this->_internal_objc_class_prefix()); + } + + // optional string csharp_namespace = 37; + if (cached_has_bits & 0x00000010u) { + total_size += 2 + + ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::StringSize( + this->_internal_csharp_namespace()); + } + + // optional string swift_prefix = 39; + if (cached_has_bits & 0x00000020u) { + total_size += 2 + + ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::StringSize( + this->_internal_swift_prefix()); + } + + // optional string php_class_prefix = 40; + if (cached_has_bits & 0x00000040u) { + total_size += 2 + + ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::StringSize( + this->_internal_php_class_prefix()); + } + + // optional string php_namespace = 41; + if (cached_has_bits & 0x00000080u) { + total_size += 2 + + ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::StringSize( + this->_internal_php_namespace()); + } + + } + if (cached_has_bits & 0x0000ff00u) { + // optional string php_metadata_namespace = 44; + if (cached_has_bits & 0x00000100u) { + total_size += 2 + + ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::StringSize( + this->_internal_php_metadata_namespace()); + } + + // optional string ruby_package = 45; + if (cached_has_bits & 0x00000200u) { + total_size += 2 + + ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::StringSize( + this->_internal_ruby_package()); + } + + // optional bool java_multiple_files = 10 [default = false]; + if (cached_has_bits & 0x00000400u) { + total_size += 1 + 1; + } + + // optional bool java_generate_equals_and_hash = 20 [deprecated = true]; + if (cached_has_bits & 0x00000800u) { + total_size += 2 + 1; + } + + // optional bool java_string_check_utf8 = 27 [default = false]; + if (cached_has_bits & 0x00001000u) { + total_size += 2 + 1; + } + + // optional bool cc_generic_services = 16 [default = false]; + if (cached_has_bits & 0x00002000u) { + total_size += 2 + 1; + } + + // optional bool java_generic_services = 17 [default = false]; + if (cached_has_bits & 0x00004000u) { + total_size += 2 + 1; + } + + // optional bool py_generic_services = 18 [default = false]; + if (cached_has_bits & 0x00008000u) { + total_size += 2 + 1; + } + + } + if (cached_has_bits & 0x000f0000u) { + // optional bool php_generic_services = 42 [default = false]; + if (cached_has_bits & 0x00010000u) { + total_size += 2 + 1; + } + + // optional bool deprecated = 23 [default = false]; + if (cached_has_bits & 0x00020000u) { + total_size += 2 + 1; + } + + // optional .google.protobuf.FileOptions.OptimizeMode optimize_for = 9 [default = SPEED]; + if (cached_has_bits & 0x00040000u) { + total_size += 1 + + ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::EnumSize(this->_internal_optimize_for()); + } + + // optional bool cc_enable_arenas = 31 [default = true]; + if (cached_has_bits & 0x00080000u) { + total_size += 2 + 1; + } + + } + return MaybeComputeUnknownFieldsSize(total_size, &_cached_size_); +} + +const ::PROTOBUF_NAMESPACE_ID::Message::ClassData FileOptions::_class_data_ = { + ::PROTOBUF_NAMESPACE_ID::Message::CopyWithSizeCheck, + FileOptions::MergeImpl +}; +const ::PROTOBUF_NAMESPACE_ID::Message::ClassData*FileOptions::GetClassData() const { return &_class_data_; } + +void FileOptions::MergeImpl(::PROTOBUF_NAMESPACE_ID::Message* to, + const ::PROTOBUF_NAMESPACE_ID::Message& from) { + static_cast<FileOptions *>(to)->MergeFrom( + static_cast<const FileOptions &>(from)); +} + + +void FileOptions::MergeFrom(const FileOptions& from) { +// @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.FileOptions) + GOOGLE_DCHECK_NE(&from, this); + arc_ui32 cached_has_bits = 0; + (void) cached_has_bits; + + uninterpreted_option_.MergeFrom(from.uninterpreted_option_); + cached_has_bits = from._has_bits_[0]; + if (cached_has_bits & 0x000000ffu) { + if (cached_has_bits & 0x00000001u) { + _internal_set_java_package(from._internal_java_package()); + } + if (cached_has_bits & 0x00000002u) { + _internal_set_java_outer_classname(from._internal_java_outer_classname()); + } + if (cached_has_bits & 0x00000004u) { + _internal_set_go_package(from._internal_go_package()); + } + if (cached_has_bits & 0x00000008u) { + _internal_set_objc_class_prefix(from._internal_objc_class_prefix()); + } + if (cached_has_bits & 0x00000010u) { + _internal_set_csharp_namespace(from._internal_csharp_namespace()); + } + if (cached_has_bits & 0x00000020u) { + _internal_set_swift_prefix(from._internal_swift_prefix()); + } + if (cached_has_bits & 0x00000040u) { + _internal_set_php_class_prefix(from._internal_php_class_prefix()); + } + if (cached_has_bits & 0x00000080u) { + _internal_set_php_namespace(from._internal_php_namespace()); + } + } + if (cached_has_bits & 0x0000ff00u) { + if (cached_has_bits & 0x00000100u) { + _internal_set_php_metadata_namespace(from._internal_php_metadata_namespace()); + } + if (cached_has_bits & 0x00000200u) { + _internal_set_ruby_package(from._internal_ruby_package()); + } + if (cached_has_bits & 0x00000400u) { + java_multiple_files_ = from.java_multiple_files_; + } + if (cached_has_bits & 0x00000800u) { + java_generate_equals_and_hash_ = from.java_generate_equals_and_hash_; + } + if (cached_has_bits & 0x00001000u) { + java_string_check_utf8_ = from.java_string_check_utf8_; + } + if (cached_has_bits & 0x00002000u) { + cc_generic_services_ = from.cc_generic_services_; + } + if (cached_has_bits & 0x00004000u) { + java_generic_services_ = from.java_generic_services_; + } + if (cached_has_bits & 0x00008000u) { + py_generic_services_ = from.py_generic_services_; + } + _has_bits_[0] |= cached_has_bits; + } + if (cached_has_bits & 0x000f0000u) { + if (cached_has_bits & 0x00010000u) { + php_generic_services_ = from.php_generic_services_; + } + if (cached_has_bits & 0x00020000u) { + deprecated_ = from.deprecated_; + } + if (cached_has_bits & 0x00040000u) { + optimize_for_ = from.optimize_for_; + } + if (cached_has_bits & 0x00080000u) { + cc_enable_arenas_ = from.cc_enable_arenas_; + } + _has_bits_[0] |= cached_has_bits; + } + _extensions_.MergeFrom(internal_default_instance(), from._extensions_); + _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_); +} + +void FileOptions::CopyFrom(const FileOptions& from) { +// @@protoc_insertion_point(class_specific_copy_from_start:google.protobuf.FileOptions) + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool FileOptions::IsInitialized() const { + if (!_extensions_.IsInitialized()) { + return false; + } + + if (!::PROTOBUF_NAMESPACE_ID::internal::AllAreInitialized(uninterpreted_option_)) + return false; + return true; +} + +void FileOptions::InternalSwap(FileOptions* other) { + using std::swap; + _extensions_.InternalSwap(&other->_extensions_); + auto* lhs_arena = GetArenaForAllocation(); + auto* rhs_arena = other->GetArenaForAllocation(); + _internal_metadata_.InternalSwap(&other->_internal_metadata_); + swap(_has_bits_[0], other->_has_bits_[0]); + uninterpreted_option_.InternalSwap(&other->uninterpreted_option_); + ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::InternalSwap( + &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), + &java_package_, lhs_arena, + &other->java_package_, rhs_arena + ); + ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::InternalSwap( + &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), + &java_outer_classname_, lhs_arena, + &other->java_outer_classname_, rhs_arena + ); + ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::InternalSwap( + &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), + &go_package_, lhs_arena, + &other->go_package_, rhs_arena + ); + ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::InternalSwap( + &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), + &objc_class_prefix_, lhs_arena, + &other->objc_class_prefix_, rhs_arena + ); + ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::InternalSwap( + &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), + &csharp_namespace_, lhs_arena, + &other->csharp_namespace_, rhs_arena + ); + ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::InternalSwap( + &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), + &swift_prefix_, lhs_arena, + &other->swift_prefix_, rhs_arena + ); + ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::InternalSwap( + &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), + &php_class_prefix_, lhs_arena, + &other->php_class_prefix_, rhs_arena + ); + ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::InternalSwap( + &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), + &php_namespace_, lhs_arena, + &other->php_namespace_, rhs_arena + ); + ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::InternalSwap( + &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), + &php_metadata_namespace_, lhs_arena, + &other->php_metadata_namespace_, rhs_arena + ); + ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::InternalSwap( + &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), + &ruby_package_, lhs_arena, + &other->ruby_package_, rhs_arena + ); + ::PROTOBUF_NAMESPACE_ID::internal::memswap< + PROTOBUF_FIELD_OFFSET(FileOptions, deprecated_) + + sizeof(FileOptions::deprecated_) + - PROTOBUF_FIELD_OFFSET(FileOptions, java_multiple_files_)>( + reinterpret_cast<char*>(&java_multiple_files_), + reinterpret_cast<char*>(&other->java_multiple_files_)); + swap(optimize_for_, other->optimize_for_); + swap(cc_enable_arenas_, other->cc_enable_arenas_); +} + +::PROTOBUF_NAMESPACE_ID::Metadata FileOptions::GetMetadata() const { + return ::PROTOBUF_NAMESPACE_ID::internal::AssignDescriptors( + &descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_getter, &descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_once, + file_level_metadata_google_2fprotobuf_2fdescriptor_2eproto[13]); +} + +// =================================================================== + +class MessageOptions::_Internal { + public: + using HasBits = decltype(std::declval<MessageOptions>()._has_bits_); + static void set_has_message_set_wire_format(HasBits* has_bits) { + (*has_bits)[0] |= 1u; + } + static void set_has_no_standard_descriptor_accessor(HasBits* has_bits) { + (*has_bits)[0] |= 2u; + } + static void set_has_deprecated(HasBits* has_bits) { + (*has_bits)[0] |= 4u; + } + static void set_has_map_entry(HasBits* has_bits) { + (*has_bits)[0] |= 8u; + } +}; + +MessageOptions::MessageOptions(::PROTOBUF_NAMESPACE_ID::Arena* arena, + bool is_message_owned) + : ::PROTOBUF_NAMESPACE_ID::Message(arena, is_message_owned), + _extensions_(arena), + uninterpreted_option_(arena) { + SharedCtor(); + if (!is_message_owned) { + RegisterArenaDtor(arena); + } + // @@protoc_insertion_point(arena_constructor:google.protobuf.MessageOptions) +} +MessageOptions::MessageOptions(const MessageOptions& from) + : ::PROTOBUF_NAMESPACE_ID::Message(), + _has_bits_(from._has_bits_), + uninterpreted_option_(from.uninterpreted_option_) { + _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_); + _extensions_.MergeFrom(internal_default_instance(), from._extensions_); + ::memcpy(&message_set_wire_format_, &from.message_set_wire_format_, + static_cast<size_t>(reinterpret_cast<char*>(&map_entry_) - + reinterpret_cast<char*>(&message_set_wire_format_)) + sizeof(map_entry_)); + // @@protoc_insertion_point(copy_constructor:google.protobuf.MessageOptions) +} + +inline void MessageOptions::SharedCtor() { +::memset(reinterpret_cast<char*>(this) + static_cast<size_t>( + reinterpret_cast<char*>(&message_set_wire_format_) - reinterpret_cast<char*>(this)), + 0, static_cast<size_t>(reinterpret_cast<char*>(&map_entry_) - + reinterpret_cast<char*>(&message_set_wire_format_)) + sizeof(map_entry_)); +} + +MessageOptions::~MessageOptions() { + // @@protoc_insertion_point(destructor:google.protobuf.MessageOptions) + if (GetArenaForAllocation() != nullptr) return; + SharedDtor(); + _internal_metadata_.Delete<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(); +} + +inline void MessageOptions::SharedDtor() { + GOOGLE_DCHECK(GetArenaForAllocation() == nullptr); +} + +void MessageOptions::ArenaDtor(void* object) { + MessageOptions* _this = reinterpret_cast< MessageOptions* >(object); + (void)_this; +} +void MessageOptions::RegisterArenaDtor(::PROTOBUF_NAMESPACE_ID::Arena*) { +} +void MessageOptions::SetCachedSize(int size) const { + _cached_size_.Set(size); +} + +void MessageOptions::Clear() { +// @@protoc_insertion_point(message_clear_start:google.protobuf.MessageOptions) + arc_ui32 cached_has_bits = 0; + // Prevent compiler warnings about cached_has_bits being unused + (void) cached_has_bits; + + _extensions_.Clear(); + uninterpreted_option_.Clear(); + ::memset(&message_set_wire_format_, 0, static_cast<size_t>( + reinterpret_cast<char*>(&map_entry_) - + reinterpret_cast<char*>(&message_set_wire_format_)) + sizeof(map_entry_)); + _has_bits_.Clear(); + _internal_metadata_.Clear<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(); +} + +const char* MessageOptions::_InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) { +#define CHK_(x) if (PROTOBUF_PREDICT_FALSE(!(x))) goto failure + _Internal::HasBits has_bits{}; + while (!ctx->Done(&ptr)) { + arc_ui32 tag; + ptr = ::PROTOBUF_NAMESPACE_ID::internal::ReadTag(ptr, &tag); + switch (tag >> 3) { + // optional bool message_set_wire_format = 1 [default = false]; + case 1: + if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 8)) { + _Internal::set_has_message_set_wire_format(&has_bits); + message_set_wire_format_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint64(&ptr); + CHK_(ptr); + } else + goto handle_unusual; + continue; + // optional bool no_standard_descriptor_accessor = 2 [default = false]; + case 2: + if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 16)) { + _Internal::set_has_no_standard_descriptor_accessor(&has_bits); + no_standard_descriptor_accessor_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint64(&ptr); + CHK_(ptr); + } else + goto handle_unusual; + continue; + // optional bool deprecated = 3 [default = false]; + case 3: + if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 24)) { + _Internal::set_has_deprecated(&has_bits); + deprecated_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint64(&ptr); + CHK_(ptr); + } else + goto handle_unusual; + continue; + // optional bool map_entry = 7; + case 7: + if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 56)) { + _Internal::set_has_map_entry(&has_bits); + map_entry_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint64(&ptr); + CHK_(ptr); + } else + goto handle_unusual; + continue; + // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999; + case 999: + if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 58)) { + ptr -= 2; + do { + ptr += 2; + ptr = ctx->ParseMessage(_internal_add_uninterpreted_option(), ptr); + CHK_(ptr); + if (!ctx->DataAvailable(ptr)) break; + } while (::PROTOBUF_NAMESPACE_ID::internal::ExpectTag<7994>(ptr)); + } else + goto handle_unusual; + continue; + default: + goto handle_unusual; + } // switch + handle_unusual: + if ((tag == 0) || ((tag & 7) == 4)) { + CHK_(ptr); + ctx->SetLastTag(tag); + goto message_done; + } + if ((8000u <= tag)) { + ptr = _extensions_.ParseField(tag, ptr, internal_default_instance(), &_internal_metadata_, ctx); + CHK_(ptr != nullptr); + continue; + } + ptr = UnknownFieldParse( + tag, + _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(), + ptr, ctx); + CHK_(ptr != nullptr); + } // while +message_done: + _has_bits_.Or(has_bits); + return ptr; +failure: + ptr = nullptr; + goto message_done; +#undef CHK_ +} + +uint8_t* MessageOptions::_InternalSerialize( + uint8_t* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const { + // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.MessageOptions) + arc_ui32 cached_has_bits = 0; + (void) cached_has_bits; + + cached_has_bits = _has_bits_[0]; + // optional bool message_set_wire_format = 1 [default = false]; + if (cached_has_bits & 0x00000001u) { + target = stream->EnsureSpace(target); + target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteBoolToArray(1, this->_internal_message_set_wire_format(), target); + } + + // optional bool no_standard_descriptor_accessor = 2 [default = false]; + if (cached_has_bits & 0x00000002u) { + target = stream->EnsureSpace(target); + target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteBoolToArray(2, this->_internal_no_standard_descriptor_accessor(), target); + } + + // optional bool deprecated = 3 [default = false]; + if (cached_has_bits & 0x00000004u) { + target = stream->EnsureSpace(target); + target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteBoolToArray(3, this->_internal_deprecated(), target); + } + + // optional bool map_entry = 7; + if (cached_has_bits & 0x00000008u) { + target = stream->EnsureSpace(target); + target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteBoolToArray(7, this->_internal_map_entry(), target); + } + + // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999; + for (unsigned int i = 0, + n = static_cast<unsigned int>(this->_internal_uninterpreted_option_size()); i < n; i++) { + target = stream->EnsureSpace(target); + target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite:: + InternalWriteMessage(999, this->_internal_uninterpreted_option(i), target, stream); + } + + // Extension range [1000, 536870912) + target = _extensions_._InternalSerialize( + internal_default_instance(), 1000, 536870912, target, stream); + + if (PROTOBUF_PREDICT_FALSE(_internal_metadata_.have_unknown_fields())) { + target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::InternalSerializeUnknownFieldsToArray( + _internal_metadata_.unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(::PROTOBUF_NAMESPACE_ID::UnknownFieldSet::default_instance), target, stream); + } + // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.MessageOptions) + return target; +} + +size_t MessageOptions::ByteSizeLong() const { +// @@protoc_insertion_point(message_byte_size_start:google.protobuf.MessageOptions) + size_t total_size = 0; + + total_size += _extensions_.ByteSize(); + + arc_ui32 cached_has_bits = 0; + // Prevent compiler warnings about cached_has_bits being unused + (void) cached_has_bits; + + // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999; + total_size += 2UL * this->_internal_uninterpreted_option_size(); + for (const auto& msg : this->uninterpreted_option_) { + total_size += + ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::MessageSize(msg); + } + + cached_has_bits = _has_bits_[0]; + if (cached_has_bits & 0x0000000fu) { + // optional bool message_set_wire_format = 1 [default = false]; + if (cached_has_bits & 0x00000001u) { + total_size += 1 + 1; + } + + // optional bool no_standard_descriptor_accessor = 2 [default = false]; + if (cached_has_bits & 0x00000002u) { + total_size += 1 + 1; + } + + // optional bool deprecated = 3 [default = false]; + if (cached_has_bits & 0x00000004u) { + total_size += 1 + 1; + } + + // optional bool map_entry = 7; + if (cached_has_bits & 0x00000008u) { + total_size += 1 + 1; + } + + } + return MaybeComputeUnknownFieldsSize(total_size, &_cached_size_); +} + +const ::PROTOBUF_NAMESPACE_ID::Message::ClassData MessageOptions::_class_data_ = { + ::PROTOBUF_NAMESPACE_ID::Message::CopyWithSizeCheck, + MessageOptions::MergeImpl +}; +const ::PROTOBUF_NAMESPACE_ID::Message::ClassData*MessageOptions::GetClassData() const { return &_class_data_; } + +void MessageOptions::MergeImpl(::PROTOBUF_NAMESPACE_ID::Message* to, + const ::PROTOBUF_NAMESPACE_ID::Message& from) { + static_cast<MessageOptions *>(to)->MergeFrom( + static_cast<const MessageOptions &>(from)); +} + + +void MessageOptions::MergeFrom(const MessageOptions& from) { +// @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.MessageOptions) + GOOGLE_DCHECK_NE(&from, this); + arc_ui32 cached_has_bits = 0; + (void) cached_has_bits; + + uninterpreted_option_.MergeFrom(from.uninterpreted_option_); + cached_has_bits = from._has_bits_[0]; + if (cached_has_bits & 0x0000000fu) { + if (cached_has_bits & 0x00000001u) { + message_set_wire_format_ = from.message_set_wire_format_; + } + if (cached_has_bits & 0x00000002u) { + no_standard_descriptor_accessor_ = from.no_standard_descriptor_accessor_; + } + if (cached_has_bits & 0x00000004u) { + deprecated_ = from.deprecated_; + } + if (cached_has_bits & 0x00000008u) { + map_entry_ = from.map_entry_; + } + _has_bits_[0] |= cached_has_bits; + } + _extensions_.MergeFrom(internal_default_instance(), from._extensions_); + _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_); +} + +void MessageOptions::CopyFrom(const MessageOptions& from) { +// @@protoc_insertion_point(class_specific_copy_from_start:google.protobuf.MessageOptions) + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool MessageOptions::IsInitialized() const { + if (!_extensions_.IsInitialized()) { + return false; + } + + if (!::PROTOBUF_NAMESPACE_ID::internal::AllAreInitialized(uninterpreted_option_)) + return false; + return true; +} + +void MessageOptions::InternalSwap(MessageOptions* other) { + using std::swap; + _extensions_.InternalSwap(&other->_extensions_); + _internal_metadata_.InternalSwap(&other->_internal_metadata_); + swap(_has_bits_[0], other->_has_bits_[0]); + uninterpreted_option_.InternalSwap(&other->uninterpreted_option_); + ::PROTOBUF_NAMESPACE_ID::internal::memswap< + PROTOBUF_FIELD_OFFSET(MessageOptions, map_entry_) + + sizeof(MessageOptions::map_entry_) + - PROTOBUF_FIELD_OFFSET(MessageOptions, message_set_wire_format_)>( + reinterpret_cast<char*>(&message_set_wire_format_), + reinterpret_cast<char*>(&other->message_set_wire_format_)); +} + +::PROTOBUF_NAMESPACE_ID::Metadata MessageOptions::GetMetadata() const { + return ::PROTOBUF_NAMESPACE_ID::internal::AssignDescriptors( + &descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_getter, &descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_once, + file_level_metadata_google_2fprotobuf_2fdescriptor_2eproto[14]); +} + +// =================================================================== + +class FieldOptions::_Internal { + public: + using HasBits = decltype(std::declval<FieldOptions>()._has_bits_); + static void set_has_ctype(HasBits* has_bits) { + (*has_bits)[0] |= 1u; + } + static void set_has_packed(HasBits* has_bits) { + (*has_bits)[0] |= 2u; + } + static void set_has_jstype(HasBits* has_bits) { + (*has_bits)[0] |= 32u; + } + static void set_has_lazy(HasBits* has_bits) { + (*has_bits)[0] |= 4u; + } + static void set_has_deprecated(HasBits* has_bits) { + (*has_bits)[0] |= 8u; + } + static void set_has_weak(HasBits* has_bits) { + (*has_bits)[0] |= 16u; + } +}; + +FieldOptions::FieldOptions(::PROTOBUF_NAMESPACE_ID::Arena* arena, + bool is_message_owned) + : ::PROTOBUF_NAMESPACE_ID::Message(arena, is_message_owned), + _extensions_(arena), + uninterpreted_option_(arena) { + SharedCtor(); + if (!is_message_owned) { + RegisterArenaDtor(arena); + } + // @@protoc_insertion_point(arena_constructor:google.protobuf.FieldOptions) +} +FieldOptions::FieldOptions(const FieldOptions& from) + : ::PROTOBUF_NAMESPACE_ID::Message(), + _has_bits_(from._has_bits_), + uninterpreted_option_(from.uninterpreted_option_) { + _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_); + _extensions_.MergeFrom(internal_default_instance(), from._extensions_); + ::memcpy(&ctype_, &from.ctype_, + static_cast<size_t>(reinterpret_cast<char*>(&jstype_) - + reinterpret_cast<char*>(&ctype_)) + sizeof(jstype_)); + // @@protoc_insertion_point(copy_constructor:google.protobuf.FieldOptions) +} + +inline void FieldOptions::SharedCtor() { +::memset(reinterpret_cast<char*>(this) + static_cast<size_t>( + reinterpret_cast<char*>(&ctype_) - reinterpret_cast<char*>(this)), + 0, static_cast<size_t>(reinterpret_cast<char*>(&jstype_) - + reinterpret_cast<char*>(&ctype_)) + sizeof(jstype_)); +} + +FieldOptions::~FieldOptions() { + // @@protoc_insertion_point(destructor:google.protobuf.FieldOptions) + if (GetArenaForAllocation() != nullptr) return; + SharedDtor(); + _internal_metadata_.Delete<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(); +} + +inline void FieldOptions::SharedDtor() { + GOOGLE_DCHECK(GetArenaForAllocation() == nullptr); +} + +void FieldOptions::ArenaDtor(void* object) { + FieldOptions* _this = reinterpret_cast< FieldOptions* >(object); + (void)_this; +} +void FieldOptions::RegisterArenaDtor(::PROTOBUF_NAMESPACE_ID::Arena*) { +} +void FieldOptions::SetCachedSize(int size) const { + _cached_size_.Set(size); +} + +void FieldOptions::Clear() { +// @@protoc_insertion_point(message_clear_start:google.protobuf.FieldOptions) + arc_ui32 cached_has_bits = 0; + // Prevent compiler warnings about cached_has_bits being unused + (void) cached_has_bits; + + _extensions_.Clear(); + uninterpreted_option_.Clear(); + cached_has_bits = _has_bits_[0]; + if (cached_has_bits & 0x0000003fu) { + ::memset(&ctype_, 0, static_cast<size_t>( + reinterpret_cast<char*>(&jstype_) - + reinterpret_cast<char*>(&ctype_)) + sizeof(jstype_)); + } + _has_bits_.Clear(); + _internal_metadata_.Clear<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(); +} + +const char* FieldOptions::_InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) { +#define CHK_(x) if (PROTOBUF_PREDICT_FALSE(!(x))) goto failure + _Internal::HasBits has_bits{}; + while (!ctx->Done(&ptr)) { + arc_ui32 tag; + ptr = ::PROTOBUF_NAMESPACE_ID::internal::ReadTag(ptr, &tag); + switch (tag >> 3) { + // optional .google.protobuf.FieldOptions.CType ctype = 1 [default = STRING]; + case 1: + if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 8)) { + arc_ui64 val = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint64(&ptr); + CHK_(ptr); + if (PROTOBUF_PREDICT_TRUE(::PROTOBUF_NAMESPACE_ID::FieldOptions_CType_IsValid(val))) { + _internal_set_ctype(static_cast<::PROTOBUF_NAMESPACE_ID::FieldOptions_CType>(val)); + } else { + ::PROTOBUF_NAMESPACE_ID::internal::WriteVarint(1, val, mutable_unknown_fields()); + } + } else + goto handle_unusual; + continue; + // optional bool packed = 2; + case 2: + if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 16)) { + _Internal::set_has_packed(&has_bits); + packed_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint64(&ptr); + CHK_(ptr); + } else + goto handle_unusual; + continue; + // optional bool deprecated = 3 [default = false]; + case 3: + if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 24)) { + _Internal::set_has_deprecated(&has_bits); + deprecated_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint64(&ptr); + CHK_(ptr); + } else + goto handle_unusual; + continue; + // optional bool lazy = 5 [default = false]; + case 5: + if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 40)) { + _Internal::set_has_lazy(&has_bits); + lazy_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint64(&ptr); + CHK_(ptr); + } else + goto handle_unusual; + continue; + // optional .google.protobuf.FieldOptions.JSType jstype = 6 [default = JS_NORMAL]; + case 6: + if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 48)) { + arc_ui64 val = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint64(&ptr); + CHK_(ptr); + if (PROTOBUF_PREDICT_TRUE(::PROTOBUF_NAMESPACE_ID::FieldOptions_JSType_IsValid(val))) { + _internal_set_jstype(static_cast<::PROTOBUF_NAMESPACE_ID::FieldOptions_JSType>(val)); + } else { + ::PROTOBUF_NAMESPACE_ID::internal::WriteVarint(6, val, mutable_unknown_fields()); + } + } else + goto handle_unusual; + continue; + // optional bool weak = 10 [default = false]; + case 10: + if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 80)) { + _Internal::set_has_weak(&has_bits); + weak_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint64(&ptr); + CHK_(ptr); + } else + goto handle_unusual; + continue; + // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999; + case 999: + if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 58)) { + ptr -= 2; + do { + ptr += 2; + ptr = ctx->ParseMessage(_internal_add_uninterpreted_option(), ptr); + CHK_(ptr); + if (!ctx->DataAvailable(ptr)) break; + } while (::PROTOBUF_NAMESPACE_ID::internal::ExpectTag<7994>(ptr)); + } else + goto handle_unusual; + continue; + default: + goto handle_unusual; + } // switch + handle_unusual: + if ((tag == 0) || ((tag & 7) == 4)) { + CHK_(ptr); + ctx->SetLastTag(tag); + goto message_done; + } + if ((8000u <= tag)) { + ptr = _extensions_.ParseField(tag, ptr, internal_default_instance(), &_internal_metadata_, ctx); + CHK_(ptr != nullptr); + continue; + } + ptr = UnknownFieldParse( + tag, + _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(), + ptr, ctx); + CHK_(ptr != nullptr); + } // while +message_done: + _has_bits_.Or(has_bits); + return ptr; +failure: + ptr = nullptr; + goto message_done; +#undef CHK_ +} + +uint8_t* FieldOptions::_InternalSerialize( + uint8_t* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const { + // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.FieldOptions) + arc_ui32 cached_has_bits = 0; + (void) cached_has_bits; + + cached_has_bits = _has_bits_[0]; + // optional .google.protobuf.FieldOptions.CType ctype = 1 [default = STRING]; + if (cached_has_bits & 0x00000001u) { + target = stream->EnsureSpace(target); + target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteEnumToArray( + 1, this->_internal_ctype(), target); + } + + // optional bool packed = 2; + if (cached_has_bits & 0x00000002u) { + target = stream->EnsureSpace(target); + target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteBoolToArray(2, this->_internal_packed(), target); + } + + // optional bool deprecated = 3 [default = false]; + if (cached_has_bits & 0x00000008u) { + target = stream->EnsureSpace(target); + target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteBoolToArray(3, this->_internal_deprecated(), target); + } + + // optional bool lazy = 5 [default = false]; + if (cached_has_bits & 0x00000004u) { + target = stream->EnsureSpace(target); + target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteBoolToArray(5, this->_internal_lazy(), target); + } + + // optional .google.protobuf.FieldOptions.JSType jstype = 6 [default = JS_NORMAL]; + if (cached_has_bits & 0x00000020u) { + target = stream->EnsureSpace(target); + target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteEnumToArray( + 6, this->_internal_jstype(), target); + } + + // optional bool weak = 10 [default = false]; + if (cached_has_bits & 0x00000010u) { + target = stream->EnsureSpace(target); + target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteBoolToArray(10, this->_internal_weak(), target); + } + + // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999; + for (unsigned int i = 0, + n = static_cast<unsigned int>(this->_internal_uninterpreted_option_size()); i < n; i++) { + target = stream->EnsureSpace(target); + target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite:: + InternalWriteMessage(999, this->_internal_uninterpreted_option(i), target, stream); + } + + // Extension range [1000, 536870912) + target = _extensions_._InternalSerialize( + internal_default_instance(), 1000, 536870912, target, stream); + + if (PROTOBUF_PREDICT_FALSE(_internal_metadata_.have_unknown_fields())) { + target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::InternalSerializeUnknownFieldsToArray( + _internal_metadata_.unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(::PROTOBUF_NAMESPACE_ID::UnknownFieldSet::default_instance), target, stream); + } + // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.FieldOptions) + return target; +} + +size_t FieldOptions::ByteSizeLong() const { +// @@protoc_insertion_point(message_byte_size_start:google.protobuf.FieldOptions) + size_t total_size = 0; + + total_size += _extensions_.ByteSize(); + + arc_ui32 cached_has_bits = 0; + // Prevent compiler warnings about cached_has_bits being unused + (void) cached_has_bits; + + // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999; + total_size += 2UL * this->_internal_uninterpreted_option_size(); + for (const auto& msg : this->uninterpreted_option_) { + total_size += + ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::MessageSize(msg); + } + + cached_has_bits = _has_bits_[0]; + if (cached_has_bits & 0x0000003fu) { + // optional .google.protobuf.FieldOptions.CType ctype = 1 [default = STRING]; + if (cached_has_bits & 0x00000001u) { + total_size += 1 + + ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::EnumSize(this->_internal_ctype()); + } + + // optional bool packed = 2; + if (cached_has_bits & 0x00000002u) { + total_size += 1 + 1; + } + + // optional bool lazy = 5 [default = false]; + if (cached_has_bits & 0x00000004u) { + total_size += 1 + 1; + } + + // optional bool deprecated = 3 [default = false]; + if (cached_has_bits & 0x00000008u) { + total_size += 1 + 1; + } + + // optional bool weak = 10 [default = false]; + if (cached_has_bits & 0x00000010u) { + total_size += 1 + 1; + } + + // optional .google.protobuf.FieldOptions.JSType jstype = 6 [default = JS_NORMAL]; + if (cached_has_bits & 0x00000020u) { + total_size += 1 + + ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::EnumSize(this->_internal_jstype()); + } + + } + return MaybeComputeUnknownFieldsSize(total_size, &_cached_size_); +} + +const ::PROTOBUF_NAMESPACE_ID::Message::ClassData FieldOptions::_class_data_ = { + ::PROTOBUF_NAMESPACE_ID::Message::CopyWithSizeCheck, + FieldOptions::MergeImpl +}; +const ::PROTOBUF_NAMESPACE_ID::Message::ClassData*FieldOptions::GetClassData() const { return &_class_data_; } + +void FieldOptions::MergeImpl(::PROTOBUF_NAMESPACE_ID::Message* to, + const ::PROTOBUF_NAMESPACE_ID::Message& from) { + static_cast<FieldOptions *>(to)->MergeFrom( + static_cast<const FieldOptions &>(from)); +} + + +void FieldOptions::MergeFrom(const FieldOptions& from) { +// @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.FieldOptions) + GOOGLE_DCHECK_NE(&from, this); + arc_ui32 cached_has_bits = 0; + (void) cached_has_bits; + + uninterpreted_option_.MergeFrom(from.uninterpreted_option_); + cached_has_bits = from._has_bits_[0]; + if (cached_has_bits & 0x0000003fu) { + if (cached_has_bits & 0x00000001u) { + ctype_ = from.ctype_; + } + if (cached_has_bits & 0x00000002u) { + packed_ = from.packed_; + } + if (cached_has_bits & 0x00000004u) { + lazy_ = from.lazy_; + } + if (cached_has_bits & 0x00000008u) { + deprecated_ = from.deprecated_; + } + if (cached_has_bits & 0x00000010u) { + weak_ = from.weak_; + } + if (cached_has_bits & 0x00000020u) { + jstype_ = from.jstype_; + } + _has_bits_[0] |= cached_has_bits; + } + _extensions_.MergeFrom(internal_default_instance(), from._extensions_); + _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_); +} + +void FieldOptions::CopyFrom(const FieldOptions& from) { +// @@protoc_insertion_point(class_specific_copy_from_start:google.protobuf.FieldOptions) + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool FieldOptions::IsInitialized() const { + if (!_extensions_.IsInitialized()) { + return false; + } + + if (!::PROTOBUF_NAMESPACE_ID::internal::AllAreInitialized(uninterpreted_option_)) + return false; + return true; +} + +void FieldOptions::InternalSwap(FieldOptions* other) { + using std::swap; + _extensions_.InternalSwap(&other->_extensions_); + _internal_metadata_.InternalSwap(&other->_internal_metadata_); + swap(_has_bits_[0], other->_has_bits_[0]); + uninterpreted_option_.InternalSwap(&other->uninterpreted_option_); + ::PROTOBUF_NAMESPACE_ID::internal::memswap< + PROTOBUF_FIELD_OFFSET(FieldOptions, jstype_) + + sizeof(FieldOptions::jstype_) + - PROTOBUF_FIELD_OFFSET(FieldOptions, ctype_)>( + reinterpret_cast<char*>(&ctype_), + reinterpret_cast<char*>(&other->ctype_)); +} + +::PROTOBUF_NAMESPACE_ID::Metadata FieldOptions::GetMetadata() const { + return ::PROTOBUF_NAMESPACE_ID::internal::AssignDescriptors( + &descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_getter, &descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_once, + file_level_metadata_google_2fprotobuf_2fdescriptor_2eproto[15]); +} + +// =================================================================== + +class OneofOptions::_Internal { + public: +}; + +OneofOptions::OneofOptions(::PROTOBUF_NAMESPACE_ID::Arena* arena, + bool is_message_owned) + : ::PROTOBUF_NAMESPACE_ID::Message(arena, is_message_owned), + _extensions_(arena), + uninterpreted_option_(arena) { + SharedCtor(); + if (!is_message_owned) { + RegisterArenaDtor(arena); + } + // @@protoc_insertion_point(arena_constructor:google.protobuf.OneofOptions) +} +OneofOptions::OneofOptions(const OneofOptions& from) + : ::PROTOBUF_NAMESPACE_ID::Message(), + uninterpreted_option_(from.uninterpreted_option_) { + _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_); + _extensions_.MergeFrom(internal_default_instance(), from._extensions_); + // @@protoc_insertion_point(copy_constructor:google.protobuf.OneofOptions) +} + +inline void OneofOptions::SharedCtor() { +} + +OneofOptions::~OneofOptions() { + // @@protoc_insertion_point(destructor:google.protobuf.OneofOptions) + if (GetArenaForAllocation() != nullptr) return; + SharedDtor(); + _internal_metadata_.Delete<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(); +} + +inline void OneofOptions::SharedDtor() { + GOOGLE_DCHECK(GetArenaForAllocation() == nullptr); +} + +void OneofOptions::ArenaDtor(void* object) { + OneofOptions* _this = reinterpret_cast< OneofOptions* >(object); + (void)_this; +} +void OneofOptions::RegisterArenaDtor(::PROTOBUF_NAMESPACE_ID::Arena*) { +} +void OneofOptions::SetCachedSize(int size) const { + _cached_size_.Set(size); +} + +void OneofOptions::Clear() { +// @@protoc_insertion_point(message_clear_start:google.protobuf.OneofOptions) + arc_ui32 cached_has_bits = 0; + // Prevent compiler warnings about cached_has_bits being unused + (void) cached_has_bits; + + _extensions_.Clear(); + uninterpreted_option_.Clear(); + _internal_metadata_.Clear<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(); +} + +const char* OneofOptions::_InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) { +#define CHK_(x) if (PROTOBUF_PREDICT_FALSE(!(x))) goto failure + while (!ctx->Done(&ptr)) { + arc_ui32 tag; + ptr = ::PROTOBUF_NAMESPACE_ID::internal::ReadTag(ptr, &tag); + switch (tag >> 3) { + // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999; + case 999: + if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 58)) { + ptr -= 2; + do { + ptr += 2; + ptr = ctx->ParseMessage(_internal_add_uninterpreted_option(), ptr); + CHK_(ptr); + if (!ctx->DataAvailable(ptr)) break; + } while (::PROTOBUF_NAMESPACE_ID::internal::ExpectTag<7994>(ptr)); + } else + goto handle_unusual; + continue; + default: + goto handle_unusual; + } // switch + handle_unusual: + if ((tag == 0) || ((tag & 7) == 4)) { + CHK_(ptr); + ctx->SetLastTag(tag); + goto message_done; + } + if ((8000u <= tag)) { + ptr = _extensions_.ParseField(tag, ptr, internal_default_instance(), &_internal_metadata_, ctx); + CHK_(ptr != nullptr); + continue; + } + ptr = UnknownFieldParse( + tag, + _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(), + ptr, ctx); + CHK_(ptr != nullptr); + } // while +message_done: + return ptr; +failure: + ptr = nullptr; + goto message_done; +#undef CHK_ +} + +uint8_t* OneofOptions::_InternalSerialize( + uint8_t* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const { + // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.OneofOptions) + arc_ui32 cached_has_bits = 0; + (void) cached_has_bits; + + // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999; + for (unsigned int i = 0, + n = static_cast<unsigned int>(this->_internal_uninterpreted_option_size()); i < n; i++) { + target = stream->EnsureSpace(target); + target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite:: + InternalWriteMessage(999, this->_internal_uninterpreted_option(i), target, stream); + } + + // Extension range [1000, 536870912) + target = _extensions_._InternalSerialize( + internal_default_instance(), 1000, 536870912, target, stream); + + if (PROTOBUF_PREDICT_FALSE(_internal_metadata_.have_unknown_fields())) { + target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::InternalSerializeUnknownFieldsToArray( + _internal_metadata_.unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(::PROTOBUF_NAMESPACE_ID::UnknownFieldSet::default_instance), target, stream); + } + // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.OneofOptions) + return target; +} + +size_t OneofOptions::ByteSizeLong() const { +// @@protoc_insertion_point(message_byte_size_start:google.protobuf.OneofOptions) + size_t total_size = 0; + + total_size += _extensions_.ByteSize(); + + arc_ui32 cached_has_bits = 0; + // Prevent compiler warnings about cached_has_bits being unused + (void) cached_has_bits; + + // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999; + total_size += 2UL * this->_internal_uninterpreted_option_size(); + for (const auto& msg : this->uninterpreted_option_) { + total_size += + ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::MessageSize(msg); + } + + return MaybeComputeUnknownFieldsSize(total_size, &_cached_size_); +} + +const ::PROTOBUF_NAMESPACE_ID::Message::ClassData OneofOptions::_class_data_ = { + ::PROTOBUF_NAMESPACE_ID::Message::CopyWithSizeCheck, + OneofOptions::MergeImpl +}; +const ::PROTOBUF_NAMESPACE_ID::Message::ClassData*OneofOptions::GetClassData() const { return &_class_data_; } + +void OneofOptions::MergeImpl(::PROTOBUF_NAMESPACE_ID::Message* to, + const ::PROTOBUF_NAMESPACE_ID::Message& from) { + static_cast<OneofOptions *>(to)->MergeFrom( + static_cast<const OneofOptions &>(from)); +} + + +void OneofOptions::MergeFrom(const OneofOptions& from) { +// @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.OneofOptions) + GOOGLE_DCHECK_NE(&from, this); + arc_ui32 cached_has_bits = 0; + (void) cached_has_bits; + + uninterpreted_option_.MergeFrom(from.uninterpreted_option_); + _extensions_.MergeFrom(internal_default_instance(), from._extensions_); + _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_); +} + +void OneofOptions::CopyFrom(const OneofOptions& from) { +// @@protoc_insertion_point(class_specific_copy_from_start:google.protobuf.OneofOptions) + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool OneofOptions::IsInitialized() const { + if (!_extensions_.IsInitialized()) { + return false; + } + + if (!::PROTOBUF_NAMESPACE_ID::internal::AllAreInitialized(uninterpreted_option_)) + return false; + return true; +} + +void OneofOptions::InternalSwap(OneofOptions* other) { + using std::swap; + _extensions_.InternalSwap(&other->_extensions_); + _internal_metadata_.InternalSwap(&other->_internal_metadata_); + uninterpreted_option_.InternalSwap(&other->uninterpreted_option_); +} + +::PROTOBUF_NAMESPACE_ID::Metadata OneofOptions::GetMetadata() const { + return ::PROTOBUF_NAMESPACE_ID::internal::AssignDescriptors( + &descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_getter, &descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_once, + file_level_metadata_google_2fprotobuf_2fdescriptor_2eproto[16]); +} + +// =================================================================== + +class EnumOptions::_Internal { + public: + using HasBits = decltype(std::declval<EnumOptions>()._has_bits_); + static void set_has_allow_alias(HasBits* has_bits) { + (*has_bits)[0] |= 1u; + } + static void set_has_deprecated(HasBits* has_bits) { + (*has_bits)[0] |= 2u; + } +}; + +EnumOptions::EnumOptions(::PROTOBUF_NAMESPACE_ID::Arena* arena, + bool is_message_owned) + : ::PROTOBUF_NAMESPACE_ID::Message(arena, is_message_owned), + _extensions_(arena), + uninterpreted_option_(arena) { + SharedCtor(); + if (!is_message_owned) { + RegisterArenaDtor(arena); + } + // @@protoc_insertion_point(arena_constructor:google.protobuf.EnumOptions) +} +EnumOptions::EnumOptions(const EnumOptions& from) + : ::PROTOBUF_NAMESPACE_ID::Message(), + _has_bits_(from._has_bits_), + uninterpreted_option_(from.uninterpreted_option_) { + _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_); + _extensions_.MergeFrom(internal_default_instance(), from._extensions_); + ::memcpy(&allow_alias_, &from.allow_alias_, + static_cast<size_t>(reinterpret_cast<char*>(&deprecated_) - + reinterpret_cast<char*>(&allow_alias_)) + sizeof(deprecated_)); + // @@protoc_insertion_point(copy_constructor:google.protobuf.EnumOptions) +} + +inline void EnumOptions::SharedCtor() { +::memset(reinterpret_cast<char*>(this) + static_cast<size_t>( + reinterpret_cast<char*>(&allow_alias_) - reinterpret_cast<char*>(this)), + 0, static_cast<size_t>(reinterpret_cast<char*>(&deprecated_) - + reinterpret_cast<char*>(&allow_alias_)) + sizeof(deprecated_)); +} + +EnumOptions::~EnumOptions() { + // @@protoc_insertion_point(destructor:google.protobuf.EnumOptions) + if (GetArenaForAllocation() != nullptr) return; + SharedDtor(); + _internal_metadata_.Delete<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(); +} + +inline void EnumOptions::SharedDtor() { + GOOGLE_DCHECK(GetArenaForAllocation() == nullptr); +} + +void EnumOptions::ArenaDtor(void* object) { + EnumOptions* _this = reinterpret_cast< EnumOptions* >(object); + (void)_this; +} +void EnumOptions::RegisterArenaDtor(::PROTOBUF_NAMESPACE_ID::Arena*) { +} +void EnumOptions::SetCachedSize(int size) const { + _cached_size_.Set(size); +} + +void EnumOptions::Clear() { +// @@protoc_insertion_point(message_clear_start:google.protobuf.EnumOptions) + arc_ui32 cached_has_bits = 0; + // Prevent compiler warnings about cached_has_bits being unused + (void) cached_has_bits; + + _extensions_.Clear(); + uninterpreted_option_.Clear(); + ::memset(&allow_alias_, 0, static_cast<size_t>( + reinterpret_cast<char*>(&deprecated_) - + reinterpret_cast<char*>(&allow_alias_)) + sizeof(deprecated_)); + _has_bits_.Clear(); + _internal_metadata_.Clear<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(); +} + +const char* EnumOptions::_InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) { +#define CHK_(x) if (PROTOBUF_PREDICT_FALSE(!(x))) goto failure + _Internal::HasBits has_bits{}; + while (!ctx->Done(&ptr)) { + arc_ui32 tag; + ptr = ::PROTOBUF_NAMESPACE_ID::internal::ReadTag(ptr, &tag); + switch (tag >> 3) { + // optional bool allow_alias = 2; + case 2: + if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 16)) { + _Internal::set_has_allow_alias(&has_bits); + allow_alias_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint64(&ptr); + CHK_(ptr); + } else + goto handle_unusual; + continue; + // optional bool deprecated = 3 [default = false]; + case 3: + if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 24)) { + _Internal::set_has_deprecated(&has_bits); + deprecated_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint64(&ptr); + CHK_(ptr); + } else + goto handle_unusual; + continue; + // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999; + case 999: + if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 58)) { + ptr -= 2; + do { + ptr += 2; + ptr = ctx->ParseMessage(_internal_add_uninterpreted_option(), ptr); + CHK_(ptr); + if (!ctx->DataAvailable(ptr)) break; + } while (::PROTOBUF_NAMESPACE_ID::internal::ExpectTag<7994>(ptr)); + } else + goto handle_unusual; + continue; + default: + goto handle_unusual; + } // switch + handle_unusual: + if ((tag == 0) || ((tag & 7) == 4)) { + CHK_(ptr); + ctx->SetLastTag(tag); + goto message_done; + } + if ((8000u <= tag)) { + ptr = _extensions_.ParseField(tag, ptr, internal_default_instance(), &_internal_metadata_, ctx); + CHK_(ptr != nullptr); + continue; + } + ptr = UnknownFieldParse( + tag, + _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(), + ptr, ctx); + CHK_(ptr != nullptr); + } // while +message_done: + _has_bits_.Or(has_bits); + return ptr; +failure: + ptr = nullptr; + goto message_done; +#undef CHK_ +} + +uint8_t* EnumOptions::_InternalSerialize( + uint8_t* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const { + // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.EnumOptions) + arc_ui32 cached_has_bits = 0; + (void) cached_has_bits; + + cached_has_bits = _has_bits_[0]; + // optional bool allow_alias = 2; + if (cached_has_bits & 0x00000001u) { + target = stream->EnsureSpace(target); + target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteBoolToArray(2, this->_internal_allow_alias(), target); + } + + // optional bool deprecated = 3 [default = false]; + if (cached_has_bits & 0x00000002u) { + target = stream->EnsureSpace(target); + target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteBoolToArray(3, this->_internal_deprecated(), target); + } + + // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999; + for (unsigned int i = 0, + n = static_cast<unsigned int>(this->_internal_uninterpreted_option_size()); i < n; i++) { + target = stream->EnsureSpace(target); + target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite:: + InternalWriteMessage(999, this->_internal_uninterpreted_option(i), target, stream); + } + + // Extension range [1000, 536870912) + target = _extensions_._InternalSerialize( + internal_default_instance(), 1000, 536870912, target, stream); + + if (PROTOBUF_PREDICT_FALSE(_internal_metadata_.have_unknown_fields())) { + target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::InternalSerializeUnknownFieldsToArray( + _internal_metadata_.unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(::PROTOBUF_NAMESPACE_ID::UnknownFieldSet::default_instance), target, stream); + } + // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.EnumOptions) + return target; +} + +size_t EnumOptions::ByteSizeLong() const { +// @@protoc_insertion_point(message_byte_size_start:google.protobuf.EnumOptions) + size_t total_size = 0; + + total_size += _extensions_.ByteSize(); + + arc_ui32 cached_has_bits = 0; + // Prevent compiler warnings about cached_has_bits being unused + (void) cached_has_bits; + + // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999; + total_size += 2UL * this->_internal_uninterpreted_option_size(); + for (const auto& msg : this->uninterpreted_option_) { + total_size += + ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::MessageSize(msg); + } + + cached_has_bits = _has_bits_[0]; + if (cached_has_bits & 0x00000003u) { + // optional bool allow_alias = 2; + if (cached_has_bits & 0x00000001u) { + total_size += 1 + 1; + } + + // optional bool deprecated = 3 [default = false]; + if (cached_has_bits & 0x00000002u) { + total_size += 1 + 1; + } + + } + return MaybeComputeUnknownFieldsSize(total_size, &_cached_size_); +} + +const ::PROTOBUF_NAMESPACE_ID::Message::ClassData EnumOptions::_class_data_ = { + ::PROTOBUF_NAMESPACE_ID::Message::CopyWithSizeCheck, + EnumOptions::MergeImpl +}; +const ::PROTOBUF_NAMESPACE_ID::Message::ClassData*EnumOptions::GetClassData() const { return &_class_data_; } + +void EnumOptions::MergeImpl(::PROTOBUF_NAMESPACE_ID::Message* to, + const ::PROTOBUF_NAMESPACE_ID::Message& from) { + static_cast<EnumOptions *>(to)->MergeFrom( + static_cast<const EnumOptions &>(from)); +} + + +void EnumOptions::MergeFrom(const EnumOptions& from) { +// @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.EnumOptions) + GOOGLE_DCHECK_NE(&from, this); + arc_ui32 cached_has_bits = 0; + (void) cached_has_bits; + + uninterpreted_option_.MergeFrom(from.uninterpreted_option_); + cached_has_bits = from._has_bits_[0]; + if (cached_has_bits & 0x00000003u) { + if (cached_has_bits & 0x00000001u) { + allow_alias_ = from.allow_alias_; + } + if (cached_has_bits & 0x00000002u) { + deprecated_ = from.deprecated_; + } + _has_bits_[0] |= cached_has_bits; + } + _extensions_.MergeFrom(internal_default_instance(), from._extensions_); + _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_); +} + +void EnumOptions::CopyFrom(const EnumOptions& from) { +// @@protoc_insertion_point(class_specific_copy_from_start:google.protobuf.EnumOptions) + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool EnumOptions::IsInitialized() const { + if (!_extensions_.IsInitialized()) { + return false; + } + + if (!::PROTOBUF_NAMESPACE_ID::internal::AllAreInitialized(uninterpreted_option_)) + return false; + return true; +} + +void EnumOptions::InternalSwap(EnumOptions* other) { + using std::swap; + _extensions_.InternalSwap(&other->_extensions_); + _internal_metadata_.InternalSwap(&other->_internal_metadata_); + swap(_has_bits_[0], other->_has_bits_[0]); + uninterpreted_option_.InternalSwap(&other->uninterpreted_option_); + ::PROTOBUF_NAMESPACE_ID::internal::memswap< + PROTOBUF_FIELD_OFFSET(EnumOptions, deprecated_) + + sizeof(EnumOptions::deprecated_) + - PROTOBUF_FIELD_OFFSET(EnumOptions, allow_alias_)>( + reinterpret_cast<char*>(&allow_alias_), + reinterpret_cast<char*>(&other->allow_alias_)); +} + +::PROTOBUF_NAMESPACE_ID::Metadata EnumOptions::GetMetadata() const { + return ::PROTOBUF_NAMESPACE_ID::internal::AssignDescriptors( + &descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_getter, &descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_once, + file_level_metadata_google_2fprotobuf_2fdescriptor_2eproto[17]); +} + +// =================================================================== + +class EnumValueOptions::_Internal { + public: + using HasBits = decltype(std::declval<EnumValueOptions>()._has_bits_); + static void set_has_deprecated(HasBits* has_bits) { + (*has_bits)[0] |= 1u; + } +}; + +EnumValueOptions::EnumValueOptions(::PROTOBUF_NAMESPACE_ID::Arena* arena, + bool is_message_owned) + : ::PROTOBUF_NAMESPACE_ID::Message(arena, is_message_owned), + _extensions_(arena), + uninterpreted_option_(arena) { + SharedCtor(); + if (!is_message_owned) { + RegisterArenaDtor(arena); + } + // @@protoc_insertion_point(arena_constructor:google.protobuf.EnumValueOptions) +} +EnumValueOptions::EnumValueOptions(const EnumValueOptions& from) + : ::PROTOBUF_NAMESPACE_ID::Message(), + _has_bits_(from._has_bits_), + uninterpreted_option_(from.uninterpreted_option_) { + _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_); + _extensions_.MergeFrom(internal_default_instance(), from._extensions_); + deprecated_ = from.deprecated_; + // @@protoc_insertion_point(copy_constructor:google.protobuf.EnumValueOptions) +} + +inline void EnumValueOptions::SharedCtor() { +deprecated_ = false; +} + +EnumValueOptions::~EnumValueOptions() { + // @@protoc_insertion_point(destructor:google.protobuf.EnumValueOptions) + if (GetArenaForAllocation() != nullptr) return; + SharedDtor(); + _internal_metadata_.Delete<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(); +} + +inline void EnumValueOptions::SharedDtor() { + GOOGLE_DCHECK(GetArenaForAllocation() == nullptr); +} + +void EnumValueOptions::ArenaDtor(void* object) { + EnumValueOptions* _this = reinterpret_cast< EnumValueOptions* >(object); + (void)_this; +} +void EnumValueOptions::RegisterArenaDtor(::PROTOBUF_NAMESPACE_ID::Arena*) { +} +void EnumValueOptions::SetCachedSize(int size) const { + _cached_size_.Set(size); +} + +void EnumValueOptions::Clear() { +// @@protoc_insertion_point(message_clear_start:google.protobuf.EnumValueOptions) + arc_ui32 cached_has_bits = 0; + // Prevent compiler warnings about cached_has_bits being unused + (void) cached_has_bits; + + _extensions_.Clear(); + uninterpreted_option_.Clear(); + deprecated_ = false; + _has_bits_.Clear(); + _internal_metadata_.Clear<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(); +} + +const char* EnumValueOptions::_InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) { +#define CHK_(x) if (PROTOBUF_PREDICT_FALSE(!(x))) goto failure + _Internal::HasBits has_bits{}; + while (!ctx->Done(&ptr)) { + arc_ui32 tag; + ptr = ::PROTOBUF_NAMESPACE_ID::internal::ReadTag(ptr, &tag); + switch (tag >> 3) { + // optional bool deprecated = 1 [default = false]; + case 1: + if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 8)) { + _Internal::set_has_deprecated(&has_bits); + deprecated_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint64(&ptr); + CHK_(ptr); + } else + goto handle_unusual; + continue; + // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999; + case 999: + if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 58)) { + ptr -= 2; + do { + ptr += 2; + ptr = ctx->ParseMessage(_internal_add_uninterpreted_option(), ptr); + CHK_(ptr); + if (!ctx->DataAvailable(ptr)) break; + } while (::PROTOBUF_NAMESPACE_ID::internal::ExpectTag<7994>(ptr)); + } else + goto handle_unusual; + continue; + default: + goto handle_unusual; + } // switch + handle_unusual: + if ((tag == 0) || ((tag & 7) == 4)) { + CHK_(ptr); + ctx->SetLastTag(tag); + goto message_done; + } + if ((8000u <= tag)) { + ptr = _extensions_.ParseField(tag, ptr, internal_default_instance(), &_internal_metadata_, ctx); + CHK_(ptr != nullptr); + continue; + } + ptr = UnknownFieldParse( + tag, + _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(), + ptr, ctx); + CHK_(ptr != nullptr); + } // while +message_done: + _has_bits_.Or(has_bits); + return ptr; +failure: + ptr = nullptr; + goto message_done; +#undef CHK_ +} + +uint8_t* EnumValueOptions::_InternalSerialize( + uint8_t* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const { + // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.EnumValueOptions) + arc_ui32 cached_has_bits = 0; + (void) cached_has_bits; + + cached_has_bits = _has_bits_[0]; + // optional bool deprecated = 1 [default = false]; + if (cached_has_bits & 0x00000001u) { + target = stream->EnsureSpace(target); + target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteBoolToArray(1, this->_internal_deprecated(), target); + } + + // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999; + for (unsigned int i = 0, + n = static_cast<unsigned int>(this->_internal_uninterpreted_option_size()); i < n; i++) { + target = stream->EnsureSpace(target); + target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite:: + InternalWriteMessage(999, this->_internal_uninterpreted_option(i), target, stream); + } + + // Extension range [1000, 536870912) + target = _extensions_._InternalSerialize( + internal_default_instance(), 1000, 536870912, target, stream); + + if (PROTOBUF_PREDICT_FALSE(_internal_metadata_.have_unknown_fields())) { + target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::InternalSerializeUnknownFieldsToArray( + _internal_metadata_.unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(::PROTOBUF_NAMESPACE_ID::UnknownFieldSet::default_instance), target, stream); + } + // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.EnumValueOptions) + return target; +} + +size_t EnumValueOptions::ByteSizeLong() const { +// @@protoc_insertion_point(message_byte_size_start:google.protobuf.EnumValueOptions) + size_t total_size = 0; + + total_size += _extensions_.ByteSize(); + + arc_ui32 cached_has_bits = 0; + // Prevent compiler warnings about cached_has_bits being unused + (void) cached_has_bits; + + // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999; + total_size += 2UL * this->_internal_uninterpreted_option_size(); + for (const auto& msg : this->uninterpreted_option_) { + total_size += + ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::MessageSize(msg); + } + + // optional bool deprecated = 1 [default = false]; + cached_has_bits = _has_bits_[0]; + if (cached_has_bits & 0x00000001u) { + total_size += 1 + 1; + } + + return MaybeComputeUnknownFieldsSize(total_size, &_cached_size_); +} + +const ::PROTOBUF_NAMESPACE_ID::Message::ClassData EnumValueOptions::_class_data_ = { + ::PROTOBUF_NAMESPACE_ID::Message::CopyWithSizeCheck, + EnumValueOptions::MergeImpl +}; +const ::PROTOBUF_NAMESPACE_ID::Message::ClassData*EnumValueOptions::GetClassData() const { return &_class_data_; } + +void EnumValueOptions::MergeImpl(::PROTOBUF_NAMESPACE_ID::Message* to, + const ::PROTOBUF_NAMESPACE_ID::Message& from) { + static_cast<EnumValueOptions *>(to)->MergeFrom( + static_cast<const EnumValueOptions &>(from)); +} + + +void EnumValueOptions::MergeFrom(const EnumValueOptions& from) { +// @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.EnumValueOptions) + GOOGLE_DCHECK_NE(&from, this); + arc_ui32 cached_has_bits = 0; + (void) cached_has_bits; + + uninterpreted_option_.MergeFrom(from.uninterpreted_option_); + if (from._internal_has_deprecated()) { + _internal_set_deprecated(from._internal_deprecated()); + } + _extensions_.MergeFrom(internal_default_instance(), from._extensions_); + _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_); +} + +void EnumValueOptions::CopyFrom(const EnumValueOptions& from) { +// @@protoc_insertion_point(class_specific_copy_from_start:google.protobuf.EnumValueOptions) + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool EnumValueOptions::IsInitialized() const { + if (!_extensions_.IsInitialized()) { + return false; + } + + if (!::PROTOBUF_NAMESPACE_ID::internal::AllAreInitialized(uninterpreted_option_)) + return false; + return true; +} + +void EnumValueOptions::InternalSwap(EnumValueOptions* other) { + using std::swap; + _extensions_.InternalSwap(&other->_extensions_); + _internal_metadata_.InternalSwap(&other->_internal_metadata_); + swap(_has_bits_[0], other->_has_bits_[0]); + uninterpreted_option_.InternalSwap(&other->uninterpreted_option_); + swap(deprecated_, other->deprecated_); +} + +::PROTOBUF_NAMESPACE_ID::Metadata EnumValueOptions::GetMetadata() const { + return ::PROTOBUF_NAMESPACE_ID::internal::AssignDescriptors( + &descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_getter, &descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_once, + file_level_metadata_google_2fprotobuf_2fdescriptor_2eproto[18]); +} + +// =================================================================== + +class ServiceOptions::_Internal { + public: + using HasBits = decltype(std::declval<ServiceOptions>()._has_bits_); + static void set_has_deprecated(HasBits* has_bits) { + (*has_bits)[0] |= 1u; + } +}; + +ServiceOptions::ServiceOptions(::PROTOBUF_NAMESPACE_ID::Arena* arena, + bool is_message_owned) + : ::PROTOBUF_NAMESPACE_ID::Message(arena, is_message_owned), + _extensions_(arena), + uninterpreted_option_(arena) { + SharedCtor(); + if (!is_message_owned) { + RegisterArenaDtor(arena); + } + // @@protoc_insertion_point(arena_constructor:google.protobuf.ServiceOptions) +} +ServiceOptions::ServiceOptions(const ServiceOptions& from) + : ::PROTOBUF_NAMESPACE_ID::Message(), + _has_bits_(from._has_bits_), + uninterpreted_option_(from.uninterpreted_option_) { + _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_); + _extensions_.MergeFrom(internal_default_instance(), from._extensions_); + deprecated_ = from.deprecated_; + // @@protoc_insertion_point(copy_constructor:google.protobuf.ServiceOptions) +} + +inline void ServiceOptions::SharedCtor() { +deprecated_ = false; +} + +ServiceOptions::~ServiceOptions() { + // @@protoc_insertion_point(destructor:google.protobuf.ServiceOptions) + if (GetArenaForAllocation() != nullptr) return; + SharedDtor(); + _internal_metadata_.Delete<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(); +} + +inline void ServiceOptions::SharedDtor() { + GOOGLE_DCHECK(GetArenaForAllocation() == nullptr); +} + +void ServiceOptions::ArenaDtor(void* object) { + ServiceOptions* _this = reinterpret_cast< ServiceOptions* >(object); + (void)_this; +} +void ServiceOptions::RegisterArenaDtor(::PROTOBUF_NAMESPACE_ID::Arena*) { +} +void ServiceOptions::SetCachedSize(int size) const { + _cached_size_.Set(size); +} + +void ServiceOptions::Clear() { +// @@protoc_insertion_point(message_clear_start:google.protobuf.ServiceOptions) + arc_ui32 cached_has_bits = 0; + // Prevent compiler warnings about cached_has_bits being unused + (void) cached_has_bits; + + _extensions_.Clear(); + uninterpreted_option_.Clear(); + deprecated_ = false; + _has_bits_.Clear(); + _internal_metadata_.Clear<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(); +} + +const char* ServiceOptions::_InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) { +#define CHK_(x) if (PROTOBUF_PREDICT_FALSE(!(x))) goto failure + _Internal::HasBits has_bits{}; + while (!ctx->Done(&ptr)) { + arc_ui32 tag; + ptr = ::PROTOBUF_NAMESPACE_ID::internal::ReadTag(ptr, &tag); + switch (tag >> 3) { + // optional bool deprecated = 33 [default = false]; + case 33: + if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 8)) { + _Internal::set_has_deprecated(&has_bits); + deprecated_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint64(&ptr); + CHK_(ptr); + } else + goto handle_unusual; + continue; + // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999; + case 999: + if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 58)) { + ptr -= 2; + do { + ptr += 2; + ptr = ctx->ParseMessage(_internal_add_uninterpreted_option(), ptr); + CHK_(ptr); + if (!ctx->DataAvailable(ptr)) break; + } while (::PROTOBUF_NAMESPACE_ID::internal::ExpectTag<7994>(ptr)); + } else + goto handle_unusual; + continue; + default: + goto handle_unusual; + } // switch + handle_unusual: + if ((tag == 0) || ((tag & 7) == 4)) { + CHK_(ptr); + ctx->SetLastTag(tag); + goto message_done; + } + if ((8000u <= tag)) { + ptr = _extensions_.ParseField(tag, ptr, internal_default_instance(), &_internal_metadata_, ctx); + CHK_(ptr != nullptr); + continue; + } + ptr = UnknownFieldParse( + tag, + _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(), + ptr, ctx); + CHK_(ptr != nullptr); + } // while +message_done: + _has_bits_.Or(has_bits); + return ptr; +failure: + ptr = nullptr; + goto message_done; +#undef CHK_ +} + +uint8_t* ServiceOptions::_InternalSerialize( + uint8_t* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const { + // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.ServiceOptions) + arc_ui32 cached_has_bits = 0; + (void) cached_has_bits; + + cached_has_bits = _has_bits_[0]; + // optional bool deprecated = 33 [default = false]; + if (cached_has_bits & 0x00000001u) { + target = stream->EnsureSpace(target); + target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteBoolToArray(33, this->_internal_deprecated(), target); + } + + // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999; + for (unsigned int i = 0, + n = static_cast<unsigned int>(this->_internal_uninterpreted_option_size()); i < n; i++) { + target = stream->EnsureSpace(target); + target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite:: + InternalWriteMessage(999, this->_internal_uninterpreted_option(i), target, stream); + } + + // Extension range [1000, 536870912) + target = _extensions_._InternalSerialize( + internal_default_instance(), 1000, 536870912, target, stream); + + if (PROTOBUF_PREDICT_FALSE(_internal_metadata_.have_unknown_fields())) { + target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::InternalSerializeUnknownFieldsToArray( + _internal_metadata_.unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(::PROTOBUF_NAMESPACE_ID::UnknownFieldSet::default_instance), target, stream); + } + // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.ServiceOptions) + return target; +} + +size_t ServiceOptions::ByteSizeLong() const { +// @@protoc_insertion_point(message_byte_size_start:google.protobuf.ServiceOptions) + size_t total_size = 0; + + total_size += _extensions_.ByteSize(); + + arc_ui32 cached_has_bits = 0; + // Prevent compiler warnings about cached_has_bits being unused + (void) cached_has_bits; + + // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999; + total_size += 2UL * this->_internal_uninterpreted_option_size(); + for (const auto& msg : this->uninterpreted_option_) { + total_size += + ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::MessageSize(msg); + } + + // optional bool deprecated = 33 [default = false]; + cached_has_bits = _has_bits_[0]; + if (cached_has_bits & 0x00000001u) { + total_size += 2 + 1; + } + + return MaybeComputeUnknownFieldsSize(total_size, &_cached_size_); +} + +const ::PROTOBUF_NAMESPACE_ID::Message::ClassData ServiceOptions::_class_data_ = { + ::PROTOBUF_NAMESPACE_ID::Message::CopyWithSizeCheck, + ServiceOptions::MergeImpl +}; +const ::PROTOBUF_NAMESPACE_ID::Message::ClassData*ServiceOptions::GetClassData() const { return &_class_data_; } + +void ServiceOptions::MergeImpl(::PROTOBUF_NAMESPACE_ID::Message* to, + const ::PROTOBUF_NAMESPACE_ID::Message& from) { + static_cast<ServiceOptions *>(to)->MergeFrom( + static_cast<const ServiceOptions &>(from)); +} + + +void ServiceOptions::MergeFrom(const ServiceOptions& from) { +// @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.ServiceOptions) + GOOGLE_DCHECK_NE(&from, this); + arc_ui32 cached_has_bits = 0; + (void) cached_has_bits; + + uninterpreted_option_.MergeFrom(from.uninterpreted_option_); + if (from._internal_has_deprecated()) { + _internal_set_deprecated(from._internal_deprecated()); + } + _extensions_.MergeFrom(internal_default_instance(), from._extensions_); + _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_); +} + +void ServiceOptions::CopyFrom(const ServiceOptions& from) { +// @@protoc_insertion_point(class_specific_copy_from_start:google.protobuf.ServiceOptions) + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool ServiceOptions::IsInitialized() const { + if (!_extensions_.IsInitialized()) { + return false; + } + + if (!::PROTOBUF_NAMESPACE_ID::internal::AllAreInitialized(uninterpreted_option_)) + return false; + return true; +} + +void ServiceOptions::InternalSwap(ServiceOptions* other) { + using std::swap; + _extensions_.InternalSwap(&other->_extensions_); + _internal_metadata_.InternalSwap(&other->_internal_metadata_); + swap(_has_bits_[0], other->_has_bits_[0]); + uninterpreted_option_.InternalSwap(&other->uninterpreted_option_); + swap(deprecated_, other->deprecated_); +} + +::PROTOBUF_NAMESPACE_ID::Metadata ServiceOptions::GetMetadata() const { + return ::PROTOBUF_NAMESPACE_ID::internal::AssignDescriptors( + &descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_getter, &descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_once, + file_level_metadata_google_2fprotobuf_2fdescriptor_2eproto[19]); +} + +// =================================================================== + +class MethodOptions::_Internal { + public: + using HasBits = decltype(std::declval<MethodOptions>()._has_bits_); + static void set_has_deprecated(HasBits* has_bits) { + (*has_bits)[0] |= 1u; + } + static void set_has_idempotency_level(HasBits* has_bits) { + (*has_bits)[0] |= 2u; + } +}; + +MethodOptions::MethodOptions(::PROTOBUF_NAMESPACE_ID::Arena* arena, + bool is_message_owned) + : ::PROTOBUF_NAMESPACE_ID::Message(arena, is_message_owned), + _extensions_(arena), + uninterpreted_option_(arena) { + SharedCtor(); + if (!is_message_owned) { + RegisterArenaDtor(arena); + } + // @@protoc_insertion_point(arena_constructor:google.protobuf.MethodOptions) +} +MethodOptions::MethodOptions(const MethodOptions& from) + : ::PROTOBUF_NAMESPACE_ID::Message(), + _has_bits_(from._has_bits_), + uninterpreted_option_(from.uninterpreted_option_) { + _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_); + _extensions_.MergeFrom(internal_default_instance(), from._extensions_); + ::memcpy(&deprecated_, &from.deprecated_, + static_cast<size_t>(reinterpret_cast<char*>(&idempotency_level_) - + reinterpret_cast<char*>(&deprecated_)) + sizeof(idempotency_level_)); + // @@protoc_insertion_point(copy_constructor:google.protobuf.MethodOptions) +} + +inline void MethodOptions::SharedCtor() { +::memset(reinterpret_cast<char*>(this) + static_cast<size_t>( + reinterpret_cast<char*>(&deprecated_) - reinterpret_cast<char*>(this)), + 0, static_cast<size_t>(reinterpret_cast<char*>(&idempotency_level_) - + reinterpret_cast<char*>(&deprecated_)) + sizeof(idempotency_level_)); +} + +MethodOptions::~MethodOptions() { + // @@protoc_insertion_point(destructor:google.protobuf.MethodOptions) + if (GetArenaForAllocation() != nullptr) return; + SharedDtor(); + _internal_metadata_.Delete<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(); +} + +inline void MethodOptions::SharedDtor() { + GOOGLE_DCHECK(GetArenaForAllocation() == nullptr); +} + +void MethodOptions::ArenaDtor(void* object) { + MethodOptions* _this = reinterpret_cast< MethodOptions* >(object); + (void)_this; +} +void MethodOptions::RegisterArenaDtor(::PROTOBUF_NAMESPACE_ID::Arena*) { +} +void MethodOptions::SetCachedSize(int size) const { + _cached_size_.Set(size); +} + +void MethodOptions::Clear() { +// @@protoc_insertion_point(message_clear_start:google.protobuf.MethodOptions) + arc_ui32 cached_has_bits = 0; + // Prevent compiler warnings about cached_has_bits being unused + (void) cached_has_bits; + + _extensions_.Clear(); + uninterpreted_option_.Clear(); + cached_has_bits = _has_bits_[0]; + if (cached_has_bits & 0x00000003u) { + ::memset(&deprecated_, 0, static_cast<size_t>( + reinterpret_cast<char*>(&idempotency_level_) - + reinterpret_cast<char*>(&deprecated_)) + sizeof(idempotency_level_)); + } + _has_bits_.Clear(); + _internal_metadata_.Clear<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(); +} + +const char* MethodOptions::_InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) { +#define CHK_(x) if (PROTOBUF_PREDICT_FALSE(!(x))) goto failure + _Internal::HasBits has_bits{}; + while (!ctx->Done(&ptr)) { + arc_ui32 tag; + ptr = ::PROTOBUF_NAMESPACE_ID::internal::ReadTag(ptr, &tag); + switch (tag >> 3) { + // optional bool deprecated = 33 [default = false]; + case 33: + if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 8)) { + _Internal::set_has_deprecated(&has_bits); + deprecated_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint64(&ptr); + CHK_(ptr); + } else + goto handle_unusual; + continue; + // optional .google.protobuf.MethodOptions.IdempotencyLevel idempotency_level = 34 [default = IDEMPOTENCY_UNKNOWN]; + case 34: + if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 16)) { + arc_ui64 val = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint64(&ptr); + CHK_(ptr); + if (PROTOBUF_PREDICT_TRUE(::PROTOBUF_NAMESPACE_ID::MethodOptions_IdempotencyLevel_IsValid(val))) { + _internal_set_idempotency_level(static_cast<::PROTOBUF_NAMESPACE_ID::MethodOptions_IdempotencyLevel>(val)); + } else { + ::PROTOBUF_NAMESPACE_ID::internal::WriteVarint(34, val, mutable_unknown_fields()); + } + } else + goto handle_unusual; + continue; + // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999; + case 999: + if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 58)) { + ptr -= 2; + do { + ptr += 2; + ptr = ctx->ParseMessage(_internal_add_uninterpreted_option(), ptr); + CHK_(ptr); + if (!ctx->DataAvailable(ptr)) break; + } while (::PROTOBUF_NAMESPACE_ID::internal::ExpectTag<7994>(ptr)); + } else + goto handle_unusual; + continue; + default: + goto handle_unusual; + } // switch + handle_unusual: + if ((tag == 0) || ((tag & 7) == 4)) { + CHK_(ptr); + ctx->SetLastTag(tag); + goto message_done; + } + if ((8000u <= tag)) { + ptr = _extensions_.ParseField(tag, ptr, internal_default_instance(), &_internal_metadata_, ctx); + CHK_(ptr != nullptr); + continue; + } + ptr = UnknownFieldParse( + tag, + _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(), + ptr, ctx); + CHK_(ptr != nullptr); + } // while +message_done: + _has_bits_.Or(has_bits); + return ptr; +failure: + ptr = nullptr; + goto message_done; +#undef CHK_ +} + +uint8_t* MethodOptions::_InternalSerialize( + uint8_t* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const { + // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.MethodOptions) + arc_ui32 cached_has_bits = 0; + (void) cached_has_bits; + + cached_has_bits = _has_bits_[0]; + // optional bool deprecated = 33 [default = false]; + if (cached_has_bits & 0x00000001u) { + target = stream->EnsureSpace(target); + target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteBoolToArray(33, this->_internal_deprecated(), target); + } + + // optional .google.protobuf.MethodOptions.IdempotencyLevel idempotency_level = 34 [default = IDEMPOTENCY_UNKNOWN]; + if (cached_has_bits & 0x00000002u) { + target = stream->EnsureSpace(target); + target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteEnumToArray( + 34, this->_internal_idempotency_level(), target); + } + + // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999; + for (unsigned int i = 0, + n = static_cast<unsigned int>(this->_internal_uninterpreted_option_size()); i < n; i++) { + target = stream->EnsureSpace(target); + target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite:: + InternalWriteMessage(999, this->_internal_uninterpreted_option(i), target, stream); + } + + // Extension range [1000, 536870912) + target = _extensions_._InternalSerialize( + internal_default_instance(), 1000, 536870912, target, stream); + + if (PROTOBUF_PREDICT_FALSE(_internal_metadata_.have_unknown_fields())) { + target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::InternalSerializeUnknownFieldsToArray( + _internal_metadata_.unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(::PROTOBUF_NAMESPACE_ID::UnknownFieldSet::default_instance), target, stream); + } + // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.MethodOptions) + return target; +} + +size_t MethodOptions::ByteSizeLong() const { +// @@protoc_insertion_point(message_byte_size_start:google.protobuf.MethodOptions) + size_t total_size = 0; + + total_size += _extensions_.ByteSize(); + + arc_ui32 cached_has_bits = 0; + // Prevent compiler warnings about cached_has_bits being unused + (void) cached_has_bits; + + // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999; + total_size += 2UL * this->_internal_uninterpreted_option_size(); + for (const auto& msg : this->uninterpreted_option_) { + total_size += + ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::MessageSize(msg); + } + + cached_has_bits = _has_bits_[0]; + if (cached_has_bits & 0x00000003u) { + // optional bool deprecated = 33 [default = false]; + if (cached_has_bits & 0x00000001u) { + total_size += 2 + 1; + } + + // optional .google.protobuf.MethodOptions.IdempotencyLevel idempotency_level = 34 [default = IDEMPOTENCY_UNKNOWN]; + if (cached_has_bits & 0x00000002u) { + total_size += 2 + + ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::EnumSize(this->_internal_idempotency_level()); + } + + } + return MaybeComputeUnknownFieldsSize(total_size, &_cached_size_); +} + +const ::PROTOBUF_NAMESPACE_ID::Message::ClassData MethodOptions::_class_data_ = { + ::PROTOBUF_NAMESPACE_ID::Message::CopyWithSizeCheck, + MethodOptions::MergeImpl +}; +const ::PROTOBUF_NAMESPACE_ID::Message::ClassData*MethodOptions::GetClassData() const { return &_class_data_; } + +void MethodOptions::MergeImpl(::PROTOBUF_NAMESPACE_ID::Message* to, + const ::PROTOBUF_NAMESPACE_ID::Message& from) { + static_cast<MethodOptions *>(to)->MergeFrom( + static_cast<const MethodOptions &>(from)); +} + + +void MethodOptions::MergeFrom(const MethodOptions& from) { +// @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.MethodOptions) + GOOGLE_DCHECK_NE(&from, this); + arc_ui32 cached_has_bits = 0; + (void) cached_has_bits; + + uninterpreted_option_.MergeFrom(from.uninterpreted_option_); + cached_has_bits = from._has_bits_[0]; + if (cached_has_bits & 0x00000003u) { + if (cached_has_bits & 0x00000001u) { + deprecated_ = from.deprecated_; + } + if (cached_has_bits & 0x00000002u) { + idempotency_level_ = from.idempotency_level_; + } + _has_bits_[0] |= cached_has_bits; + } + _extensions_.MergeFrom(internal_default_instance(), from._extensions_); + _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_); +} + +void MethodOptions::CopyFrom(const MethodOptions& from) { +// @@protoc_insertion_point(class_specific_copy_from_start:google.protobuf.MethodOptions) + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool MethodOptions::IsInitialized() const { + if (!_extensions_.IsInitialized()) { + return false; + } + + if (!::PROTOBUF_NAMESPACE_ID::internal::AllAreInitialized(uninterpreted_option_)) + return false; + return true; +} + +void MethodOptions::InternalSwap(MethodOptions* other) { + using std::swap; + _extensions_.InternalSwap(&other->_extensions_); + _internal_metadata_.InternalSwap(&other->_internal_metadata_); + swap(_has_bits_[0], other->_has_bits_[0]); + uninterpreted_option_.InternalSwap(&other->uninterpreted_option_); + ::PROTOBUF_NAMESPACE_ID::internal::memswap< + PROTOBUF_FIELD_OFFSET(MethodOptions, idempotency_level_) + + sizeof(MethodOptions::idempotency_level_) + - PROTOBUF_FIELD_OFFSET(MethodOptions, deprecated_)>( + reinterpret_cast<char*>(&deprecated_), + reinterpret_cast<char*>(&other->deprecated_)); +} + +::PROTOBUF_NAMESPACE_ID::Metadata MethodOptions::GetMetadata() const { + return ::PROTOBUF_NAMESPACE_ID::internal::AssignDescriptors( + &descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_getter, &descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_once, + file_level_metadata_google_2fprotobuf_2fdescriptor_2eproto[20]); +} + +// =================================================================== + +class UninterpretedOption_NamePart::_Internal { + public: + using HasBits = decltype(std::declval<UninterpretedOption_NamePart>()._has_bits_); + static void set_has_name_part(HasBits* has_bits) { + (*has_bits)[0] |= 1u; + } + static void set_has_is_extension(HasBits* has_bits) { + (*has_bits)[0] |= 2u; + } + static bool MissingRequiredFields(const HasBits& has_bits) { + return ((has_bits[0] & 0x00000003) ^ 0x00000003) != 0; + } +}; + +UninterpretedOption_NamePart::UninterpretedOption_NamePart(::PROTOBUF_NAMESPACE_ID::Arena* arena, + bool is_message_owned) + : ::PROTOBUF_NAMESPACE_ID::Message(arena, is_message_owned) { + SharedCtor(); + if (!is_message_owned) { + RegisterArenaDtor(arena); + } + // @@protoc_insertion_point(arena_constructor:google.protobuf.UninterpretedOption.NamePart) +} +UninterpretedOption_NamePart::UninterpretedOption_NamePart(const UninterpretedOption_NamePart& from) + : ::PROTOBUF_NAMESPACE_ID::Message(), + _has_bits_(from._has_bits_) { + _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_); + name_part_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); + #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING + name_part_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation()); + #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING + if (from._internal_has_name_part()) { + name_part_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, from._internal_name_part(), + GetArenaForAllocation()); + } + is_extension_ = from.is_extension_; + // @@protoc_insertion_point(copy_constructor:google.protobuf.UninterpretedOption.NamePart) +} + +inline void UninterpretedOption_NamePart::SharedCtor() { +name_part_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); +#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING + name_part_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation()); +#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING +is_extension_ = false; +} + +UninterpretedOption_NamePart::~UninterpretedOption_NamePart() { + // @@protoc_insertion_point(destructor:google.protobuf.UninterpretedOption.NamePart) + if (GetArenaForAllocation() != nullptr) return; + SharedDtor(); + _internal_metadata_.Delete<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(); +} + +inline void UninterpretedOption_NamePart::SharedDtor() { + GOOGLE_DCHECK(GetArenaForAllocation() == nullptr); + name_part_.DestroyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); +} + +void UninterpretedOption_NamePart::ArenaDtor(void* object) { + UninterpretedOption_NamePart* _this = reinterpret_cast< UninterpretedOption_NamePart* >(object); + (void)_this; +} +void UninterpretedOption_NamePart::RegisterArenaDtor(::PROTOBUF_NAMESPACE_ID::Arena*) { +} +void UninterpretedOption_NamePart::SetCachedSize(int size) const { + _cached_size_.Set(size); +} + +void UninterpretedOption_NamePart::Clear() { +// @@protoc_insertion_point(message_clear_start:google.protobuf.UninterpretedOption.NamePart) + arc_ui32 cached_has_bits = 0; + // Prevent compiler warnings about cached_has_bits being unused + (void) cached_has_bits; + + cached_has_bits = _has_bits_[0]; + if (cached_has_bits & 0x00000001u) { + name_part_.ClearNonDefaultToEmpty(); + } + is_extension_ = false; + _has_bits_.Clear(); + _internal_metadata_.Clear<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(); +} + +const char* UninterpretedOption_NamePart::_InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) { +#define CHK_(x) if (PROTOBUF_PREDICT_FALSE(!(x))) goto failure + _Internal::HasBits has_bits{}; + while (!ctx->Done(&ptr)) { + arc_ui32 tag; + ptr = ::PROTOBUF_NAMESPACE_ID::internal::ReadTag(ptr, &tag); + switch (tag >> 3) { + // required string name_part = 1; + case 1: + if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 10)) { + auto str = _internal_mutable_name_part(); + ptr = ::PROTOBUF_NAMESPACE_ID::internal::InlineGreedyStringParser(str, ptr, ctx); + #ifndef NDEBUG + ::PROTOBUF_NAMESPACE_ID::internal::VerifyUTF8(str, "google.protobuf.UninterpretedOption.NamePart.name_part"); + #endif // !NDEBUG + CHK_(ptr); + } else + goto handle_unusual; + continue; + // required bool is_extension = 2; + case 2: + if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 16)) { + _Internal::set_has_is_extension(&has_bits); + is_extension_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint64(&ptr); + CHK_(ptr); + } else + goto handle_unusual; + continue; + default: + goto handle_unusual; + } // switch + handle_unusual: + if ((tag == 0) || ((tag & 7) == 4)) { + CHK_(ptr); + ctx->SetLastTag(tag); + goto message_done; + } + ptr = UnknownFieldParse( + tag, + _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(), + ptr, ctx); + CHK_(ptr != nullptr); + } // while +message_done: + _has_bits_.Or(has_bits); + return ptr; +failure: + ptr = nullptr; + goto message_done; +#undef CHK_ +} + +uint8_t* UninterpretedOption_NamePart::_InternalSerialize( + uint8_t* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const { + // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.UninterpretedOption.NamePart) + arc_ui32 cached_has_bits = 0; + (void) cached_has_bits; + + cached_has_bits = _has_bits_[0]; + // required string name_part = 1; + if (cached_has_bits & 0x00000001u) { + ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::VerifyUTF8StringNamedField( + this->_internal_name_part().data(), static_cast<int>(this->_internal_name_part().length()), + ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::SERIALIZE, + "google.protobuf.UninterpretedOption.NamePart.name_part"); + target = stream->WriteStringMaybeAliased( + 1, this->_internal_name_part(), target); + } + + // required bool is_extension = 2; + if (cached_has_bits & 0x00000002u) { + target = stream->EnsureSpace(target); + target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteBoolToArray(2, this->_internal_is_extension(), target); + } + + if (PROTOBUF_PREDICT_FALSE(_internal_metadata_.have_unknown_fields())) { + target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::InternalSerializeUnknownFieldsToArray( + _internal_metadata_.unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(::PROTOBUF_NAMESPACE_ID::UnknownFieldSet::default_instance), target, stream); + } + // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.UninterpretedOption.NamePart) + return target; +} + +size_t UninterpretedOption_NamePart::RequiredFieldsByteSizeFallback() const { +// @@protoc_insertion_point(required_fields_byte_size_fallback_start:google.protobuf.UninterpretedOption.NamePart) + size_t total_size = 0; + + if (_internal_has_name_part()) { + // required string name_part = 1; + total_size += 1 + + ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::StringSize( + this->_internal_name_part()); + } + + if (_internal_has_is_extension()) { + // required bool is_extension = 2; + total_size += 1 + 1; + } + + return total_size; +} +size_t UninterpretedOption_NamePart::ByteSizeLong() const { +// @@protoc_insertion_point(message_byte_size_start:google.protobuf.UninterpretedOption.NamePart) + size_t total_size = 0; + + if (((_has_bits_[0] & 0x00000003) ^ 0x00000003) == 0) { // All required fields are present. + // required string name_part = 1; + total_size += 1 + + ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::StringSize( + this->_internal_name_part()); + + // required bool is_extension = 2; + total_size += 1 + 1; + + } else { + total_size += RequiredFieldsByteSizeFallback(); + } + arc_ui32 cached_has_bits = 0; + // Prevent compiler warnings about cached_has_bits being unused + (void) cached_has_bits; + + return MaybeComputeUnknownFieldsSize(total_size, &_cached_size_); +} + +const ::PROTOBUF_NAMESPACE_ID::Message::ClassData UninterpretedOption_NamePart::_class_data_ = { + ::PROTOBUF_NAMESPACE_ID::Message::CopyWithSizeCheck, + UninterpretedOption_NamePart::MergeImpl +}; +const ::PROTOBUF_NAMESPACE_ID::Message::ClassData*UninterpretedOption_NamePart::GetClassData() const { return &_class_data_; } + +void UninterpretedOption_NamePart::MergeImpl(::PROTOBUF_NAMESPACE_ID::Message* to, + const ::PROTOBUF_NAMESPACE_ID::Message& from) { + static_cast<UninterpretedOption_NamePart *>(to)->MergeFrom( + static_cast<const UninterpretedOption_NamePart &>(from)); +} + + +void UninterpretedOption_NamePart::MergeFrom(const UninterpretedOption_NamePart& from) { +// @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.UninterpretedOption.NamePart) + GOOGLE_DCHECK_NE(&from, this); + arc_ui32 cached_has_bits = 0; + (void) cached_has_bits; + + cached_has_bits = from._has_bits_[0]; + if (cached_has_bits & 0x00000003u) { + if (cached_has_bits & 0x00000001u) { + _internal_set_name_part(from._internal_name_part()); + } + if (cached_has_bits & 0x00000002u) { + is_extension_ = from.is_extension_; + } + _has_bits_[0] |= cached_has_bits; + } + _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_); +} + +void UninterpretedOption_NamePart::CopyFrom(const UninterpretedOption_NamePart& from) { +// @@protoc_insertion_point(class_specific_copy_from_start:google.protobuf.UninterpretedOption.NamePart) + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool UninterpretedOption_NamePart::IsInitialized() const { + if (_Internal::MissingRequiredFields(_has_bits_)) return false; + return true; +} + +void UninterpretedOption_NamePart::InternalSwap(UninterpretedOption_NamePart* other) { + using std::swap; + auto* lhs_arena = GetArenaForAllocation(); + auto* rhs_arena = other->GetArenaForAllocation(); + _internal_metadata_.InternalSwap(&other->_internal_metadata_); + swap(_has_bits_[0], other->_has_bits_[0]); + ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::InternalSwap( + &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), + &name_part_, lhs_arena, + &other->name_part_, rhs_arena + ); + swap(is_extension_, other->is_extension_); +} + +::PROTOBUF_NAMESPACE_ID::Metadata UninterpretedOption_NamePart::GetMetadata() const { + return ::PROTOBUF_NAMESPACE_ID::internal::AssignDescriptors( + &descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_getter, &descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_once, + file_level_metadata_google_2fprotobuf_2fdescriptor_2eproto[21]); +} + +// =================================================================== + +class UninterpretedOption::_Internal { + public: + using HasBits = decltype(std::declval<UninterpretedOption>()._has_bits_); + static void set_has_identifier_value(HasBits* has_bits) { + (*has_bits)[0] |= 1u; + } + static void set_has_positive_int_value(HasBits* has_bits) { + (*has_bits)[0] |= 8u; + } + static void set_has_negative_int_value(HasBits* has_bits) { + (*has_bits)[0] |= 16u; + } + static void set_has_double_value(HasBits* has_bits) { + (*has_bits)[0] |= 32u; + } + static void set_has_string_value(HasBits* has_bits) { + (*has_bits)[0] |= 2u; + } + static void set_has_aggregate_value(HasBits* has_bits) { + (*has_bits)[0] |= 4u; + } +}; + +UninterpretedOption::UninterpretedOption(::PROTOBUF_NAMESPACE_ID::Arena* arena, + bool is_message_owned) + : ::PROTOBUF_NAMESPACE_ID::Message(arena, is_message_owned), + name_(arena) { + SharedCtor(); + if (!is_message_owned) { + RegisterArenaDtor(arena); + } + // @@protoc_insertion_point(arena_constructor:google.protobuf.UninterpretedOption) +} +UninterpretedOption::UninterpretedOption(const UninterpretedOption& from) + : ::PROTOBUF_NAMESPACE_ID::Message(), + _has_bits_(from._has_bits_), + name_(from.name_) { + _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_); + identifier_value_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); + #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING + identifier_value_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation()); + #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING + if (from._internal_has_identifier_value()) { + identifier_value_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, from._internal_identifier_value(), + GetArenaForAllocation()); + } + string_value_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); + #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING + string_value_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation()); + #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING + if (from._internal_has_string_value()) { + string_value_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, from._internal_string_value(), + GetArenaForAllocation()); + } + aggregate_value_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); + #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING + aggregate_value_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation()); + #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING + if (from._internal_has_aggregate_value()) { + aggregate_value_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, from._internal_aggregate_value(), + GetArenaForAllocation()); + } + ::memcpy(&positive_int_value_, &from.positive_int_value_, + static_cast<size_t>(reinterpret_cast<char*>(&double_value_) - + reinterpret_cast<char*>(&positive_int_value_)) + sizeof(double_value_)); + // @@protoc_insertion_point(copy_constructor:google.protobuf.UninterpretedOption) +} + +inline void UninterpretedOption::SharedCtor() { +identifier_value_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); +#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING + identifier_value_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation()); +#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING +string_value_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); +#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING + string_value_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation()); +#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING +aggregate_value_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); +#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING + aggregate_value_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation()); +#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING +::memset(reinterpret_cast<char*>(this) + static_cast<size_t>( + reinterpret_cast<char*>(&positive_int_value_) - reinterpret_cast<char*>(this)), + 0, static_cast<size_t>(reinterpret_cast<char*>(&double_value_) - + reinterpret_cast<char*>(&positive_int_value_)) + sizeof(double_value_)); +} + +UninterpretedOption::~UninterpretedOption() { + // @@protoc_insertion_point(destructor:google.protobuf.UninterpretedOption) + if (GetArenaForAllocation() != nullptr) return; + SharedDtor(); + _internal_metadata_.Delete<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(); +} + +inline void UninterpretedOption::SharedDtor() { + GOOGLE_DCHECK(GetArenaForAllocation() == nullptr); + identifier_value_.DestroyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); + string_value_.DestroyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); + aggregate_value_.DestroyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); +} + +void UninterpretedOption::ArenaDtor(void* object) { + UninterpretedOption* _this = reinterpret_cast< UninterpretedOption* >(object); + (void)_this; +} +void UninterpretedOption::RegisterArenaDtor(::PROTOBUF_NAMESPACE_ID::Arena*) { +} +void UninterpretedOption::SetCachedSize(int size) const { + _cached_size_.Set(size); +} + +void UninterpretedOption::Clear() { +// @@protoc_insertion_point(message_clear_start:google.protobuf.UninterpretedOption) + arc_ui32 cached_has_bits = 0; + // Prevent compiler warnings about cached_has_bits being unused + (void) cached_has_bits; + + name_.Clear(); + cached_has_bits = _has_bits_[0]; + if (cached_has_bits & 0x00000007u) { + if (cached_has_bits & 0x00000001u) { + identifier_value_.ClearNonDefaultToEmpty(); + } + if (cached_has_bits & 0x00000002u) { + string_value_.ClearNonDefaultToEmpty(); + } + if (cached_has_bits & 0x00000004u) { + aggregate_value_.ClearNonDefaultToEmpty(); + } + } + if (cached_has_bits & 0x00000038u) { + ::memset(&positive_int_value_, 0, static_cast<size_t>( + reinterpret_cast<char*>(&double_value_) - + reinterpret_cast<char*>(&positive_int_value_)) + sizeof(double_value_)); + } + _has_bits_.Clear(); + _internal_metadata_.Clear<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(); +} + +const char* UninterpretedOption::_InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) { +#define CHK_(x) if (PROTOBUF_PREDICT_FALSE(!(x))) goto failure + _Internal::HasBits has_bits{}; + while (!ctx->Done(&ptr)) { + arc_ui32 tag; + ptr = ::PROTOBUF_NAMESPACE_ID::internal::ReadTag(ptr, &tag); + switch (tag >> 3) { + // repeated .google.protobuf.UninterpretedOption.NamePart name = 2; + case 2: + if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 18)) { + ptr -= 1; + do { + ptr += 1; + ptr = ctx->ParseMessage(_internal_add_name(), ptr); + CHK_(ptr); + if (!ctx->DataAvailable(ptr)) break; + } while (::PROTOBUF_NAMESPACE_ID::internal::ExpectTag<18>(ptr)); + } else + goto handle_unusual; + continue; + // optional string identifier_value = 3; + case 3: + if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 26)) { + auto str = _internal_mutable_identifier_value(); + ptr = ::PROTOBUF_NAMESPACE_ID::internal::InlineGreedyStringParser(str, ptr, ctx); + #ifndef NDEBUG + ::PROTOBUF_NAMESPACE_ID::internal::VerifyUTF8(str, "google.protobuf.UninterpretedOption.identifier_value"); + #endif // !NDEBUG + CHK_(ptr); + } else + goto handle_unusual; + continue; + // optional uint64 positive_int_value = 4; + case 4: + if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 32)) { + _Internal::set_has_positive_int_value(&has_bits); + positive_int_value_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint64(&ptr); + CHK_(ptr); + } else + goto handle_unusual; + continue; + // optional int64 negative_int_value = 5; + case 5: + if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 40)) { + _Internal::set_has_negative_int_value(&has_bits); + negative_int_value_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint64(&ptr); + CHK_(ptr); + } else + goto handle_unusual; + continue; + // optional double double_value = 6; + case 6: + if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 49)) { + _Internal::set_has_double_value(&has_bits); + double_value_ = ::PROTOBUF_NAMESPACE_ID::internal::UnalignedLoad<double>(ptr); + ptr += sizeof(double); + } else + goto handle_unusual; + continue; + // optional bytes string_value = 7; + case 7: + if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 58)) { + auto str = _internal_mutable_string_value(); + ptr = ::PROTOBUF_NAMESPACE_ID::internal::InlineGreedyStringParser(str, ptr, ctx); + CHK_(ptr); + } else + goto handle_unusual; + continue; + // optional string aggregate_value = 8; + case 8: + if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 66)) { + auto str = _internal_mutable_aggregate_value(); + ptr = ::PROTOBUF_NAMESPACE_ID::internal::InlineGreedyStringParser(str, ptr, ctx); + #ifndef NDEBUG + ::PROTOBUF_NAMESPACE_ID::internal::VerifyUTF8(str, "google.protobuf.UninterpretedOption.aggregate_value"); + #endif // !NDEBUG + CHK_(ptr); + } else + goto handle_unusual; + continue; + default: + goto handle_unusual; + } // switch + handle_unusual: + if ((tag == 0) || ((tag & 7) == 4)) { + CHK_(ptr); + ctx->SetLastTag(tag); + goto message_done; + } + ptr = UnknownFieldParse( + tag, + _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(), + ptr, ctx); + CHK_(ptr != nullptr); + } // while +message_done: + _has_bits_.Or(has_bits); + return ptr; +failure: + ptr = nullptr; + goto message_done; +#undef CHK_ +} + +uint8_t* UninterpretedOption::_InternalSerialize( + uint8_t* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const { + // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.UninterpretedOption) + arc_ui32 cached_has_bits = 0; + (void) cached_has_bits; + + // repeated .google.protobuf.UninterpretedOption.NamePart name = 2; + for (unsigned int i = 0, + n = static_cast<unsigned int>(this->_internal_name_size()); i < n; i++) { + target = stream->EnsureSpace(target); + target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite:: + InternalWriteMessage(2, this->_internal_name(i), target, stream); + } + + cached_has_bits = _has_bits_[0]; + // optional string identifier_value = 3; + if (cached_has_bits & 0x00000001u) { + ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::VerifyUTF8StringNamedField( + this->_internal_identifier_value().data(), static_cast<int>(this->_internal_identifier_value().length()), + ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::SERIALIZE, + "google.protobuf.UninterpretedOption.identifier_value"); + target = stream->WriteStringMaybeAliased( + 3, this->_internal_identifier_value(), target); + } + + // optional uint64 positive_int_value = 4; + if (cached_has_bits & 0x00000008u) { + target = stream->EnsureSpace(target); + target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteUInt64ToArray(4, this->_internal_positive_int_value(), target); + } + + // optional int64 negative_int_value = 5; + if (cached_has_bits & 0x00000010u) { + target = stream->EnsureSpace(target); + target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteInt64ToArray(5, this->_internal_negative_int_value(), target); + } + + // optional double double_value = 6; + if (cached_has_bits & 0x00000020u) { + target = stream->EnsureSpace(target); + target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteDoubleToArray(6, this->_internal_double_value(), target); + } + + // optional bytes string_value = 7; + if (cached_has_bits & 0x00000002u) { + target = stream->WriteBytesMaybeAliased( + 7, this->_internal_string_value(), target); + } + + // optional string aggregate_value = 8; + if (cached_has_bits & 0x00000004u) { + ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::VerifyUTF8StringNamedField( + this->_internal_aggregate_value().data(), static_cast<int>(this->_internal_aggregate_value().length()), + ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::SERIALIZE, + "google.protobuf.UninterpretedOption.aggregate_value"); + target = stream->WriteStringMaybeAliased( + 8, this->_internal_aggregate_value(), target); + } + + if (PROTOBUF_PREDICT_FALSE(_internal_metadata_.have_unknown_fields())) { + target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::InternalSerializeUnknownFieldsToArray( + _internal_metadata_.unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(::PROTOBUF_NAMESPACE_ID::UnknownFieldSet::default_instance), target, stream); + } + // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.UninterpretedOption) + return target; +} + +size_t UninterpretedOption::ByteSizeLong() const { +// @@protoc_insertion_point(message_byte_size_start:google.protobuf.UninterpretedOption) + size_t total_size = 0; + + arc_ui32 cached_has_bits = 0; + // Prevent compiler warnings about cached_has_bits being unused + (void) cached_has_bits; + + // repeated .google.protobuf.UninterpretedOption.NamePart name = 2; + total_size += 1UL * this->_internal_name_size(); + for (const auto& msg : this->name_) { + total_size += + ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::MessageSize(msg); + } + + cached_has_bits = _has_bits_[0]; + if (cached_has_bits & 0x0000003fu) { + // optional string identifier_value = 3; + if (cached_has_bits & 0x00000001u) { + total_size += 1 + + ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::StringSize( + this->_internal_identifier_value()); + } + + // optional bytes string_value = 7; + if (cached_has_bits & 0x00000002u) { + total_size += 1 + + ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::BytesSize( + this->_internal_string_value()); + } + + // optional string aggregate_value = 8; + if (cached_has_bits & 0x00000004u) { + total_size += 1 + + ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::StringSize( + this->_internal_aggregate_value()); + } + + // optional uint64 positive_int_value = 4; + if (cached_has_bits & 0x00000008u) { + total_size += ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::UInt64SizePlusOne(this->_internal_positive_int_value()); + } + + // optional int64 negative_int_value = 5; + if (cached_has_bits & 0x00000010u) { + total_size += ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::Int64SizePlusOne(this->_internal_negative_int_value()); + } + + // optional double double_value = 6; + if (cached_has_bits & 0x00000020u) { + total_size += 1 + 8; + } + + } + return MaybeComputeUnknownFieldsSize(total_size, &_cached_size_); +} + +const ::PROTOBUF_NAMESPACE_ID::Message::ClassData UninterpretedOption::_class_data_ = { + ::PROTOBUF_NAMESPACE_ID::Message::CopyWithSizeCheck, + UninterpretedOption::MergeImpl +}; +const ::PROTOBUF_NAMESPACE_ID::Message::ClassData*UninterpretedOption::GetClassData() const { return &_class_data_; } + +void UninterpretedOption::MergeImpl(::PROTOBUF_NAMESPACE_ID::Message* to, + const ::PROTOBUF_NAMESPACE_ID::Message& from) { + static_cast<UninterpretedOption *>(to)->MergeFrom( + static_cast<const UninterpretedOption &>(from)); +} + + +void UninterpretedOption::MergeFrom(const UninterpretedOption& from) { +// @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.UninterpretedOption) + GOOGLE_DCHECK_NE(&from, this); + arc_ui32 cached_has_bits = 0; + (void) cached_has_bits; + + name_.MergeFrom(from.name_); + cached_has_bits = from._has_bits_[0]; + if (cached_has_bits & 0x0000003fu) { + if (cached_has_bits & 0x00000001u) { + _internal_set_identifier_value(from._internal_identifier_value()); + } + if (cached_has_bits & 0x00000002u) { + _internal_set_string_value(from._internal_string_value()); + } + if (cached_has_bits & 0x00000004u) { + _internal_set_aggregate_value(from._internal_aggregate_value()); + } + if (cached_has_bits & 0x00000008u) { + positive_int_value_ = from.positive_int_value_; + } + if (cached_has_bits & 0x00000010u) { + negative_int_value_ = from.negative_int_value_; + } + if (cached_has_bits & 0x00000020u) { + double_value_ = from.double_value_; + } + _has_bits_[0] |= cached_has_bits; + } + _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_); +} + +void UninterpretedOption::CopyFrom(const UninterpretedOption& from) { +// @@protoc_insertion_point(class_specific_copy_from_start:google.protobuf.UninterpretedOption) + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool UninterpretedOption::IsInitialized() const { + if (!::PROTOBUF_NAMESPACE_ID::internal::AllAreInitialized(name_)) + return false; + return true; +} + +void UninterpretedOption::InternalSwap(UninterpretedOption* other) { + using std::swap; + auto* lhs_arena = GetArenaForAllocation(); + auto* rhs_arena = other->GetArenaForAllocation(); + _internal_metadata_.InternalSwap(&other->_internal_metadata_); + swap(_has_bits_[0], other->_has_bits_[0]); + name_.InternalSwap(&other->name_); + ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::InternalSwap( + &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), + &identifier_value_, lhs_arena, + &other->identifier_value_, rhs_arena + ); + ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::InternalSwap( + &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), + &string_value_, lhs_arena, + &other->string_value_, rhs_arena + ); + ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::InternalSwap( + &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), + &aggregate_value_, lhs_arena, + &other->aggregate_value_, rhs_arena + ); + ::PROTOBUF_NAMESPACE_ID::internal::memswap< + PROTOBUF_FIELD_OFFSET(UninterpretedOption, double_value_) + + sizeof(UninterpretedOption::double_value_) + - PROTOBUF_FIELD_OFFSET(UninterpretedOption, positive_int_value_)>( + reinterpret_cast<char*>(&positive_int_value_), + reinterpret_cast<char*>(&other->positive_int_value_)); +} + +::PROTOBUF_NAMESPACE_ID::Metadata UninterpretedOption::GetMetadata() const { + return ::PROTOBUF_NAMESPACE_ID::internal::AssignDescriptors( + &descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_getter, &descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_once, + file_level_metadata_google_2fprotobuf_2fdescriptor_2eproto[22]); +} + +// =================================================================== + +class SourceCodeInfo_Location::_Internal { + public: + using HasBits = decltype(std::declval<SourceCodeInfo_Location>()._has_bits_); + static void set_has_leading_comments(HasBits* has_bits) { + (*has_bits)[0] |= 1u; + } + static void set_has_trailing_comments(HasBits* has_bits) { + (*has_bits)[0] |= 2u; + } +}; + +SourceCodeInfo_Location::SourceCodeInfo_Location(::PROTOBUF_NAMESPACE_ID::Arena* arena, + bool is_message_owned) + : ::PROTOBUF_NAMESPACE_ID::Message(arena, is_message_owned), + path_(arena), + span_(arena), + leading_detached_comments_(arena) { + SharedCtor(); + if (!is_message_owned) { + RegisterArenaDtor(arena); + } + // @@protoc_insertion_point(arena_constructor:google.protobuf.SourceCodeInfo.Location) +} +SourceCodeInfo_Location::SourceCodeInfo_Location(const SourceCodeInfo_Location& from) + : ::PROTOBUF_NAMESPACE_ID::Message(), + _has_bits_(from._has_bits_), + path_(from.path_), + span_(from.span_), + leading_detached_comments_(from.leading_detached_comments_) { + _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_); + leading_comments_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); + #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING + leading_comments_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation()); + #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING + if (from._internal_has_leading_comments()) { + leading_comments_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, from._internal_leading_comments(), + GetArenaForAllocation()); + } + trailing_comments_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); + #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING + trailing_comments_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation()); + #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING + if (from._internal_has_trailing_comments()) { + trailing_comments_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, from._internal_trailing_comments(), + GetArenaForAllocation()); + } + // @@protoc_insertion_point(copy_constructor:google.protobuf.SourceCodeInfo.Location) +} + +inline void SourceCodeInfo_Location::SharedCtor() { +leading_comments_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); +#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING + leading_comments_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation()); +#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING +trailing_comments_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); +#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING + trailing_comments_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation()); +#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING +} + +SourceCodeInfo_Location::~SourceCodeInfo_Location() { + // @@protoc_insertion_point(destructor:google.protobuf.SourceCodeInfo.Location) + if (GetArenaForAllocation() != nullptr) return; + SharedDtor(); + _internal_metadata_.Delete<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(); +} + +inline void SourceCodeInfo_Location::SharedDtor() { + GOOGLE_DCHECK(GetArenaForAllocation() == nullptr); + leading_comments_.DestroyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); + trailing_comments_.DestroyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); +} + +void SourceCodeInfo_Location::ArenaDtor(void* object) { + SourceCodeInfo_Location* _this = reinterpret_cast< SourceCodeInfo_Location* >(object); + (void)_this; +} +void SourceCodeInfo_Location::RegisterArenaDtor(::PROTOBUF_NAMESPACE_ID::Arena*) { +} +void SourceCodeInfo_Location::SetCachedSize(int size) const { + _cached_size_.Set(size); +} + +void SourceCodeInfo_Location::Clear() { +// @@protoc_insertion_point(message_clear_start:google.protobuf.SourceCodeInfo.Location) + arc_ui32 cached_has_bits = 0; + // Prevent compiler warnings about cached_has_bits being unused + (void) cached_has_bits; + + path_.Clear(); + span_.Clear(); + leading_detached_comments_.Clear(); + cached_has_bits = _has_bits_[0]; + if (cached_has_bits & 0x00000003u) { + if (cached_has_bits & 0x00000001u) { + leading_comments_.ClearNonDefaultToEmpty(); + } + if (cached_has_bits & 0x00000002u) { + trailing_comments_.ClearNonDefaultToEmpty(); + } + } + _has_bits_.Clear(); + _internal_metadata_.Clear<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(); +} + +const char* SourceCodeInfo_Location::_InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) { +#define CHK_(x) if (PROTOBUF_PREDICT_FALSE(!(x))) goto failure + _Internal::HasBits has_bits{}; + while (!ctx->Done(&ptr)) { + arc_ui32 tag; + ptr = ::PROTOBUF_NAMESPACE_ID::internal::ReadTag(ptr, &tag); + switch (tag >> 3) { + // repeated int32 path = 1 [packed = true]; + case 1: + if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 10)) { + ptr = ::PROTOBUF_NAMESPACE_ID::internal::PackedInt32Parser(_internal_mutable_path(), ptr, ctx); + CHK_(ptr); + } else if (static_cast<uint8_t>(tag) == 8) { + _internal_add_path(::PROTOBUF_NAMESPACE_ID::internal::ReadVarint32(&ptr)); + CHK_(ptr); + } else + goto handle_unusual; + continue; + // repeated int32 span = 2 [packed = true]; + case 2: + if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 18)) { + ptr = ::PROTOBUF_NAMESPACE_ID::internal::PackedInt32Parser(_internal_mutable_span(), ptr, ctx); + CHK_(ptr); + } else if (static_cast<uint8_t>(tag) == 16) { + _internal_add_span(::PROTOBUF_NAMESPACE_ID::internal::ReadVarint32(&ptr)); + CHK_(ptr); + } else + goto handle_unusual; + continue; + // optional string leading_comments = 3; + case 3: + if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 26)) { + auto str = _internal_mutable_leading_comments(); + ptr = ::PROTOBUF_NAMESPACE_ID::internal::InlineGreedyStringParser(str, ptr, ctx); + #ifndef NDEBUG + ::PROTOBUF_NAMESPACE_ID::internal::VerifyUTF8(str, "google.protobuf.SourceCodeInfo.Location.leading_comments"); + #endif // !NDEBUG + CHK_(ptr); + } else + goto handle_unusual; + continue; + // optional string trailing_comments = 4; + case 4: + if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 34)) { + auto str = _internal_mutable_trailing_comments(); + ptr = ::PROTOBUF_NAMESPACE_ID::internal::InlineGreedyStringParser(str, ptr, ctx); + #ifndef NDEBUG + ::PROTOBUF_NAMESPACE_ID::internal::VerifyUTF8(str, "google.protobuf.SourceCodeInfo.Location.trailing_comments"); + #endif // !NDEBUG + CHK_(ptr); + } else + goto handle_unusual; + continue; + // repeated string leading_detached_comments = 6; + case 6: + if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 50)) { + ptr -= 1; + do { + ptr += 1; + auto str = _internal_add_leading_detached_comments(); + ptr = ::PROTOBUF_NAMESPACE_ID::internal::InlineGreedyStringParser(str, ptr, ctx); + #ifndef NDEBUG + ::PROTOBUF_NAMESPACE_ID::internal::VerifyUTF8(str, "google.protobuf.SourceCodeInfo.Location.leading_detached_comments"); + #endif // !NDEBUG + CHK_(ptr); + if (!ctx->DataAvailable(ptr)) break; + } while (::PROTOBUF_NAMESPACE_ID::internal::ExpectTag<50>(ptr)); + } else + goto handle_unusual; + continue; + default: + goto handle_unusual; + } // switch + handle_unusual: + if ((tag == 0) || ((tag & 7) == 4)) { + CHK_(ptr); + ctx->SetLastTag(tag); + goto message_done; + } + ptr = UnknownFieldParse( + tag, + _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(), + ptr, ctx); + CHK_(ptr != nullptr); + } // while +message_done: + _has_bits_.Or(has_bits); + return ptr; +failure: + ptr = nullptr; + goto message_done; +#undef CHK_ +} + +uint8_t* SourceCodeInfo_Location::_InternalSerialize( + uint8_t* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const { + // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.SourceCodeInfo.Location) + arc_ui32 cached_has_bits = 0; + (void) cached_has_bits; + + // repeated int32 path = 1 [packed = true]; + { + int byte_size = _path_cached_byte_size_.load(std::memory_order_relaxed); + if (byte_size > 0) { + target = stream->WriteInt32Packed( + 1, _internal_path(), byte_size, target); + } + } + + // repeated int32 span = 2 [packed = true]; + { + int byte_size = _span_cached_byte_size_.load(std::memory_order_relaxed); + if (byte_size > 0) { + target = stream->WriteInt32Packed( + 2, _internal_span(), byte_size, target); + } + } + + cached_has_bits = _has_bits_[0]; + // optional string leading_comments = 3; + if (cached_has_bits & 0x00000001u) { + ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::VerifyUTF8StringNamedField( + this->_internal_leading_comments().data(), static_cast<int>(this->_internal_leading_comments().length()), + ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::SERIALIZE, + "google.protobuf.SourceCodeInfo.Location.leading_comments"); + target = stream->WriteStringMaybeAliased( + 3, this->_internal_leading_comments(), target); + } + + // optional string trailing_comments = 4; + if (cached_has_bits & 0x00000002u) { + ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::VerifyUTF8StringNamedField( + this->_internal_trailing_comments().data(), static_cast<int>(this->_internal_trailing_comments().length()), + ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::SERIALIZE, + "google.protobuf.SourceCodeInfo.Location.trailing_comments"); + target = stream->WriteStringMaybeAliased( + 4, this->_internal_trailing_comments(), target); + } + + // repeated string leading_detached_comments = 6; + for (int i = 0, n = this->_internal_leading_detached_comments_size(); i < n; i++) { + const auto& s = this->_internal_leading_detached_comments(i); + ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::VerifyUTF8StringNamedField( + s.data(), static_cast<int>(s.length()), + ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::SERIALIZE, + "google.protobuf.SourceCodeInfo.Location.leading_detached_comments"); + target = stream->WriteString(6, s, target); + } + + if (PROTOBUF_PREDICT_FALSE(_internal_metadata_.have_unknown_fields())) { + target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::InternalSerializeUnknownFieldsToArray( + _internal_metadata_.unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(::PROTOBUF_NAMESPACE_ID::UnknownFieldSet::default_instance), target, stream); + } + // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.SourceCodeInfo.Location) + return target; +} + +size_t SourceCodeInfo_Location::ByteSizeLong() const { +// @@protoc_insertion_point(message_byte_size_start:google.protobuf.SourceCodeInfo.Location) + size_t total_size = 0; + + arc_ui32 cached_has_bits = 0; + // Prevent compiler warnings about cached_has_bits being unused + (void) cached_has_bits; + + // repeated int32 path = 1 [packed = true]; + { + size_t data_size = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite:: + Int32Size(this->path_); + if (data_size > 0) { + total_size += 1 + + ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::Int32Size( + static_cast<arc_i32>(data_size)); + } + int cached_size = ::PROTOBUF_NAMESPACE_ID::internal::ToCachedSize(data_size); + _path_cached_byte_size_.store(cached_size, + std::memory_order_relaxed); + total_size += data_size; + } + + // repeated int32 span = 2 [packed = true]; + { + size_t data_size = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite:: + Int32Size(this->span_); + if (data_size > 0) { + total_size += 1 + + ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::Int32Size( + static_cast<arc_i32>(data_size)); + } + int cached_size = ::PROTOBUF_NAMESPACE_ID::internal::ToCachedSize(data_size); + _span_cached_byte_size_.store(cached_size, + std::memory_order_relaxed); + total_size += data_size; + } + + // repeated string leading_detached_comments = 6; + total_size += 1 * + ::PROTOBUF_NAMESPACE_ID::internal::FromIntSize(leading_detached_comments_.size()); + for (int i = 0, n = leading_detached_comments_.size(); i < n; i++) { + total_size += ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::StringSize( + leading_detached_comments_.Get(i)); + } + + cached_has_bits = _has_bits_[0]; + if (cached_has_bits & 0x00000003u) { + // optional string leading_comments = 3; + if (cached_has_bits & 0x00000001u) { + total_size += 1 + + ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::StringSize( + this->_internal_leading_comments()); + } + + // optional string trailing_comments = 4; + if (cached_has_bits & 0x00000002u) { + total_size += 1 + + ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::StringSize( + this->_internal_trailing_comments()); + } + + } + return MaybeComputeUnknownFieldsSize(total_size, &_cached_size_); +} + +const ::PROTOBUF_NAMESPACE_ID::Message::ClassData SourceCodeInfo_Location::_class_data_ = { + ::PROTOBUF_NAMESPACE_ID::Message::CopyWithSizeCheck, + SourceCodeInfo_Location::MergeImpl +}; +const ::PROTOBUF_NAMESPACE_ID::Message::ClassData*SourceCodeInfo_Location::GetClassData() const { return &_class_data_; } + +void SourceCodeInfo_Location::MergeImpl(::PROTOBUF_NAMESPACE_ID::Message* to, + const ::PROTOBUF_NAMESPACE_ID::Message& from) { + static_cast<SourceCodeInfo_Location *>(to)->MergeFrom( + static_cast<const SourceCodeInfo_Location &>(from)); +} + + +void SourceCodeInfo_Location::MergeFrom(const SourceCodeInfo_Location& from) { +// @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.SourceCodeInfo.Location) + GOOGLE_DCHECK_NE(&from, this); + arc_ui32 cached_has_bits = 0; + (void) cached_has_bits; + + path_.MergeFrom(from.path_); + span_.MergeFrom(from.span_); + leading_detached_comments_.MergeFrom(from.leading_detached_comments_); + cached_has_bits = from._has_bits_[0]; + if (cached_has_bits & 0x00000003u) { + if (cached_has_bits & 0x00000001u) { + _internal_set_leading_comments(from._internal_leading_comments()); + } + if (cached_has_bits & 0x00000002u) { + _internal_set_trailing_comments(from._internal_trailing_comments()); + } + } + _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_); +} + +void SourceCodeInfo_Location::CopyFrom(const SourceCodeInfo_Location& from) { +// @@protoc_insertion_point(class_specific_copy_from_start:google.protobuf.SourceCodeInfo.Location) + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool SourceCodeInfo_Location::IsInitialized() const { + return true; +} + +void SourceCodeInfo_Location::InternalSwap(SourceCodeInfo_Location* other) { + using std::swap; + auto* lhs_arena = GetArenaForAllocation(); + auto* rhs_arena = other->GetArenaForAllocation(); + _internal_metadata_.InternalSwap(&other->_internal_metadata_); + swap(_has_bits_[0], other->_has_bits_[0]); + path_.InternalSwap(&other->path_); + span_.InternalSwap(&other->span_); + leading_detached_comments_.InternalSwap(&other->leading_detached_comments_); + ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::InternalSwap( + &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), + &leading_comments_, lhs_arena, + &other->leading_comments_, rhs_arena + ); + ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::InternalSwap( + &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), + &trailing_comments_, lhs_arena, + &other->trailing_comments_, rhs_arena + ); +} + +::PROTOBUF_NAMESPACE_ID::Metadata SourceCodeInfo_Location::GetMetadata() const { + return ::PROTOBUF_NAMESPACE_ID::internal::AssignDescriptors( + &descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_getter, &descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_once, + file_level_metadata_google_2fprotobuf_2fdescriptor_2eproto[23]); +} + +// =================================================================== + +class SourceCodeInfo::_Internal { + public: +}; + +SourceCodeInfo::SourceCodeInfo(::PROTOBUF_NAMESPACE_ID::Arena* arena, + bool is_message_owned) + : ::PROTOBUF_NAMESPACE_ID::Message(arena, is_message_owned), + location_(arena) { + SharedCtor(); + if (!is_message_owned) { + RegisterArenaDtor(arena); + } + // @@protoc_insertion_point(arena_constructor:google.protobuf.SourceCodeInfo) +} +SourceCodeInfo::SourceCodeInfo(const SourceCodeInfo& from) + : ::PROTOBUF_NAMESPACE_ID::Message(), + location_(from.location_) { + _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_); + // @@protoc_insertion_point(copy_constructor:google.protobuf.SourceCodeInfo) +} + +inline void SourceCodeInfo::SharedCtor() { +} + +SourceCodeInfo::~SourceCodeInfo() { + // @@protoc_insertion_point(destructor:google.protobuf.SourceCodeInfo) + if (GetArenaForAllocation() != nullptr) return; + SharedDtor(); + _internal_metadata_.Delete<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(); +} + +inline void SourceCodeInfo::SharedDtor() { + GOOGLE_DCHECK(GetArenaForAllocation() == nullptr); +} + +void SourceCodeInfo::ArenaDtor(void* object) { + SourceCodeInfo* _this = reinterpret_cast< SourceCodeInfo* >(object); + (void)_this; +} +void SourceCodeInfo::RegisterArenaDtor(::PROTOBUF_NAMESPACE_ID::Arena*) { +} +void SourceCodeInfo::SetCachedSize(int size) const { + _cached_size_.Set(size); +} + +void SourceCodeInfo::Clear() { +// @@protoc_insertion_point(message_clear_start:google.protobuf.SourceCodeInfo) + arc_ui32 cached_has_bits = 0; + // Prevent compiler warnings about cached_has_bits being unused + (void) cached_has_bits; + + location_.Clear(); + _internal_metadata_.Clear<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(); +} + +const char* SourceCodeInfo::_InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) { +#define CHK_(x) if (PROTOBUF_PREDICT_FALSE(!(x))) goto failure + while (!ctx->Done(&ptr)) { + arc_ui32 tag; + ptr = ::PROTOBUF_NAMESPACE_ID::internal::ReadTag(ptr, &tag); + switch (tag >> 3) { + // repeated .google.protobuf.SourceCodeInfo.Location location = 1; + case 1: + if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 10)) { + ptr -= 1; + do { + ptr += 1; + ptr = ctx->ParseMessage(_internal_add_location(), ptr); + CHK_(ptr); + if (!ctx->DataAvailable(ptr)) break; + } while (::PROTOBUF_NAMESPACE_ID::internal::ExpectTag<10>(ptr)); + } else + goto handle_unusual; + continue; + default: + goto handle_unusual; + } // switch + handle_unusual: + if ((tag == 0) || ((tag & 7) == 4)) { + CHK_(ptr); + ctx->SetLastTag(tag); + goto message_done; + } + ptr = UnknownFieldParse( + tag, + _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(), + ptr, ctx); + CHK_(ptr != nullptr); + } // while +message_done: + return ptr; +failure: + ptr = nullptr; + goto message_done; +#undef CHK_ +} + +uint8_t* SourceCodeInfo::_InternalSerialize( + uint8_t* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const { + // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.SourceCodeInfo) + arc_ui32 cached_has_bits = 0; + (void) cached_has_bits; + + // repeated .google.protobuf.SourceCodeInfo.Location location = 1; + for (unsigned int i = 0, + n = static_cast<unsigned int>(this->_internal_location_size()); i < n; i++) { + target = stream->EnsureSpace(target); + target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite:: + InternalWriteMessage(1, this->_internal_location(i), target, stream); + } + + if (PROTOBUF_PREDICT_FALSE(_internal_metadata_.have_unknown_fields())) { + target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::InternalSerializeUnknownFieldsToArray( + _internal_metadata_.unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(::PROTOBUF_NAMESPACE_ID::UnknownFieldSet::default_instance), target, stream); + } + // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.SourceCodeInfo) + return target; +} + +size_t SourceCodeInfo::ByteSizeLong() const { +// @@protoc_insertion_point(message_byte_size_start:google.protobuf.SourceCodeInfo) + size_t total_size = 0; + + arc_ui32 cached_has_bits = 0; + // Prevent compiler warnings about cached_has_bits being unused + (void) cached_has_bits; + + // repeated .google.protobuf.SourceCodeInfo.Location location = 1; + total_size += 1UL * this->_internal_location_size(); + for (const auto& msg : this->location_) { + total_size += + ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::MessageSize(msg); + } + + return MaybeComputeUnknownFieldsSize(total_size, &_cached_size_); +} + +const ::PROTOBUF_NAMESPACE_ID::Message::ClassData SourceCodeInfo::_class_data_ = { + ::PROTOBUF_NAMESPACE_ID::Message::CopyWithSizeCheck, + SourceCodeInfo::MergeImpl +}; +const ::PROTOBUF_NAMESPACE_ID::Message::ClassData*SourceCodeInfo::GetClassData() const { return &_class_data_; } + +void SourceCodeInfo::MergeImpl(::PROTOBUF_NAMESPACE_ID::Message* to, + const ::PROTOBUF_NAMESPACE_ID::Message& from) { + static_cast<SourceCodeInfo *>(to)->MergeFrom( + static_cast<const SourceCodeInfo &>(from)); +} + + +void SourceCodeInfo::MergeFrom(const SourceCodeInfo& from) { +// @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.SourceCodeInfo) + GOOGLE_DCHECK_NE(&from, this); + arc_ui32 cached_has_bits = 0; + (void) cached_has_bits; + + location_.MergeFrom(from.location_); + _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_); +} + +void SourceCodeInfo::CopyFrom(const SourceCodeInfo& from) { +// @@protoc_insertion_point(class_specific_copy_from_start:google.protobuf.SourceCodeInfo) + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool SourceCodeInfo::IsInitialized() const { + return true; +} + +void SourceCodeInfo::InternalSwap(SourceCodeInfo* other) { + using std::swap; + _internal_metadata_.InternalSwap(&other->_internal_metadata_); + location_.InternalSwap(&other->location_); +} + +::PROTOBUF_NAMESPACE_ID::Metadata SourceCodeInfo::GetMetadata() const { + return ::PROTOBUF_NAMESPACE_ID::internal::AssignDescriptors( + &descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_getter, &descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_once, + file_level_metadata_google_2fprotobuf_2fdescriptor_2eproto[24]); +} + +// =================================================================== + +class GeneratedCodeInfo_Annotation::_Internal { + public: + using HasBits = decltype(std::declval<GeneratedCodeInfo_Annotation>()._has_bits_); + static void set_has_source_file(HasBits* has_bits) { + (*has_bits)[0] |= 1u; + } + static void set_has_begin(HasBits* has_bits) { + (*has_bits)[0] |= 2u; + } + static void set_has_end(HasBits* has_bits) { + (*has_bits)[0] |= 4u; + } +}; + +GeneratedCodeInfo_Annotation::GeneratedCodeInfo_Annotation(::PROTOBUF_NAMESPACE_ID::Arena* arena, + bool is_message_owned) + : ::PROTOBUF_NAMESPACE_ID::Message(arena, is_message_owned), + path_(arena) { + SharedCtor(); + if (!is_message_owned) { + RegisterArenaDtor(arena); + } + // @@protoc_insertion_point(arena_constructor:google.protobuf.GeneratedCodeInfo.Annotation) +} +GeneratedCodeInfo_Annotation::GeneratedCodeInfo_Annotation(const GeneratedCodeInfo_Annotation& from) + : ::PROTOBUF_NAMESPACE_ID::Message(), + _has_bits_(from._has_bits_), + path_(from.path_) { + _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_); + source_file_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); + #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING + source_file_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation()); + #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING + if (from._internal_has_source_file()) { + source_file_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, from._internal_source_file(), + GetArenaForAllocation()); + } + ::memcpy(&begin_, &from.begin_, + static_cast<size_t>(reinterpret_cast<char*>(&end_) - + reinterpret_cast<char*>(&begin_)) + sizeof(end_)); + // @@protoc_insertion_point(copy_constructor:google.protobuf.GeneratedCodeInfo.Annotation) +} + +inline void GeneratedCodeInfo_Annotation::SharedCtor() { +source_file_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); +#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING + source_file_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation()); +#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING +::memset(reinterpret_cast<char*>(this) + static_cast<size_t>( + reinterpret_cast<char*>(&begin_) - reinterpret_cast<char*>(this)), + 0, static_cast<size_t>(reinterpret_cast<char*>(&end_) - + reinterpret_cast<char*>(&begin_)) + sizeof(end_)); +} + +GeneratedCodeInfo_Annotation::~GeneratedCodeInfo_Annotation() { + // @@protoc_insertion_point(destructor:google.protobuf.GeneratedCodeInfo.Annotation) + if (GetArenaForAllocation() != nullptr) return; + SharedDtor(); + _internal_metadata_.Delete<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(); +} + +inline void GeneratedCodeInfo_Annotation::SharedDtor() { + GOOGLE_DCHECK(GetArenaForAllocation() == nullptr); + source_file_.DestroyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); +} + +void GeneratedCodeInfo_Annotation::ArenaDtor(void* object) { + GeneratedCodeInfo_Annotation* _this = reinterpret_cast< GeneratedCodeInfo_Annotation* >(object); + (void)_this; +} +void GeneratedCodeInfo_Annotation::RegisterArenaDtor(::PROTOBUF_NAMESPACE_ID::Arena*) { +} +void GeneratedCodeInfo_Annotation::SetCachedSize(int size) const { + _cached_size_.Set(size); +} + +void GeneratedCodeInfo_Annotation::Clear() { +// @@protoc_insertion_point(message_clear_start:google.protobuf.GeneratedCodeInfo.Annotation) + arc_ui32 cached_has_bits = 0; + // Prevent compiler warnings about cached_has_bits being unused + (void) cached_has_bits; + + path_.Clear(); + cached_has_bits = _has_bits_[0]; + if (cached_has_bits & 0x00000001u) { + source_file_.ClearNonDefaultToEmpty(); + } + if (cached_has_bits & 0x00000006u) { + ::memset(&begin_, 0, static_cast<size_t>( + reinterpret_cast<char*>(&end_) - + reinterpret_cast<char*>(&begin_)) + sizeof(end_)); + } + _has_bits_.Clear(); + _internal_metadata_.Clear<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(); +} + +const char* GeneratedCodeInfo_Annotation::_InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) { +#define CHK_(x) if (PROTOBUF_PREDICT_FALSE(!(x))) goto failure + _Internal::HasBits has_bits{}; + while (!ctx->Done(&ptr)) { + arc_ui32 tag; + ptr = ::PROTOBUF_NAMESPACE_ID::internal::ReadTag(ptr, &tag); + switch (tag >> 3) { + // repeated int32 path = 1 [packed = true]; + case 1: + if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 10)) { + ptr = ::PROTOBUF_NAMESPACE_ID::internal::PackedInt32Parser(_internal_mutable_path(), ptr, ctx); + CHK_(ptr); + } else if (static_cast<uint8_t>(tag) == 8) { + _internal_add_path(::PROTOBUF_NAMESPACE_ID::internal::ReadVarint32(&ptr)); + CHK_(ptr); + } else + goto handle_unusual; + continue; + // optional string source_file = 2; + case 2: + if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 18)) { + auto str = _internal_mutable_source_file(); + ptr = ::PROTOBUF_NAMESPACE_ID::internal::InlineGreedyStringParser(str, ptr, ctx); + #ifndef NDEBUG + ::PROTOBUF_NAMESPACE_ID::internal::VerifyUTF8(str, "google.protobuf.GeneratedCodeInfo.Annotation.source_file"); + #endif // !NDEBUG + CHK_(ptr); + } else + goto handle_unusual; + continue; + // optional int32 begin = 3; + case 3: + if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 24)) { + _Internal::set_has_begin(&has_bits); + begin_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint32(&ptr); + CHK_(ptr); + } else + goto handle_unusual; + continue; + // optional int32 end = 4; + case 4: + if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 32)) { + _Internal::set_has_end(&has_bits); + end_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint32(&ptr); + CHK_(ptr); + } else + goto handle_unusual; + continue; + default: + goto handle_unusual; + } // switch + handle_unusual: + if ((tag == 0) || ((tag & 7) == 4)) { + CHK_(ptr); + ctx->SetLastTag(tag); + goto message_done; + } + ptr = UnknownFieldParse( + tag, + _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(), + ptr, ctx); + CHK_(ptr != nullptr); + } // while +message_done: + _has_bits_.Or(has_bits); + return ptr; +failure: + ptr = nullptr; + goto message_done; +#undef CHK_ +} + +uint8_t* GeneratedCodeInfo_Annotation::_InternalSerialize( + uint8_t* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const { + // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.GeneratedCodeInfo.Annotation) + arc_ui32 cached_has_bits = 0; + (void) cached_has_bits; + + // repeated int32 path = 1 [packed = true]; + { + int byte_size = _path_cached_byte_size_.load(std::memory_order_relaxed); + if (byte_size > 0) { + target = stream->WriteInt32Packed( + 1, _internal_path(), byte_size, target); + } + } + + cached_has_bits = _has_bits_[0]; + // optional string source_file = 2; + if (cached_has_bits & 0x00000001u) { + ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::VerifyUTF8StringNamedField( + this->_internal_source_file().data(), static_cast<int>(this->_internal_source_file().length()), + ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::SERIALIZE, + "google.protobuf.GeneratedCodeInfo.Annotation.source_file"); + target = stream->WriteStringMaybeAliased( + 2, this->_internal_source_file(), target); + } + + // optional int32 begin = 3; + if (cached_has_bits & 0x00000002u) { + target = stream->EnsureSpace(target); + target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteInt32ToArray(3, this->_internal_begin(), target); + } + + // optional int32 end = 4; + if (cached_has_bits & 0x00000004u) { + target = stream->EnsureSpace(target); + target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteInt32ToArray(4, this->_internal_end(), target); + } + + if (PROTOBUF_PREDICT_FALSE(_internal_metadata_.have_unknown_fields())) { + target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::InternalSerializeUnknownFieldsToArray( + _internal_metadata_.unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(::PROTOBUF_NAMESPACE_ID::UnknownFieldSet::default_instance), target, stream); + } + // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.GeneratedCodeInfo.Annotation) + return target; +} + +size_t GeneratedCodeInfo_Annotation::ByteSizeLong() const { +// @@protoc_insertion_point(message_byte_size_start:google.protobuf.GeneratedCodeInfo.Annotation) + size_t total_size = 0; + + arc_ui32 cached_has_bits = 0; + // Prevent compiler warnings about cached_has_bits being unused + (void) cached_has_bits; + + // repeated int32 path = 1 [packed = true]; + { + size_t data_size = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite:: + Int32Size(this->path_); + if (data_size > 0) { + total_size += 1 + + ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::Int32Size( + static_cast<arc_i32>(data_size)); + } + int cached_size = ::PROTOBUF_NAMESPACE_ID::internal::ToCachedSize(data_size); + _path_cached_byte_size_.store(cached_size, + std::memory_order_relaxed); + total_size += data_size; + } + + cached_has_bits = _has_bits_[0]; + if (cached_has_bits & 0x00000007u) { + // optional string source_file = 2; + if (cached_has_bits & 0x00000001u) { + total_size += 1 + + ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::StringSize( + this->_internal_source_file()); + } + + // optional int32 begin = 3; + if (cached_has_bits & 0x00000002u) { + total_size += ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::Int32SizePlusOne(this->_internal_begin()); + } + + // optional int32 end = 4; + if (cached_has_bits & 0x00000004u) { + total_size += ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::Int32SizePlusOne(this->_internal_end()); + } + + } + return MaybeComputeUnknownFieldsSize(total_size, &_cached_size_); +} + +const ::PROTOBUF_NAMESPACE_ID::Message::ClassData GeneratedCodeInfo_Annotation::_class_data_ = { + ::PROTOBUF_NAMESPACE_ID::Message::CopyWithSizeCheck, + GeneratedCodeInfo_Annotation::MergeImpl +}; +const ::PROTOBUF_NAMESPACE_ID::Message::ClassData*GeneratedCodeInfo_Annotation::GetClassData() const { return &_class_data_; } + +void GeneratedCodeInfo_Annotation::MergeImpl(::PROTOBUF_NAMESPACE_ID::Message* to, + const ::PROTOBUF_NAMESPACE_ID::Message& from) { + static_cast<GeneratedCodeInfo_Annotation *>(to)->MergeFrom( + static_cast<const GeneratedCodeInfo_Annotation &>(from)); +} + + +void GeneratedCodeInfo_Annotation::MergeFrom(const GeneratedCodeInfo_Annotation& from) { +// @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.GeneratedCodeInfo.Annotation) + GOOGLE_DCHECK_NE(&from, this); + arc_ui32 cached_has_bits = 0; + (void) cached_has_bits; + + path_.MergeFrom(from.path_); + cached_has_bits = from._has_bits_[0]; + if (cached_has_bits & 0x00000007u) { + if (cached_has_bits & 0x00000001u) { + _internal_set_source_file(from._internal_source_file()); + } + if (cached_has_bits & 0x00000002u) { + begin_ = from.begin_; + } + if (cached_has_bits & 0x00000004u) { + end_ = from.end_; + } + _has_bits_[0] |= cached_has_bits; + } + _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_); +} + +void GeneratedCodeInfo_Annotation::CopyFrom(const GeneratedCodeInfo_Annotation& from) { +// @@protoc_insertion_point(class_specific_copy_from_start:google.protobuf.GeneratedCodeInfo.Annotation) + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool GeneratedCodeInfo_Annotation::IsInitialized() const { + return true; +} + +void GeneratedCodeInfo_Annotation::InternalSwap(GeneratedCodeInfo_Annotation* other) { + using std::swap; + auto* lhs_arena = GetArenaForAllocation(); + auto* rhs_arena = other->GetArenaForAllocation(); + _internal_metadata_.InternalSwap(&other->_internal_metadata_); + swap(_has_bits_[0], other->_has_bits_[0]); + path_.InternalSwap(&other->path_); + ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::InternalSwap( + &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), + &source_file_, lhs_arena, + &other->source_file_, rhs_arena + ); + ::PROTOBUF_NAMESPACE_ID::internal::memswap< + PROTOBUF_FIELD_OFFSET(GeneratedCodeInfo_Annotation, end_) + + sizeof(GeneratedCodeInfo_Annotation::end_) + - PROTOBUF_FIELD_OFFSET(GeneratedCodeInfo_Annotation, begin_)>( + reinterpret_cast<char*>(&begin_), + reinterpret_cast<char*>(&other->begin_)); +} + +::PROTOBUF_NAMESPACE_ID::Metadata GeneratedCodeInfo_Annotation::GetMetadata() const { + return ::PROTOBUF_NAMESPACE_ID::internal::AssignDescriptors( + &descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_getter, &descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_once, + file_level_metadata_google_2fprotobuf_2fdescriptor_2eproto[25]); +} + +// =================================================================== + +class GeneratedCodeInfo::_Internal { + public: +}; + +GeneratedCodeInfo::GeneratedCodeInfo(::PROTOBUF_NAMESPACE_ID::Arena* arena, + bool is_message_owned) + : ::PROTOBUF_NAMESPACE_ID::Message(arena, is_message_owned), + annotation_(arena) { + SharedCtor(); + if (!is_message_owned) { + RegisterArenaDtor(arena); + } + // @@protoc_insertion_point(arena_constructor:google.protobuf.GeneratedCodeInfo) +} +GeneratedCodeInfo::GeneratedCodeInfo(const GeneratedCodeInfo& from) + : ::PROTOBUF_NAMESPACE_ID::Message(), + annotation_(from.annotation_) { + _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_); + // @@protoc_insertion_point(copy_constructor:google.protobuf.GeneratedCodeInfo) +} + +inline void GeneratedCodeInfo::SharedCtor() { +} + +GeneratedCodeInfo::~GeneratedCodeInfo() { + // @@protoc_insertion_point(destructor:google.protobuf.GeneratedCodeInfo) + if (GetArenaForAllocation() != nullptr) return; + SharedDtor(); + _internal_metadata_.Delete<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(); +} + +inline void GeneratedCodeInfo::SharedDtor() { + GOOGLE_DCHECK(GetArenaForAllocation() == nullptr); +} + +void GeneratedCodeInfo::ArenaDtor(void* object) { + GeneratedCodeInfo* _this = reinterpret_cast< GeneratedCodeInfo* >(object); + (void)_this; +} +void GeneratedCodeInfo::RegisterArenaDtor(::PROTOBUF_NAMESPACE_ID::Arena*) { +} +void GeneratedCodeInfo::SetCachedSize(int size) const { + _cached_size_.Set(size); +} + +void GeneratedCodeInfo::Clear() { +// @@protoc_insertion_point(message_clear_start:google.protobuf.GeneratedCodeInfo) + arc_ui32 cached_has_bits = 0; + // Prevent compiler warnings about cached_has_bits being unused + (void) cached_has_bits; + + annotation_.Clear(); + _internal_metadata_.Clear<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(); +} + +const char* GeneratedCodeInfo::_InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) { +#define CHK_(x) if (PROTOBUF_PREDICT_FALSE(!(x))) goto failure + while (!ctx->Done(&ptr)) { + arc_ui32 tag; + ptr = ::PROTOBUF_NAMESPACE_ID::internal::ReadTag(ptr, &tag); + switch (tag >> 3) { + // repeated .google.protobuf.GeneratedCodeInfo.Annotation annotation = 1; + case 1: + if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 10)) { + ptr -= 1; + do { + ptr += 1; + ptr = ctx->ParseMessage(_internal_add_annotation(), ptr); + CHK_(ptr); + if (!ctx->DataAvailable(ptr)) break; + } while (::PROTOBUF_NAMESPACE_ID::internal::ExpectTag<10>(ptr)); + } else + goto handle_unusual; + continue; + default: + goto handle_unusual; + } // switch + handle_unusual: + if ((tag == 0) || ((tag & 7) == 4)) { + CHK_(ptr); + ctx->SetLastTag(tag); + goto message_done; + } + ptr = UnknownFieldParse( + tag, + _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(), + ptr, ctx); + CHK_(ptr != nullptr); + } // while +message_done: + return ptr; +failure: + ptr = nullptr; + goto message_done; +#undef CHK_ +} + +uint8_t* GeneratedCodeInfo::_InternalSerialize( + uint8_t* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const { + // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.GeneratedCodeInfo) + arc_ui32 cached_has_bits = 0; + (void) cached_has_bits; + + // repeated .google.protobuf.GeneratedCodeInfo.Annotation annotation = 1; + for (unsigned int i = 0, + n = static_cast<unsigned int>(this->_internal_annotation_size()); i < n; i++) { + target = stream->EnsureSpace(target); + target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite:: + InternalWriteMessage(1, this->_internal_annotation(i), target, stream); + } + + if (PROTOBUF_PREDICT_FALSE(_internal_metadata_.have_unknown_fields())) { + target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::InternalSerializeUnknownFieldsToArray( + _internal_metadata_.unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(::PROTOBUF_NAMESPACE_ID::UnknownFieldSet::default_instance), target, stream); + } + // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.GeneratedCodeInfo) + return target; +} + +size_t GeneratedCodeInfo::ByteSizeLong() const { +// @@protoc_insertion_point(message_byte_size_start:google.protobuf.GeneratedCodeInfo) + size_t total_size = 0; + + arc_ui32 cached_has_bits = 0; + // Prevent compiler warnings about cached_has_bits being unused + (void) cached_has_bits; + + // repeated .google.protobuf.GeneratedCodeInfo.Annotation annotation = 1; + total_size += 1UL * this->_internal_annotation_size(); + for (const auto& msg : this->annotation_) { + total_size += + ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::MessageSize(msg); + } + + return MaybeComputeUnknownFieldsSize(total_size, &_cached_size_); +} + +const ::PROTOBUF_NAMESPACE_ID::Message::ClassData GeneratedCodeInfo::_class_data_ = { + ::PROTOBUF_NAMESPACE_ID::Message::CopyWithSizeCheck, + GeneratedCodeInfo::MergeImpl +}; +const ::PROTOBUF_NAMESPACE_ID::Message::ClassData*GeneratedCodeInfo::GetClassData() const { return &_class_data_; } + +void GeneratedCodeInfo::MergeImpl(::PROTOBUF_NAMESPACE_ID::Message* to, + const ::PROTOBUF_NAMESPACE_ID::Message& from) { + static_cast<GeneratedCodeInfo *>(to)->MergeFrom( + static_cast<const GeneratedCodeInfo &>(from)); +} + + +void GeneratedCodeInfo::MergeFrom(const GeneratedCodeInfo& from) { +// @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.GeneratedCodeInfo) + GOOGLE_DCHECK_NE(&from, this); + arc_ui32 cached_has_bits = 0; + (void) cached_has_bits; + + annotation_.MergeFrom(from.annotation_); + _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_); +} + +void GeneratedCodeInfo::CopyFrom(const GeneratedCodeInfo& from) { +// @@protoc_insertion_point(class_specific_copy_from_start:google.protobuf.GeneratedCodeInfo) + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool GeneratedCodeInfo::IsInitialized() const { + return true; +} + +void GeneratedCodeInfo::InternalSwap(GeneratedCodeInfo* other) { + using std::swap; + _internal_metadata_.InternalSwap(&other->_internal_metadata_); + annotation_.InternalSwap(&other->annotation_); +} + +::PROTOBUF_NAMESPACE_ID::Metadata GeneratedCodeInfo::GetMetadata() const { + return ::PROTOBUF_NAMESPACE_ID::internal::AssignDescriptors( + &descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_getter, &descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_once, + file_level_metadata_google_2fprotobuf_2fdescriptor_2eproto[26]); +} + +// @@protoc_insertion_point(namespace_scope) +PROTOBUF_NAMESPACE_CLOSE +PROTOBUF_NAMESPACE_OPEN +template<> PROTOBUF_NOINLINE ::PROTOBUF_NAMESPACE_ID::FileDescriptorSet* Arena::CreateMaybeMessage< ::PROTOBUF_NAMESPACE_ID::FileDescriptorSet >(Arena* arena) { + return Arena::CreateMessageInternal< ::PROTOBUF_NAMESPACE_ID::FileDescriptorSet >(arena); +} +template<> PROTOBUF_NOINLINE ::PROTOBUF_NAMESPACE_ID::FileDescriptorProto* Arena::CreateMaybeMessage< ::PROTOBUF_NAMESPACE_ID::FileDescriptorProto >(Arena* arena) { + return Arena::CreateMessageInternal< ::PROTOBUF_NAMESPACE_ID::FileDescriptorProto >(arena); +} +template<> PROTOBUF_NOINLINE ::PROTOBUF_NAMESPACE_ID::DescriptorProto_ExtensionRange* Arena::CreateMaybeMessage< ::PROTOBUF_NAMESPACE_ID::DescriptorProto_ExtensionRange >(Arena* arena) { + return Arena::CreateMessageInternal< ::PROTOBUF_NAMESPACE_ID::DescriptorProto_ExtensionRange >(arena); +} +template<> PROTOBUF_NOINLINE ::PROTOBUF_NAMESPACE_ID::DescriptorProto_ReservedRange* Arena::CreateMaybeMessage< ::PROTOBUF_NAMESPACE_ID::DescriptorProto_ReservedRange >(Arena* arena) { + return Arena::CreateMessageInternal< ::PROTOBUF_NAMESPACE_ID::DescriptorProto_ReservedRange >(arena); +} +template<> PROTOBUF_NOINLINE ::PROTOBUF_NAMESPACE_ID::DescriptorProto* Arena::CreateMaybeMessage< ::PROTOBUF_NAMESPACE_ID::DescriptorProto >(Arena* arena) { + return Arena::CreateMessageInternal< ::PROTOBUF_NAMESPACE_ID::DescriptorProto >(arena); +} +template<> PROTOBUF_NOINLINE ::PROTOBUF_NAMESPACE_ID::ExtensionRangeOptions* Arena::CreateMaybeMessage< ::PROTOBUF_NAMESPACE_ID::ExtensionRangeOptions >(Arena* arena) { + return Arena::CreateMessageInternal< ::PROTOBUF_NAMESPACE_ID::ExtensionRangeOptions >(arena); +} +template<> PROTOBUF_NOINLINE ::PROTOBUF_NAMESPACE_ID::FieldDescriptorProto* Arena::CreateMaybeMessage< ::PROTOBUF_NAMESPACE_ID::FieldDescriptorProto >(Arena* arena) { + return Arena::CreateMessageInternal< ::PROTOBUF_NAMESPACE_ID::FieldDescriptorProto >(arena); +} +template<> PROTOBUF_NOINLINE ::PROTOBUF_NAMESPACE_ID::OneofDescriptorProto* Arena::CreateMaybeMessage< ::PROTOBUF_NAMESPACE_ID::OneofDescriptorProto >(Arena* arena) { + return Arena::CreateMessageInternal< ::PROTOBUF_NAMESPACE_ID::OneofDescriptorProto >(arena); +} +template<> PROTOBUF_NOINLINE ::PROTOBUF_NAMESPACE_ID::EnumDescriptorProto_EnumReservedRange* Arena::CreateMaybeMessage< ::PROTOBUF_NAMESPACE_ID::EnumDescriptorProto_EnumReservedRange >(Arena* arena) { + return Arena::CreateMessageInternal< ::PROTOBUF_NAMESPACE_ID::EnumDescriptorProto_EnumReservedRange >(arena); +} +template<> PROTOBUF_NOINLINE ::PROTOBUF_NAMESPACE_ID::EnumDescriptorProto* Arena::CreateMaybeMessage< ::PROTOBUF_NAMESPACE_ID::EnumDescriptorProto >(Arena* arena) { + return Arena::CreateMessageInternal< ::PROTOBUF_NAMESPACE_ID::EnumDescriptorProto >(arena); +} +template<> PROTOBUF_NOINLINE ::PROTOBUF_NAMESPACE_ID::EnumValueDescriptorProto* Arena::CreateMaybeMessage< ::PROTOBUF_NAMESPACE_ID::EnumValueDescriptorProto >(Arena* arena) { + return Arena::CreateMessageInternal< ::PROTOBUF_NAMESPACE_ID::EnumValueDescriptorProto >(arena); +} +template<> PROTOBUF_NOINLINE ::PROTOBUF_NAMESPACE_ID::ServiceDescriptorProto* Arena::CreateMaybeMessage< ::PROTOBUF_NAMESPACE_ID::ServiceDescriptorProto >(Arena* arena) { + return Arena::CreateMessageInternal< ::PROTOBUF_NAMESPACE_ID::ServiceDescriptorProto >(arena); +} +template<> PROTOBUF_NOINLINE ::PROTOBUF_NAMESPACE_ID::MethodDescriptorProto* Arena::CreateMaybeMessage< ::PROTOBUF_NAMESPACE_ID::MethodDescriptorProto >(Arena* arena) { + return Arena::CreateMessageInternal< ::PROTOBUF_NAMESPACE_ID::MethodDescriptorProto >(arena); +} +template<> PROTOBUF_NOINLINE ::PROTOBUF_NAMESPACE_ID::FileOptions* Arena::CreateMaybeMessage< ::PROTOBUF_NAMESPACE_ID::FileOptions >(Arena* arena) { + return Arena::CreateMessageInternal< ::PROTOBUF_NAMESPACE_ID::FileOptions >(arena); +} +template<> PROTOBUF_NOINLINE ::PROTOBUF_NAMESPACE_ID::MessageOptions* Arena::CreateMaybeMessage< ::PROTOBUF_NAMESPACE_ID::MessageOptions >(Arena* arena) { + return Arena::CreateMessageInternal< ::PROTOBUF_NAMESPACE_ID::MessageOptions >(arena); +} +template<> PROTOBUF_NOINLINE ::PROTOBUF_NAMESPACE_ID::FieldOptions* Arena::CreateMaybeMessage< ::PROTOBUF_NAMESPACE_ID::FieldOptions >(Arena* arena) { + return Arena::CreateMessageInternal< ::PROTOBUF_NAMESPACE_ID::FieldOptions >(arena); +} +template<> PROTOBUF_NOINLINE ::PROTOBUF_NAMESPACE_ID::OneofOptions* Arena::CreateMaybeMessage< ::PROTOBUF_NAMESPACE_ID::OneofOptions >(Arena* arena) { + return Arena::CreateMessageInternal< ::PROTOBUF_NAMESPACE_ID::OneofOptions >(arena); +} +template<> PROTOBUF_NOINLINE ::PROTOBUF_NAMESPACE_ID::EnumOptions* Arena::CreateMaybeMessage< ::PROTOBUF_NAMESPACE_ID::EnumOptions >(Arena* arena) { + return Arena::CreateMessageInternal< ::PROTOBUF_NAMESPACE_ID::EnumOptions >(arena); +} +template<> PROTOBUF_NOINLINE ::PROTOBUF_NAMESPACE_ID::EnumValueOptions* Arena::CreateMaybeMessage< ::PROTOBUF_NAMESPACE_ID::EnumValueOptions >(Arena* arena) { + return Arena::CreateMessageInternal< ::PROTOBUF_NAMESPACE_ID::EnumValueOptions >(arena); +} +template<> PROTOBUF_NOINLINE ::PROTOBUF_NAMESPACE_ID::ServiceOptions* Arena::CreateMaybeMessage< ::PROTOBUF_NAMESPACE_ID::ServiceOptions >(Arena* arena) { + return Arena::CreateMessageInternal< ::PROTOBUF_NAMESPACE_ID::ServiceOptions >(arena); +} +template<> PROTOBUF_NOINLINE ::PROTOBUF_NAMESPACE_ID::MethodOptions* Arena::CreateMaybeMessage< ::PROTOBUF_NAMESPACE_ID::MethodOptions >(Arena* arena) { + return Arena::CreateMessageInternal< ::PROTOBUF_NAMESPACE_ID::MethodOptions >(arena); +} +template<> PROTOBUF_NOINLINE ::PROTOBUF_NAMESPACE_ID::UninterpretedOption_NamePart* Arena::CreateMaybeMessage< ::PROTOBUF_NAMESPACE_ID::UninterpretedOption_NamePart >(Arena* arena) { + return Arena::CreateMessageInternal< ::PROTOBUF_NAMESPACE_ID::UninterpretedOption_NamePart >(arena); +} +template<> PROTOBUF_NOINLINE ::PROTOBUF_NAMESPACE_ID::UninterpretedOption* Arena::CreateMaybeMessage< ::PROTOBUF_NAMESPACE_ID::UninterpretedOption >(Arena* arena) { + return Arena::CreateMessageInternal< ::PROTOBUF_NAMESPACE_ID::UninterpretedOption >(arena); +} +template<> PROTOBUF_NOINLINE ::PROTOBUF_NAMESPACE_ID::SourceCodeInfo_Location* Arena::CreateMaybeMessage< ::PROTOBUF_NAMESPACE_ID::SourceCodeInfo_Location >(Arena* arena) { + return Arena::CreateMessageInternal< ::PROTOBUF_NAMESPACE_ID::SourceCodeInfo_Location >(arena); +} +template<> PROTOBUF_NOINLINE ::PROTOBUF_NAMESPACE_ID::SourceCodeInfo* Arena::CreateMaybeMessage< ::PROTOBUF_NAMESPACE_ID::SourceCodeInfo >(Arena* arena) { + return Arena::CreateMessageInternal< ::PROTOBUF_NAMESPACE_ID::SourceCodeInfo >(arena); +} +template<> PROTOBUF_NOINLINE ::PROTOBUF_NAMESPACE_ID::GeneratedCodeInfo_Annotation* Arena::CreateMaybeMessage< ::PROTOBUF_NAMESPACE_ID::GeneratedCodeInfo_Annotation >(Arena* arena) { + return Arena::CreateMessageInternal< ::PROTOBUF_NAMESPACE_ID::GeneratedCodeInfo_Annotation >(arena); +} +template<> PROTOBUF_NOINLINE ::PROTOBUF_NAMESPACE_ID::GeneratedCodeInfo* Arena::CreateMaybeMessage< ::PROTOBUF_NAMESPACE_ID::GeneratedCodeInfo >(Arena* arena) { + return Arena::CreateMessageInternal< ::PROTOBUF_NAMESPACE_ID::GeneratedCodeInfo >(arena); +} +PROTOBUF_NAMESPACE_CLOSE + +// @@protoc_insertion_point(global_scope) +#include <google/protobuf/port_undef.inc> diff --git a/contrib/libs/protobuf_old/src/google/protobuf/descriptor.pb.h b/contrib/libs/protobuf_old/src/google/protobuf/descriptor.pb.h new file mode 100644 index 0000000000..ecf3a8af07 --- /dev/null +++ b/contrib/libs/protobuf_old/src/google/protobuf/descriptor.pb.h @@ -0,0 +1,14766 @@ +// Generated by the protocol buffer compiler. DO NOT EDIT! +// source: google/protobuf/descriptor.proto + +#ifndef GOOGLE_PROTOBUF_INCLUDED_google_2fprotobuf_2fdescriptor_2eproto +#define GOOGLE_PROTOBUF_INCLUDED_google_2fprotobuf_2fdescriptor_2eproto + +#include <limits> +#include <string> + +#include <google/protobuf/port_def.inc> +#if PROTOBUF_VERSION < 3019000 +#error This file was generated by a newer version of protoc which is +#error incompatible with your Protocol Buffer headers. Please update +#error your headers. +#endif +#if 3019000 < PROTOBUF_MIN_PROTOC_VERSION +#error This file was generated by an older version of protoc which is +#error incompatible with your Protocol Buffer headers. Please +#error regenerate this file with a newer version of protoc. +#endif + +#include <google/protobuf/port_undef.inc> +#include <google/protobuf/io/coded_stream.h> +#include <google/protobuf/arena.h> +#include <google/protobuf/arenastring.h> +#include <google/protobuf/generated_message_table_driven.h> +#include <google/protobuf/generated_message_util.h> +#include <google/protobuf/metadata_lite.h> +#include <google/protobuf/generated_message_reflection.h> +#include <google/protobuf/message.h> +#include <google/protobuf/repeated_field.h> // IWYU pragma: export +#include <google/protobuf/extension_set.h> // IWYU pragma: export +#include <google/protobuf/generated_enum_reflection.h> +#include <google/protobuf/unknown_field_set.h> +// @@protoc_insertion_point(includes) +#include <google/protobuf/port_def.inc> +#define PROTOBUF_INTERNAL_EXPORT_google_2fprotobuf_2fdescriptor_2eproto PROTOBUF_EXPORT +PROTOBUF_NAMESPACE_OPEN +namespace internal { +class AnyMetadata; +} // namespace internal +PROTOBUF_NAMESPACE_CLOSE + +// Internal implementation detail -- do not use these members. +struct PROTOBUF_EXPORT TableStruct_google_2fprotobuf_2fdescriptor_2eproto { + static const ::PROTOBUF_NAMESPACE_ID::internal::ParseTableField entries[] + PROTOBUF_SECTION_VARIABLE(protodesc_cold); + static const ::PROTOBUF_NAMESPACE_ID::internal::AuxiliaryParseTableField aux[] + PROTOBUF_SECTION_VARIABLE(protodesc_cold); + static const ::PROTOBUF_NAMESPACE_ID::internal::ParseTable schema[27] + PROTOBUF_SECTION_VARIABLE(protodesc_cold); + static const ::PROTOBUF_NAMESPACE_ID::internal::FieldMetadata field_metadata[]; + static const ::PROTOBUF_NAMESPACE_ID::internal::SerializationTable serialization_table[]; + static const arc_ui32 offsets[]; +}; +PROTOBUF_EXPORT extern const ::PROTOBUF_NAMESPACE_ID::internal::DescriptorTable descriptor_table_google_2fprotobuf_2fdescriptor_2eproto; +PROTOBUF_NAMESPACE_OPEN +class DescriptorProto; +struct DescriptorProtoDefaultTypeInternal; +PROTOBUF_EXPORT extern DescriptorProtoDefaultTypeInternal _DescriptorProto_default_instance_; +class DescriptorProto_ExtensionRange; +struct DescriptorProto_ExtensionRangeDefaultTypeInternal; +PROTOBUF_EXPORT extern DescriptorProto_ExtensionRangeDefaultTypeInternal _DescriptorProto_ExtensionRange_default_instance_; +class DescriptorProto_ReservedRange; +struct DescriptorProto_ReservedRangeDefaultTypeInternal; +PROTOBUF_EXPORT extern DescriptorProto_ReservedRangeDefaultTypeInternal _DescriptorProto_ReservedRange_default_instance_; +class EnumDescriptorProto; +struct EnumDescriptorProtoDefaultTypeInternal; +PROTOBUF_EXPORT extern EnumDescriptorProtoDefaultTypeInternal _EnumDescriptorProto_default_instance_; +class EnumDescriptorProto_EnumReservedRange; +struct EnumDescriptorProto_EnumReservedRangeDefaultTypeInternal; +PROTOBUF_EXPORT extern EnumDescriptorProto_EnumReservedRangeDefaultTypeInternal _EnumDescriptorProto_EnumReservedRange_default_instance_; +class EnumOptions; +struct EnumOptionsDefaultTypeInternal; +PROTOBUF_EXPORT extern EnumOptionsDefaultTypeInternal _EnumOptions_default_instance_; +class EnumValueDescriptorProto; +struct EnumValueDescriptorProtoDefaultTypeInternal; +PROTOBUF_EXPORT extern EnumValueDescriptorProtoDefaultTypeInternal _EnumValueDescriptorProto_default_instance_; +class EnumValueOptions; +struct EnumValueOptionsDefaultTypeInternal; +PROTOBUF_EXPORT extern EnumValueOptionsDefaultTypeInternal _EnumValueOptions_default_instance_; +class ExtensionRangeOptions; +struct ExtensionRangeOptionsDefaultTypeInternal; +PROTOBUF_EXPORT extern ExtensionRangeOptionsDefaultTypeInternal _ExtensionRangeOptions_default_instance_; +class FieldDescriptorProto; +struct FieldDescriptorProtoDefaultTypeInternal; +PROTOBUF_EXPORT extern FieldDescriptorProtoDefaultTypeInternal _FieldDescriptorProto_default_instance_; +class FieldOptions; +struct FieldOptionsDefaultTypeInternal; +PROTOBUF_EXPORT extern FieldOptionsDefaultTypeInternal _FieldOptions_default_instance_; +class FileDescriptorProto; +struct FileDescriptorProtoDefaultTypeInternal; +PROTOBUF_EXPORT extern FileDescriptorProtoDefaultTypeInternal _FileDescriptorProto_default_instance_; +class FileDescriptorSet; +struct FileDescriptorSetDefaultTypeInternal; +PROTOBUF_EXPORT extern FileDescriptorSetDefaultTypeInternal _FileDescriptorSet_default_instance_; +class FileOptions; +struct FileOptionsDefaultTypeInternal; +PROTOBUF_EXPORT extern FileOptionsDefaultTypeInternal _FileOptions_default_instance_; +class GeneratedCodeInfo; +struct GeneratedCodeInfoDefaultTypeInternal; +PROTOBUF_EXPORT extern GeneratedCodeInfoDefaultTypeInternal _GeneratedCodeInfo_default_instance_; +class GeneratedCodeInfo_Annotation; +struct GeneratedCodeInfo_AnnotationDefaultTypeInternal; +PROTOBUF_EXPORT extern GeneratedCodeInfo_AnnotationDefaultTypeInternal _GeneratedCodeInfo_Annotation_default_instance_; +class MessageOptions; +struct MessageOptionsDefaultTypeInternal; +PROTOBUF_EXPORT extern MessageOptionsDefaultTypeInternal _MessageOptions_default_instance_; +class MethodDescriptorProto; +struct MethodDescriptorProtoDefaultTypeInternal; +PROTOBUF_EXPORT extern MethodDescriptorProtoDefaultTypeInternal _MethodDescriptorProto_default_instance_; +class MethodOptions; +struct MethodOptionsDefaultTypeInternal; +PROTOBUF_EXPORT extern MethodOptionsDefaultTypeInternal _MethodOptions_default_instance_; +class OneofDescriptorProto; +struct OneofDescriptorProtoDefaultTypeInternal; +PROTOBUF_EXPORT extern OneofDescriptorProtoDefaultTypeInternal _OneofDescriptorProto_default_instance_; +class OneofOptions; +struct OneofOptionsDefaultTypeInternal; +PROTOBUF_EXPORT extern OneofOptionsDefaultTypeInternal _OneofOptions_default_instance_; +class ServiceDescriptorProto; +struct ServiceDescriptorProtoDefaultTypeInternal; +PROTOBUF_EXPORT extern ServiceDescriptorProtoDefaultTypeInternal _ServiceDescriptorProto_default_instance_; +class ServiceOptions; +struct ServiceOptionsDefaultTypeInternal; +PROTOBUF_EXPORT extern ServiceOptionsDefaultTypeInternal _ServiceOptions_default_instance_; +class SourceCodeInfo; +struct SourceCodeInfoDefaultTypeInternal; +PROTOBUF_EXPORT extern SourceCodeInfoDefaultTypeInternal _SourceCodeInfo_default_instance_; +class SourceCodeInfo_Location; +struct SourceCodeInfo_LocationDefaultTypeInternal; +PROTOBUF_EXPORT extern SourceCodeInfo_LocationDefaultTypeInternal _SourceCodeInfo_Location_default_instance_; +class UninterpretedOption; +struct UninterpretedOptionDefaultTypeInternal; +PROTOBUF_EXPORT extern UninterpretedOptionDefaultTypeInternal _UninterpretedOption_default_instance_; +class UninterpretedOption_NamePart; +struct UninterpretedOption_NamePartDefaultTypeInternal; +PROTOBUF_EXPORT extern UninterpretedOption_NamePartDefaultTypeInternal _UninterpretedOption_NamePart_default_instance_; +PROTOBUF_NAMESPACE_CLOSE +PROTOBUF_NAMESPACE_OPEN +template<> PROTOBUF_EXPORT ::PROTOBUF_NAMESPACE_ID::DescriptorProto* Arena::CreateMaybeMessage<::PROTOBUF_NAMESPACE_ID::DescriptorProto>(Arena*); +template<> PROTOBUF_EXPORT ::PROTOBUF_NAMESPACE_ID::DescriptorProto_ExtensionRange* Arena::CreateMaybeMessage<::PROTOBUF_NAMESPACE_ID::DescriptorProto_ExtensionRange>(Arena*); +template<> PROTOBUF_EXPORT ::PROTOBUF_NAMESPACE_ID::DescriptorProto_ReservedRange* Arena::CreateMaybeMessage<::PROTOBUF_NAMESPACE_ID::DescriptorProto_ReservedRange>(Arena*); +template<> PROTOBUF_EXPORT ::PROTOBUF_NAMESPACE_ID::EnumDescriptorProto* Arena::CreateMaybeMessage<::PROTOBUF_NAMESPACE_ID::EnumDescriptorProto>(Arena*); +template<> PROTOBUF_EXPORT ::PROTOBUF_NAMESPACE_ID::EnumDescriptorProto_EnumReservedRange* Arena::CreateMaybeMessage<::PROTOBUF_NAMESPACE_ID::EnumDescriptorProto_EnumReservedRange>(Arena*); +template<> PROTOBUF_EXPORT ::PROTOBUF_NAMESPACE_ID::EnumOptions* Arena::CreateMaybeMessage<::PROTOBUF_NAMESPACE_ID::EnumOptions>(Arena*); +template<> PROTOBUF_EXPORT ::PROTOBUF_NAMESPACE_ID::EnumValueDescriptorProto* Arena::CreateMaybeMessage<::PROTOBUF_NAMESPACE_ID::EnumValueDescriptorProto>(Arena*); +template<> PROTOBUF_EXPORT ::PROTOBUF_NAMESPACE_ID::EnumValueOptions* Arena::CreateMaybeMessage<::PROTOBUF_NAMESPACE_ID::EnumValueOptions>(Arena*); +template<> PROTOBUF_EXPORT ::PROTOBUF_NAMESPACE_ID::ExtensionRangeOptions* Arena::CreateMaybeMessage<::PROTOBUF_NAMESPACE_ID::ExtensionRangeOptions>(Arena*); +template<> PROTOBUF_EXPORT ::PROTOBUF_NAMESPACE_ID::FieldDescriptorProto* Arena::CreateMaybeMessage<::PROTOBUF_NAMESPACE_ID::FieldDescriptorProto>(Arena*); +template<> PROTOBUF_EXPORT ::PROTOBUF_NAMESPACE_ID::FieldOptions* Arena::CreateMaybeMessage<::PROTOBUF_NAMESPACE_ID::FieldOptions>(Arena*); +template<> PROTOBUF_EXPORT ::PROTOBUF_NAMESPACE_ID::FileDescriptorProto* Arena::CreateMaybeMessage<::PROTOBUF_NAMESPACE_ID::FileDescriptorProto>(Arena*); +template<> PROTOBUF_EXPORT ::PROTOBUF_NAMESPACE_ID::FileDescriptorSet* Arena::CreateMaybeMessage<::PROTOBUF_NAMESPACE_ID::FileDescriptorSet>(Arena*); +template<> PROTOBUF_EXPORT ::PROTOBUF_NAMESPACE_ID::FileOptions* Arena::CreateMaybeMessage<::PROTOBUF_NAMESPACE_ID::FileOptions>(Arena*); +template<> PROTOBUF_EXPORT ::PROTOBUF_NAMESPACE_ID::GeneratedCodeInfo* Arena::CreateMaybeMessage<::PROTOBUF_NAMESPACE_ID::GeneratedCodeInfo>(Arena*); +template<> PROTOBUF_EXPORT ::PROTOBUF_NAMESPACE_ID::GeneratedCodeInfo_Annotation* Arena::CreateMaybeMessage<::PROTOBUF_NAMESPACE_ID::GeneratedCodeInfo_Annotation>(Arena*); +template<> PROTOBUF_EXPORT ::PROTOBUF_NAMESPACE_ID::MessageOptions* Arena::CreateMaybeMessage<::PROTOBUF_NAMESPACE_ID::MessageOptions>(Arena*); +template<> PROTOBUF_EXPORT ::PROTOBUF_NAMESPACE_ID::MethodDescriptorProto* Arena::CreateMaybeMessage<::PROTOBUF_NAMESPACE_ID::MethodDescriptorProto>(Arena*); +template<> PROTOBUF_EXPORT ::PROTOBUF_NAMESPACE_ID::MethodOptions* Arena::CreateMaybeMessage<::PROTOBUF_NAMESPACE_ID::MethodOptions>(Arena*); +template<> PROTOBUF_EXPORT ::PROTOBUF_NAMESPACE_ID::OneofDescriptorProto* Arena::CreateMaybeMessage<::PROTOBUF_NAMESPACE_ID::OneofDescriptorProto>(Arena*); +template<> PROTOBUF_EXPORT ::PROTOBUF_NAMESPACE_ID::OneofOptions* Arena::CreateMaybeMessage<::PROTOBUF_NAMESPACE_ID::OneofOptions>(Arena*); +template<> PROTOBUF_EXPORT ::PROTOBUF_NAMESPACE_ID::ServiceDescriptorProto* Arena::CreateMaybeMessage<::PROTOBUF_NAMESPACE_ID::ServiceDescriptorProto>(Arena*); +template<> PROTOBUF_EXPORT ::PROTOBUF_NAMESPACE_ID::ServiceOptions* Arena::CreateMaybeMessage<::PROTOBUF_NAMESPACE_ID::ServiceOptions>(Arena*); +template<> PROTOBUF_EXPORT ::PROTOBUF_NAMESPACE_ID::SourceCodeInfo* Arena::CreateMaybeMessage<::PROTOBUF_NAMESPACE_ID::SourceCodeInfo>(Arena*); +template<> PROTOBUF_EXPORT ::PROTOBUF_NAMESPACE_ID::SourceCodeInfo_Location* Arena::CreateMaybeMessage<::PROTOBUF_NAMESPACE_ID::SourceCodeInfo_Location>(Arena*); +template<> PROTOBUF_EXPORT ::PROTOBUF_NAMESPACE_ID::UninterpretedOption* Arena::CreateMaybeMessage<::PROTOBUF_NAMESPACE_ID::UninterpretedOption>(Arena*); +template<> PROTOBUF_EXPORT ::PROTOBUF_NAMESPACE_ID::UninterpretedOption_NamePart* Arena::CreateMaybeMessage<::PROTOBUF_NAMESPACE_ID::UninterpretedOption_NamePart>(Arena*); +PROTOBUF_NAMESPACE_CLOSE +PROTOBUF_NAMESPACE_OPEN + +enum FieldDescriptorProto_Type : int { + FieldDescriptorProto_Type_TYPE_DOUBLE = 1, + FieldDescriptorProto_Type_TYPE_FLOAT = 2, + FieldDescriptorProto_Type_TYPE_INT64 = 3, + FieldDescriptorProto_Type_TYPE_UINT64 = 4, + FieldDescriptorProto_Type_TYPE_INT32 = 5, + FieldDescriptorProto_Type_TYPE_FIXED64 = 6, + FieldDescriptorProto_Type_TYPE_FIXED32 = 7, + FieldDescriptorProto_Type_TYPE_BOOL = 8, + FieldDescriptorProto_Type_TYPE_STRING = 9, + FieldDescriptorProto_Type_TYPE_GROUP = 10, + FieldDescriptorProto_Type_TYPE_MESSAGE = 11, + FieldDescriptorProto_Type_TYPE_BYTES = 12, + FieldDescriptorProto_Type_TYPE_UINT32 = 13, + FieldDescriptorProto_Type_TYPE_ENUM = 14, + FieldDescriptorProto_Type_TYPE_SFIXED32 = 15, + FieldDescriptorProto_Type_TYPE_SFIXED64 = 16, + FieldDescriptorProto_Type_TYPE_SINT32 = 17, + FieldDescriptorProto_Type_TYPE_SINT64 = 18 +}; +PROTOBUF_EXPORT bool FieldDescriptorProto_Type_IsValid(int value); +constexpr FieldDescriptorProto_Type FieldDescriptorProto_Type_Type_MIN = FieldDescriptorProto_Type_TYPE_DOUBLE; +constexpr FieldDescriptorProto_Type FieldDescriptorProto_Type_Type_MAX = FieldDescriptorProto_Type_TYPE_SINT64; +constexpr int FieldDescriptorProto_Type_Type_ARRAYSIZE = FieldDescriptorProto_Type_Type_MAX + 1; + +PROTOBUF_EXPORT const ::PROTOBUF_NAMESPACE_ID::EnumDescriptor* FieldDescriptorProto_Type_descriptor(); +template<typename T> +inline const TProtoStringType& FieldDescriptorProto_Type_Name(T enum_t_value) { + static_assert(::std::is_same<T, FieldDescriptorProto_Type>::value || + ::std::is_integral<T>::value, + "Incorrect type passed to function FieldDescriptorProto_Type_Name."); + return ::PROTOBUF_NAMESPACE_ID::internal::NameOfEnum( + FieldDescriptorProto_Type_descriptor(), enum_t_value); +} +inline bool FieldDescriptorProto_Type_Parse( + ::PROTOBUF_NAMESPACE_ID::ConstStringParam name, FieldDescriptorProto_Type* value) { + return ::PROTOBUF_NAMESPACE_ID::internal::ParseNamedEnum<FieldDescriptorProto_Type>( + FieldDescriptorProto_Type_descriptor(), name, value); +} +enum FieldDescriptorProto_Label : int { + FieldDescriptorProto_Label_LABEL_OPTIONAL = 1, + FieldDescriptorProto_Label_LABEL_REQUIRED = 2, + FieldDescriptorProto_Label_LABEL_REPEATED = 3 +}; +PROTOBUF_EXPORT bool FieldDescriptorProto_Label_IsValid(int value); +constexpr FieldDescriptorProto_Label FieldDescriptorProto_Label_Label_MIN = FieldDescriptorProto_Label_LABEL_OPTIONAL; +constexpr FieldDescriptorProto_Label FieldDescriptorProto_Label_Label_MAX = FieldDescriptorProto_Label_LABEL_REPEATED; +constexpr int FieldDescriptorProto_Label_Label_ARRAYSIZE = FieldDescriptorProto_Label_Label_MAX + 1; + +PROTOBUF_EXPORT const ::PROTOBUF_NAMESPACE_ID::EnumDescriptor* FieldDescriptorProto_Label_descriptor(); +template<typename T> +inline const TProtoStringType& FieldDescriptorProto_Label_Name(T enum_t_value) { + static_assert(::std::is_same<T, FieldDescriptorProto_Label>::value || + ::std::is_integral<T>::value, + "Incorrect type passed to function FieldDescriptorProto_Label_Name."); + return ::PROTOBUF_NAMESPACE_ID::internal::NameOfEnum( + FieldDescriptorProto_Label_descriptor(), enum_t_value); +} +inline bool FieldDescriptorProto_Label_Parse( + ::PROTOBUF_NAMESPACE_ID::ConstStringParam name, FieldDescriptorProto_Label* value) { + return ::PROTOBUF_NAMESPACE_ID::internal::ParseNamedEnum<FieldDescriptorProto_Label>( + FieldDescriptorProto_Label_descriptor(), name, value); +} +enum FileOptions_OptimizeMode : int { + FileOptions_OptimizeMode_SPEED = 1, + FileOptions_OptimizeMode_CODE_SIZE = 2, + FileOptions_OptimizeMode_LITE_RUNTIME = 3 +}; +PROTOBUF_EXPORT bool FileOptions_OptimizeMode_IsValid(int value); +constexpr FileOptions_OptimizeMode FileOptions_OptimizeMode_OptimizeMode_MIN = FileOptions_OptimizeMode_SPEED; +constexpr FileOptions_OptimizeMode FileOptions_OptimizeMode_OptimizeMode_MAX = FileOptions_OptimizeMode_LITE_RUNTIME; +constexpr int FileOptions_OptimizeMode_OptimizeMode_ARRAYSIZE = FileOptions_OptimizeMode_OptimizeMode_MAX + 1; + +PROTOBUF_EXPORT const ::PROTOBUF_NAMESPACE_ID::EnumDescriptor* FileOptions_OptimizeMode_descriptor(); +template<typename T> +inline const TProtoStringType& FileOptions_OptimizeMode_Name(T enum_t_value) { + static_assert(::std::is_same<T, FileOptions_OptimizeMode>::value || + ::std::is_integral<T>::value, + "Incorrect type passed to function FileOptions_OptimizeMode_Name."); + return ::PROTOBUF_NAMESPACE_ID::internal::NameOfEnum( + FileOptions_OptimizeMode_descriptor(), enum_t_value); +} +inline bool FileOptions_OptimizeMode_Parse( + ::PROTOBUF_NAMESPACE_ID::ConstStringParam name, FileOptions_OptimizeMode* value) { + return ::PROTOBUF_NAMESPACE_ID::internal::ParseNamedEnum<FileOptions_OptimizeMode>( + FileOptions_OptimizeMode_descriptor(), name, value); +} +enum FieldOptions_CType : int { + FieldOptions_CType_STRING = 0, + FieldOptions_CType_CORD = 1, + FieldOptions_CType_STRING_PIECE = 2 +}; +PROTOBUF_EXPORT bool FieldOptions_CType_IsValid(int value); +constexpr FieldOptions_CType FieldOptions_CType_CType_MIN = FieldOptions_CType_STRING; +constexpr FieldOptions_CType FieldOptions_CType_CType_MAX = FieldOptions_CType_STRING_PIECE; +constexpr int FieldOptions_CType_CType_ARRAYSIZE = FieldOptions_CType_CType_MAX + 1; + +PROTOBUF_EXPORT const ::PROTOBUF_NAMESPACE_ID::EnumDescriptor* FieldOptions_CType_descriptor(); +template<typename T> +inline const TProtoStringType& FieldOptions_CType_Name(T enum_t_value) { + static_assert(::std::is_same<T, FieldOptions_CType>::value || + ::std::is_integral<T>::value, + "Incorrect type passed to function FieldOptions_CType_Name."); + return ::PROTOBUF_NAMESPACE_ID::internal::NameOfEnum( + FieldOptions_CType_descriptor(), enum_t_value); +} +inline bool FieldOptions_CType_Parse( + ::PROTOBUF_NAMESPACE_ID::ConstStringParam name, FieldOptions_CType* value) { + return ::PROTOBUF_NAMESPACE_ID::internal::ParseNamedEnum<FieldOptions_CType>( + FieldOptions_CType_descriptor(), name, value); +} +enum FieldOptions_JSType : int { + FieldOptions_JSType_JS_NORMAL = 0, + FieldOptions_JSType_JS_STRING = 1, + FieldOptions_JSType_JS_NUMBER = 2 +}; +PROTOBUF_EXPORT bool FieldOptions_JSType_IsValid(int value); +constexpr FieldOptions_JSType FieldOptions_JSType_JSType_MIN = FieldOptions_JSType_JS_NORMAL; +constexpr FieldOptions_JSType FieldOptions_JSType_JSType_MAX = FieldOptions_JSType_JS_NUMBER; +constexpr int FieldOptions_JSType_JSType_ARRAYSIZE = FieldOptions_JSType_JSType_MAX + 1; + +PROTOBUF_EXPORT const ::PROTOBUF_NAMESPACE_ID::EnumDescriptor* FieldOptions_JSType_descriptor(); +template<typename T> +inline const TProtoStringType& FieldOptions_JSType_Name(T enum_t_value) { + static_assert(::std::is_same<T, FieldOptions_JSType>::value || + ::std::is_integral<T>::value, + "Incorrect type passed to function FieldOptions_JSType_Name."); + return ::PROTOBUF_NAMESPACE_ID::internal::NameOfEnum( + FieldOptions_JSType_descriptor(), enum_t_value); +} +inline bool FieldOptions_JSType_Parse( + ::PROTOBUF_NAMESPACE_ID::ConstStringParam name, FieldOptions_JSType* value) { + return ::PROTOBUF_NAMESPACE_ID::internal::ParseNamedEnum<FieldOptions_JSType>( + FieldOptions_JSType_descriptor(), name, value); +} +enum MethodOptions_IdempotencyLevel : int { + MethodOptions_IdempotencyLevel_IDEMPOTENCY_UNKNOWN = 0, + MethodOptions_IdempotencyLevel_NO_SIDE_EFFECTS = 1, + MethodOptions_IdempotencyLevel_IDEMPOTENT = 2 +}; +PROTOBUF_EXPORT bool MethodOptions_IdempotencyLevel_IsValid(int value); +constexpr MethodOptions_IdempotencyLevel MethodOptions_IdempotencyLevel_IdempotencyLevel_MIN = MethodOptions_IdempotencyLevel_IDEMPOTENCY_UNKNOWN; +constexpr MethodOptions_IdempotencyLevel MethodOptions_IdempotencyLevel_IdempotencyLevel_MAX = MethodOptions_IdempotencyLevel_IDEMPOTENT; +constexpr int MethodOptions_IdempotencyLevel_IdempotencyLevel_ARRAYSIZE = MethodOptions_IdempotencyLevel_IdempotencyLevel_MAX + 1; + +PROTOBUF_EXPORT const ::PROTOBUF_NAMESPACE_ID::EnumDescriptor* MethodOptions_IdempotencyLevel_descriptor(); +template<typename T> +inline const TProtoStringType& MethodOptions_IdempotencyLevel_Name(T enum_t_value) { + static_assert(::std::is_same<T, MethodOptions_IdempotencyLevel>::value || + ::std::is_integral<T>::value, + "Incorrect type passed to function MethodOptions_IdempotencyLevel_Name."); + return ::PROTOBUF_NAMESPACE_ID::internal::NameOfEnum( + MethodOptions_IdempotencyLevel_descriptor(), enum_t_value); +} +inline bool MethodOptions_IdempotencyLevel_Parse( + ::PROTOBUF_NAMESPACE_ID::ConstStringParam name, MethodOptions_IdempotencyLevel* value) { + return ::PROTOBUF_NAMESPACE_ID::internal::ParseNamedEnum<MethodOptions_IdempotencyLevel>( + MethodOptions_IdempotencyLevel_descriptor(), name, value); +} +// =================================================================== + +class PROTOBUF_EXPORT FileDescriptorSet final : + public ::PROTOBUF_NAMESPACE_ID::Message /* @@protoc_insertion_point(class_definition:google.protobuf.FileDescriptorSet) */ { + public: + inline FileDescriptorSet() : FileDescriptorSet(nullptr) {} + ~FileDescriptorSet() override; + explicit constexpr FileDescriptorSet(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized); + + FileDescriptorSet(const FileDescriptorSet& from); + FileDescriptorSet(FileDescriptorSet&& from) noexcept + : FileDescriptorSet() { + *this = ::std::move(from); + } + + inline FileDescriptorSet& operator=(const FileDescriptorSet& from) { + CopyFrom(from); + return *this; + } + inline FileDescriptorSet& operator=(FileDescriptorSet&& from) noexcept { + if (this == &from) return *this; + if (GetOwningArena() == from.GetOwningArena() + #ifdef PROTOBUF_FORCE_COPY_IN_MOVE + && GetOwningArena() != nullptr + #endif // !PROTOBUF_FORCE_COPY_IN_MOVE + ) { + InternalSwap(&from); + } else { + CopyFrom(from); + } + return *this; + } + + inline const ::PROTOBUF_NAMESPACE_ID::UnknownFieldSet& unknown_fields() const { + return _internal_metadata_.unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(::PROTOBUF_NAMESPACE_ID::UnknownFieldSet::default_instance); + } + inline ::PROTOBUF_NAMESPACE_ID::UnknownFieldSet* mutable_unknown_fields() { + return _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(); + } + + static const ::PROTOBUF_NAMESPACE_ID::Descriptor* descriptor() { + return GetDescriptor(); + } + static const ::PROTOBUF_NAMESPACE_ID::Descriptor* GetDescriptor() { + return default_instance().GetMetadata().descriptor; + } + static const ::PROTOBUF_NAMESPACE_ID::Reflection* GetReflection() { + return default_instance().GetMetadata().reflection; + } + static const FileDescriptorSet& default_instance() { + return *internal_default_instance(); + } + static inline const FileDescriptorSet* internal_default_instance() { + return reinterpret_cast<const FileDescriptorSet*>( + &_FileDescriptorSet_default_instance_); + } + static constexpr int kIndexInFileMessages = + 0; + + friend void swap(FileDescriptorSet& a, FileDescriptorSet& b) { + a.Swap(&b); + } + inline void Swap(FileDescriptorSet* other) { + if (other == this) return; + #ifdef PROTOBUF_FORCE_COPY_IN_SWAP + if (GetOwningArena() != nullptr && + GetOwningArena() == other->GetOwningArena()) { + #else // PROTOBUF_FORCE_COPY_IN_SWAP + if (GetOwningArena() == other->GetOwningArena()) { + #endif // !PROTOBUF_FORCE_COPY_IN_SWAP + InternalSwap(other); + } else { + ::PROTOBUF_NAMESPACE_ID::internal::GenericSwap(this, other); + } + } + void UnsafeArenaSwap(FileDescriptorSet* other) { + if (other == this) return; + GOOGLE_DCHECK(GetOwningArena() == other->GetOwningArena()); + InternalSwap(other); + } + + // implements Message ---------------------------------------------- + + FileDescriptorSet* New(::PROTOBUF_NAMESPACE_ID::Arena* arena = nullptr) const final { + return CreateMaybeMessage<FileDescriptorSet>(arena); + } + using ::PROTOBUF_NAMESPACE_ID::Message::CopyFrom; + void CopyFrom(const FileDescriptorSet& from); + using ::PROTOBUF_NAMESPACE_ID::Message::MergeFrom; + void MergeFrom(const FileDescriptorSet& 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; + + size_t ByteSizeLong() const final; + const char* _InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) final; + uint8_t* _InternalSerialize( + uint8_t* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const final; + int GetCachedSize() const final { return _cached_size_.Get(); } + + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const final; + void InternalSwap(FileDescriptorSet* other); + + private: + friend class ::PROTOBUF_NAMESPACE_ID::internal::AnyMetadata; + static ::PROTOBUF_NAMESPACE_ID::StringPiece FullMessageName() { + return "google.protobuf.FileDescriptorSet"; + } + protected: + explicit FileDescriptorSet(::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 ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + enum : int { + kFileFieldNumber = 1, + }; + // repeated .google.protobuf.FileDescriptorProto file = 1; + int file_size() const; + private: + int _internal_file_size() const; + public: + void clear_file(); + ::PROTOBUF_NAMESPACE_ID::FileDescriptorProto* mutable_file(int index); + ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::FileDescriptorProto >* + mutable_file(); + private: + const ::PROTOBUF_NAMESPACE_ID::FileDescriptorProto& _internal_file(int index) const; + ::PROTOBUF_NAMESPACE_ID::FileDescriptorProto* _internal_add_file(); + public: + const ::PROTOBUF_NAMESPACE_ID::FileDescriptorProto& file(int index) const; + ::PROTOBUF_NAMESPACE_ID::FileDescriptorProto* add_file(); + const ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::FileDescriptorProto >& + file() const; + + // @@protoc_insertion_point(class_scope:google.protobuf.FileDescriptorSet) + private: + class _Internal; + + template <typename T> friend class ::PROTOBUF_NAMESPACE_ID::Arena::InternalHelper; + typedef void InternalArenaConstructable_; + typedef void DestructorSkippable_; + ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::FileDescriptorProto > file_; + mutable ::PROTOBUF_NAMESPACE_ID::internal::CachedSize _cached_size_; + friend struct ::TableStruct_google_2fprotobuf_2fdescriptor_2eproto; +}; +// ------------------------------------------------------------------- + +class PROTOBUF_EXPORT FileDescriptorProto final : + public ::PROTOBUF_NAMESPACE_ID::Message /* @@protoc_insertion_point(class_definition:google.protobuf.FileDescriptorProto) */ { + public: + inline FileDescriptorProto() : FileDescriptorProto(nullptr) {} + ~FileDescriptorProto() override; + explicit constexpr FileDescriptorProto(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized); + + FileDescriptorProto(const FileDescriptorProto& from); + FileDescriptorProto(FileDescriptorProto&& from) noexcept + : FileDescriptorProto() { + *this = ::std::move(from); + } + + inline FileDescriptorProto& operator=(const FileDescriptorProto& from) { + CopyFrom(from); + return *this; + } + inline FileDescriptorProto& operator=(FileDescriptorProto&& from) noexcept { + if (this == &from) return *this; + if (GetOwningArena() == from.GetOwningArena() + #ifdef PROTOBUF_FORCE_COPY_IN_MOVE + && GetOwningArena() != nullptr + #endif // !PROTOBUF_FORCE_COPY_IN_MOVE + ) { + InternalSwap(&from); + } else { + CopyFrom(from); + } + return *this; + } + + inline const ::PROTOBUF_NAMESPACE_ID::UnknownFieldSet& unknown_fields() const { + return _internal_metadata_.unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(::PROTOBUF_NAMESPACE_ID::UnknownFieldSet::default_instance); + } + inline ::PROTOBUF_NAMESPACE_ID::UnknownFieldSet* mutable_unknown_fields() { + return _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(); + } + + static const ::PROTOBUF_NAMESPACE_ID::Descriptor* descriptor() { + return GetDescriptor(); + } + static const ::PROTOBUF_NAMESPACE_ID::Descriptor* GetDescriptor() { + return default_instance().GetMetadata().descriptor; + } + static const ::PROTOBUF_NAMESPACE_ID::Reflection* GetReflection() { + return default_instance().GetMetadata().reflection; + } + static const FileDescriptorProto& default_instance() { + return *internal_default_instance(); + } + static inline const FileDescriptorProto* internal_default_instance() { + return reinterpret_cast<const FileDescriptorProto*>( + &_FileDescriptorProto_default_instance_); + } + static constexpr int kIndexInFileMessages = + 1; + + friend void swap(FileDescriptorProto& a, FileDescriptorProto& b) { + a.Swap(&b); + } + inline void Swap(FileDescriptorProto* other) { + if (other == this) return; + #ifdef PROTOBUF_FORCE_COPY_IN_SWAP + if (GetOwningArena() != nullptr && + GetOwningArena() == other->GetOwningArena()) { + #else // PROTOBUF_FORCE_COPY_IN_SWAP + if (GetOwningArena() == other->GetOwningArena()) { + #endif // !PROTOBUF_FORCE_COPY_IN_SWAP + InternalSwap(other); + } else { + ::PROTOBUF_NAMESPACE_ID::internal::GenericSwap(this, other); + } + } + void UnsafeArenaSwap(FileDescriptorProto* other) { + if (other == this) return; + GOOGLE_DCHECK(GetOwningArena() == other->GetOwningArena()); + InternalSwap(other); + } + + // implements Message ---------------------------------------------- + + FileDescriptorProto* New(::PROTOBUF_NAMESPACE_ID::Arena* arena = nullptr) const final { + return CreateMaybeMessage<FileDescriptorProto>(arena); + } + using ::PROTOBUF_NAMESPACE_ID::Message::CopyFrom; + void CopyFrom(const FileDescriptorProto& from); + using ::PROTOBUF_NAMESPACE_ID::Message::MergeFrom; + void MergeFrom(const FileDescriptorProto& 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; + + size_t ByteSizeLong() const final; + const char* _InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) final; + uint8_t* _InternalSerialize( + uint8_t* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const final; + int GetCachedSize() const final { return _cached_size_.Get(); } + + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const final; + void InternalSwap(FileDescriptorProto* other); + + private: + friend class ::PROTOBUF_NAMESPACE_ID::internal::AnyMetadata; + static ::PROTOBUF_NAMESPACE_ID::StringPiece FullMessageName() { + return "google.protobuf.FileDescriptorProto"; + } + protected: + explicit FileDescriptorProto(::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 ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + enum : int { + kDependencyFieldNumber = 3, + kMessageTypeFieldNumber = 4, + kEnumTypeFieldNumber = 5, + kServiceFieldNumber = 6, + kExtensionFieldNumber = 7, + kPublicDependencyFieldNumber = 10, + kWeakDependencyFieldNumber = 11, + kNameFieldNumber = 1, + kPackageFieldNumber = 2, + kSyntaxFieldNumber = 12, + kOptionsFieldNumber = 8, + kSourceCodeInfoFieldNumber = 9, + }; + // repeated string dependency = 3; + int dependency_size() const; + private: + int _internal_dependency_size() const; + public: + void clear_dependency(); + const TProtoStringType& dependency(int index) const; + TProtoStringType* mutable_dependency(int index); + void set_dependency(int index, const TProtoStringType& value); + void set_dependency(int index, TProtoStringType&& value); + void set_dependency(int index, const char* value); + void set_dependency(int index, const char* value, size_t size); + TProtoStringType* add_dependency(); + void add_dependency(const TProtoStringType& value); + void add_dependency(TProtoStringType&& value); + void add_dependency(const char* value); + void add_dependency(const char* value, size_t size); + const ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField<TProtoStringType>& dependency() const; + ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField<TProtoStringType>* mutable_dependency(); + private: + const TProtoStringType& _internal_dependency(int index) const; + TProtoStringType* _internal_add_dependency(); + public: + + // repeated .google.protobuf.DescriptorProto message_type = 4; + int message_type_size() const; + private: + int _internal_message_type_size() const; + public: + void clear_message_type(); + ::PROTOBUF_NAMESPACE_ID::DescriptorProto* mutable_message_type(int index); + ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::DescriptorProto >* + mutable_message_type(); + private: + const ::PROTOBUF_NAMESPACE_ID::DescriptorProto& _internal_message_type(int index) const; + ::PROTOBUF_NAMESPACE_ID::DescriptorProto* _internal_add_message_type(); + public: + const ::PROTOBUF_NAMESPACE_ID::DescriptorProto& message_type(int index) const; + ::PROTOBUF_NAMESPACE_ID::DescriptorProto* add_message_type(); + const ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::DescriptorProto >& + message_type() const; + + // repeated .google.protobuf.EnumDescriptorProto enum_type = 5; + int enum_type_size() const; + private: + int _internal_enum_type_size() const; + public: + void clear_enum_type(); + ::PROTOBUF_NAMESPACE_ID::EnumDescriptorProto* mutable_enum_type(int index); + ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::EnumDescriptorProto >* + mutable_enum_type(); + private: + const ::PROTOBUF_NAMESPACE_ID::EnumDescriptorProto& _internal_enum_type(int index) const; + ::PROTOBUF_NAMESPACE_ID::EnumDescriptorProto* _internal_add_enum_type(); + public: + const ::PROTOBUF_NAMESPACE_ID::EnumDescriptorProto& enum_type(int index) const; + ::PROTOBUF_NAMESPACE_ID::EnumDescriptorProto* add_enum_type(); + const ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::EnumDescriptorProto >& + enum_type() const; + + // repeated .google.protobuf.ServiceDescriptorProto service = 6; + int service_size() const; + private: + int _internal_service_size() const; + public: + void clear_service(); + ::PROTOBUF_NAMESPACE_ID::ServiceDescriptorProto* mutable_service(int index); + ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::ServiceDescriptorProto >* + mutable_service(); + private: + const ::PROTOBUF_NAMESPACE_ID::ServiceDescriptorProto& _internal_service(int index) const; + ::PROTOBUF_NAMESPACE_ID::ServiceDescriptorProto* _internal_add_service(); + public: + const ::PROTOBUF_NAMESPACE_ID::ServiceDescriptorProto& service(int index) const; + ::PROTOBUF_NAMESPACE_ID::ServiceDescriptorProto* add_service(); + const ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::ServiceDescriptorProto >& + service() const; + + // repeated .google.protobuf.FieldDescriptorProto extension = 7; + int extension_size() const; + private: + int _internal_extension_size() const; + public: + void clear_extension(); + ::PROTOBUF_NAMESPACE_ID::FieldDescriptorProto* mutable_extension(int index); + ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::FieldDescriptorProto >* + mutable_extension(); + private: + const ::PROTOBUF_NAMESPACE_ID::FieldDescriptorProto& _internal_extension(int index) const; + ::PROTOBUF_NAMESPACE_ID::FieldDescriptorProto* _internal_add_extension(); + public: + const ::PROTOBUF_NAMESPACE_ID::FieldDescriptorProto& extension(int index) const; + ::PROTOBUF_NAMESPACE_ID::FieldDescriptorProto* add_extension(); + const ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::FieldDescriptorProto >& + extension() const; + + // repeated int32 public_dependency = 10; + int public_dependency_size() const; + private: + int _internal_public_dependency_size() const; + public: + void clear_public_dependency(); + private: + arc_i32 _internal_public_dependency(int index) const; + const ::PROTOBUF_NAMESPACE_ID::RepeatedField< arc_i32 >& + _internal_public_dependency() const; + void _internal_add_public_dependency(arc_i32 value); + ::PROTOBUF_NAMESPACE_ID::RepeatedField< arc_i32 >* + _internal_mutable_public_dependency(); + public: + arc_i32 public_dependency(int index) const; + void set_public_dependency(int index, arc_i32 value); + void add_public_dependency(arc_i32 value); + const ::PROTOBUF_NAMESPACE_ID::RepeatedField< arc_i32 >& + public_dependency() const; + ::PROTOBUF_NAMESPACE_ID::RepeatedField< arc_i32 >* + mutable_public_dependency(); + + // repeated int32 weak_dependency = 11; + int weak_dependency_size() const; + private: + int _internal_weak_dependency_size() const; + public: + void clear_weak_dependency(); + private: + arc_i32 _internal_weak_dependency(int index) const; + const ::PROTOBUF_NAMESPACE_ID::RepeatedField< arc_i32 >& + _internal_weak_dependency() const; + void _internal_add_weak_dependency(arc_i32 value); + ::PROTOBUF_NAMESPACE_ID::RepeatedField< arc_i32 >* + _internal_mutable_weak_dependency(); + public: + arc_i32 weak_dependency(int index) const; + void set_weak_dependency(int index, arc_i32 value); + void add_weak_dependency(arc_i32 value); + const ::PROTOBUF_NAMESPACE_ID::RepeatedField< arc_i32 >& + weak_dependency() const; + ::PROTOBUF_NAMESPACE_ID::RepeatedField< arc_i32 >* + mutable_weak_dependency(); + + // optional string name = 1; + bool has_name() const; + private: + bool _internal_has_name() const; + public: + void clear_name(); + const TProtoStringType& name() const; + template <typename ArgT0 = const TProtoStringType&, typename... ArgT> + void set_name(ArgT0&& arg0, ArgT... args); + TProtoStringType* mutable_name(); + PROTOBUF_NODISCARD TProtoStringType* release_name(); + void set_allocated_name(TProtoStringType* name); + private: + const TProtoStringType& _internal_name() const; + inline PROTOBUF_ALWAYS_INLINE void _internal_set_name(const TProtoStringType& value); + TProtoStringType* _internal_mutable_name(); + public: + + // optional string package = 2; + bool has_package() const; + private: + bool _internal_has_package() const; + public: + void clear_package(); + const TProtoStringType& package() const; + template <typename ArgT0 = const TProtoStringType&, typename... ArgT> + void set_package(ArgT0&& arg0, ArgT... args); + TProtoStringType* mutable_package(); + PROTOBUF_NODISCARD TProtoStringType* release_package(); + void set_allocated_package(TProtoStringType* package); + private: + const TProtoStringType& _internal_package() const; + inline PROTOBUF_ALWAYS_INLINE void _internal_set_package(const TProtoStringType& value); + TProtoStringType* _internal_mutable_package(); + public: + + // optional string syntax = 12; + bool has_syntax() const; + private: + bool _internal_has_syntax() const; + public: + void clear_syntax(); + const TProtoStringType& syntax() const; + template <typename ArgT0 = const TProtoStringType&, typename... ArgT> + void set_syntax(ArgT0&& arg0, ArgT... args); + TProtoStringType* mutable_syntax(); + PROTOBUF_NODISCARD TProtoStringType* release_syntax(); + void set_allocated_syntax(TProtoStringType* syntax); + private: + const TProtoStringType& _internal_syntax() const; + inline PROTOBUF_ALWAYS_INLINE void _internal_set_syntax(const TProtoStringType& value); + TProtoStringType* _internal_mutable_syntax(); + public: + + // optional .google.protobuf.FileOptions options = 8; + bool has_options() const; + private: + bool _internal_has_options() const; + public: + void clear_options(); + const ::PROTOBUF_NAMESPACE_ID::FileOptions& options() const; + PROTOBUF_NODISCARD ::PROTOBUF_NAMESPACE_ID::FileOptions* release_options(); + ::PROTOBUF_NAMESPACE_ID::FileOptions* mutable_options(); + void set_allocated_options(::PROTOBUF_NAMESPACE_ID::FileOptions* options); + private: + const ::PROTOBUF_NAMESPACE_ID::FileOptions& _internal_options() const; + ::PROTOBUF_NAMESPACE_ID::FileOptions* _internal_mutable_options(); + public: + void unsafe_arena_set_allocated_options( + ::PROTOBUF_NAMESPACE_ID::FileOptions* options); + ::PROTOBUF_NAMESPACE_ID::FileOptions* unsafe_arena_release_options(); + + // optional .google.protobuf.SourceCodeInfo source_code_info = 9; + bool has_source_code_info() const; + private: + bool _internal_has_source_code_info() const; + public: + void clear_source_code_info(); + const ::PROTOBUF_NAMESPACE_ID::SourceCodeInfo& source_code_info() const; + PROTOBUF_NODISCARD ::PROTOBUF_NAMESPACE_ID::SourceCodeInfo* release_source_code_info(); + ::PROTOBUF_NAMESPACE_ID::SourceCodeInfo* mutable_source_code_info(); + void set_allocated_source_code_info(::PROTOBUF_NAMESPACE_ID::SourceCodeInfo* source_code_info); + private: + const ::PROTOBUF_NAMESPACE_ID::SourceCodeInfo& _internal_source_code_info() const; + ::PROTOBUF_NAMESPACE_ID::SourceCodeInfo* _internal_mutable_source_code_info(); + public: + void unsafe_arena_set_allocated_source_code_info( + ::PROTOBUF_NAMESPACE_ID::SourceCodeInfo* source_code_info); + ::PROTOBUF_NAMESPACE_ID::SourceCodeInfo* unsafe_arena_release_source_code_info(); + + // @@protoc_insertion_point(class_scope:google.protobuf.FileDescriptorProto) + private: + class _Internal; + + template <typename T> friend class ::PROTOBUF_NAMESPACE_ID::Arena::InternalHelper; + typedef void InternalArenaConstructable_; + typedef void DestructorSkippable_; + ::PROTOBUF_NAMESPACE_ID::internal::HasBits<1> _has_bits_; + mutable ::PROTOBUF_NAMESPACE_ID::internal::CachedSize _cached_size_; + ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField<TProtoStringType> dependency_; + ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::DescriptorProto > message_type_; + ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::EnumDescriptorProto > enum_type_; + ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::ServiceDescriptorProto > service_; + ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::FieldDescriptorProto > extension_; + ::PROTOBUF_NAMESPACE_ID::RepeatedField< arc_i32 > public_dependency_; + ::PROTOBUF_NAMESPACE_ID::RepeatedField< arc_i32 > weak_dependency_; + ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr name_; + ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr package_; + ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr syntax_; + ::PROTOBUF_NAMESPACE_ID::FileOptions* options_; + ::PROTOBUF_NAMESPACE_ID::SourceCodeInfo* source_code_info_; + friend struct ::TableStruct_google_2fprotobuf_2fdescriptor_2eproto; +}; +// ------------------------------------------------------------------- + +class PROTOBUF_EXPORT DescriptorProto_ExtensionRange final : + public ::PROTOBUF_NAMESPACE_ID::Message /* @@protoc_insertion_point(class_definition:google.protobuf.DescriptorProto.ExtensionRange) */ { + public: + inline DescriptorProto_ExtensionRange() : DescriptorProto_ExtensionRange(nullptr) {} + ~DescriptorProto_ExtensionRange() override; + explicit constexpr DescriptorProto_ExtensionRange(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized); + + DescriptorProto_ExtensionRange(const DescriptorProto_ExtensionRange& from); + DescriptorProto_ExtensionRange(DescriptorProto_ExtensionRange&& from) noexcept + : DescriptorProto_ExtensionRange() { + *this = ::std::move(from); + } + + inline DescriptorProto_ExtensionRange& operator=(const DescriptorProto_ExtensionRange& from) { + CopyFrom(from); + return *this; + } + inline DescriptorProto_ExtensionRange& operator=(DescriptorProto_ExtensionRange&& from) noexcept { + if (this == &from) return *this; + if (GetOwningArena() == from.GetOwningArena() + #ifdef PROTOBUF_FORCE_COPY_IN_MOVE + && GetOwningArena() != nullptr + #endif // !PROTOBUF_FORCE_COPY_IN_MOVE + ) { + InternalSwap(&from); + } else { + CopyFrom(from); + } + return *this; + } + + inline const ::PROTOBUF_NAMESPACE_ID::UnknownFieldSet& unknown_fields() const { + return _internal_metadata_.unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(::PROTOBUF_NAMESPACE_ID::UnknownFieldSet::default_instance); + } + inline ::PROTOBUF_NAMESPACE_ID::UnknownFieldSet* mutable_unknown_fields() { + return _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(); + } + + static const ::PROTOBUF_NAMESPACE_ID::Descriptor* descriptor() { + return GetDescriptor(); + } + static const ::PROTOBUF_NAMESPACE_ID::Descriptor* GetDescriptor() { + return default_instance().GetMetadata().descriptor; + } + static const ::PROTOBUF_NAMESPACE_ID::Reflection* GetReflection() { + return default_instance().GetMetadata().reflection; + } + static const DescriptorProto_ExtensionRange& default_instance() { + return *internal_default_instance(); + } + static inline const DescriptorProto_ExtensionRange* internal_default_instance() { + return reinterpret_cast<const DescriptorProto_ExtensionRange*>( + &_DescriptorProto_ExtensionRange_default_instance_); + } + static constexpr int kIndexInFileMessages = + 2; + + friend void swap(DescriptorProto_ExtensionRange& a, DescriptorProto_ExtensionRange& b) { + a.Swap(&b); + } + inline void Swap(DescriptorProto_ExtensionRange* other) { + if (other == this) return; + #ifdef PROTOBUF_FORCE_COPY_IN_SWAP + if (GetOwningArena() != nullptr && + GetOwningArena() == other->GetOwningArena()) { + #else // PROTOBUF_FORCE_COPY_IN_SWAP + if (GetOwningArena() == other->GetOwningArena()) { + #endif // !PROTOBUF_FORCE_COPY_IN_SWAP + InternalSwap(other); + } else { + ::PROTOBUF_NAMESPACE_ID::internal::GenericSwap(this, other); + } + } + void UnsafeArenaSwap(DescriptorProto_ExtensionRange* other) { + if (other == this) return; + GOOGLE_DCHECK(GetOwningArena() == other->GetOwningArena()); + InternalSwap(other); + } + + // implements Message ---------------------------------------------- + + DescriptorProto_ExtensionRange* New(::PROTOBUF_NAMESPACE_ID::Arena* arena = nullptr) const final { + return CreateMaybeMessage<DescriptorProto_ExtensionRange>(arena); + } + using ::PROTOBUF_NAMESPACE_ID::Message::CopyFrom; + void CopyFrom(const DescriptorProto_ExtensionRange& from); + using ::PROTOBUF_NAMESPACE_ID::Message::MergeFrom; + void MergeFrom(const DescriptorProto_ExtensionRange& 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; + + size_t ByteSizeLong() const final; + const char* _InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) final; + uint8_t* _InternalSerialize( + uint8_t* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const final; + int GetCachedSize() const final { return _cached_size_.Get(); } + + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const final; + void InternalSwap(DescriptorProto_ExtensionRange* other); + + private: + friend class ::PROTOBUF_NAMESPACE_ID::internal::AnyMetadata; + static ::PROTOBUF_NAMESPACE_ID::StringPiece FullMessageName() { + return "google.protobuf.DescriptorProto.ExtensionRange"; + } + protected: + explicit DescriptorProto_ExtensionRange(::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 ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + enum : int { + kOptionsFieldNumber = 3, + kStartFieldNumber = 1, + kEndFieldNumber = 2, + }; + // optional .google.protobuf.ExtensionRangeOptions options = 3; + bool has_options() const; + private: + bool _internal_has_options() const; + public: + void clear_options(); + const ::PROTOBUF_NAMESPACE_ID::ExtensionRangeOptions& options() const; + PROTOBUF_NODISCARD ::PROTOBUF_NAMESPACE_ID::ExtensionRangeOptions* release_options(); + ::PROTOBUF_NAMESPACE_ID::ExtensionRangeOptions* mutable_options(); + void set_allocated_options(::PROTOBUF_NAMESPACE_ID::ExtensionRangeOptions* options); + private: + const ::PROTOBUF_NAMESPACE_ID::ExtensionRangeOptions& _internal_options() const; + ::PROTOBUF_NAMESPACE_ID::ExtensionRangeOptions* _internal_mutable_options(); + public: + void unsafe_arena_set_allocated_options( + ::PROTOBUF_NAMESPACE_ID::ExtensionRangeOptions* options); + ::PROTOBUF_NAMESPACE_ID::ExtensionRangeOptions* unsafe_arena_release_options(); + + // optional int32 start = 1; + bool has_start() const; + private: + bool _internal_has_start() const; + public: + void clear_start(); + arc_i32 start() const; + void set_start(arc_i32 value); + private: + arc_i32 _internal_start() const; + void _internal_set_start(arc_i32 value); + public: + + // optional int32 end = 2; + bool has_end() const; + private: + bool _internal_has_end() const; + public: + void clear_end(); + arc_i32 end() const; + void set_end(arc_i32 value); + private: + arc_i32 _internal_end() const; + void _internal_set_end(arc_i32 value); + public: + + // @@protoc_insertion_point(class_scope:google.protobuf.DescriptorProto.ExtensionRange) + private: + class _Internal; + + template <typename T> friend class ::PROTOBUF_NAMESPACE_ID::Arena::InternalHelper; + typedef void InternalArenaConstructable_; + typedef void DestructorSkippable_; + ::PROTOBUF_NAMESPACE_ID::internal::HasBits<1> _has_bits_; + mutable ::PROTOBUF_NAMESPACE_ID::internal::CachedSize _cached_size_; + ::PROTOBUF_NAMESPACE_ID::ExtensionRangeOptions* options_; + arc_i32 start_; + arc_i32 end_; + friend struct ::TableStruct_google_2fprotobuf_2fdescriptor_2eproto; +}; +// ------------------------------------------------------------------- + +class PROTOBUF_EXPORT DescriptorProto_ReservedRange final : + public ::PROTOBUF_NAMESPACE_ID::Message /* @@protoc_insertion_point(class_definition:google.protobuf.DescriptorProto.ReservedRange) */ { + public: + inline DescriptorProto_ReservedRange() : DescriptorProto_ReservedRange(nullptr) {} + ~DescriptorProto_ReservedRange() override; + explicit constexpr DescriptorProto_ReservedRange(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized); + + DescriptorProto_ReservedRange(const DescriptorProto_ReservedRange& from); + DescriptorProto_ReservedRange(DescriptorProto_ReservedRange&& from) noexcept + : DescriptorProto_ReservedRange() { + *this = ::std::move(from); + } + + inline DescriptorProto_ReservedRange& operator=(const DescriptorProto_ReservedRange& from) { + CopyFrom(from); + return *this; + } + inline DescriptorProto_ReservedRange& operator=(DescriptorProto_ReservedRange&& from) noexcept { + if (this == &from) return *this; + if (GetOwningArena() == from.GetOwningArena() + #ifdef PROTOBUF_FORCE_COPY_IN_MOVE + && GetOwningArena() != nullptr + #endif // !PROTOBUF_FORCE_COPY_IN_MOVE + ) { + InternalSwap(&from); + } else { + CopyFrom(from); + } + return *this; + } + + inline const ::PROTOBUF_NAMESPACE_ID::UnknownFieldSet& unknown_fields() const { + return _internal_metadata_.unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(::PROTOBUF_NAMESPACE_ID::UnknownFieldSet::default_instance); + } + inline ::PROTOBUF_NAMESPACE_ID::UnknownFieldSet* mutable_unknown_fields() { + return _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(); + } + + static const ::PROTOBUF_NAMESPACE_ID::Descriptor* descriptor() { + return GetDescriptor(); + } + static const ::PROTOBUF_NAMESPACE_ID::Descriptor* GetDescriptor() { + return default_instance().GetMetadata().descriptor; + } + static const ::PROTOBUF_NAMESPACE_ID::Reflection* GetReflection() { + return default_instance().GetMetadata().reflection; + } + static const DescriptorProto_ReservedRange& default_instance() { + return *internal_default_instance(); + } + static inline const DescriptorProto_ReservedRange* internal_default_instance() { + return reinterpret_cast<const DescriptorProto_ReservedRange*>( + &_DescriptorProto_ReservedRange_default_instance_); + } + static constexpr int kIndexInFileMessages = + 3; + + friend void swap(DescriptorProto_ReservedRange& a, DescriptorProto_ReservedRange& b) { + a.Swap(&b); + } + inline void Swap(DescriptorProto_ReservedRange* other) { + if (other == this) return; + #ifdef PROTOBUF_FORCE_COPY_IN_SWAP + if (GetOwningArena() != nullptr && + GetOwningArena() == other->GetOwningArena()) { + #else // PROTOBUF_FORCE_COPY_IN_SWAP + if (GetOwningArena() == other->GetOwningArena()) { + #endif // !PROTOBUF_FORCE_COPY_IN_SWAP + InternalSwap(other); + } else { + ::PROTOBUF_NAMESPACE_ID::internal::GenericSwap(this, other); + } + } + void UnsafeArenaSwap(DescriptorProto_ReservedRange* other) { + if (other == this) return; + GOOGLE_DCHECK(GetOwningArena() == other->GetOwningArena()); + InternalSwap(other); + } + + // implements Message ---------------------------------------------- + + DescriptorProto_ReservedRange* New(::PROTOBUF_NAMESPACE_ID::Arena* arena = nullptr) const final { + return CreateMaybeMessage<DescriptorProto_ReservedRange>(arena); + } + using ::PROTOBUF_NAMESPACE_ID::Message::CopyFrom; + void CopyFrom(const DescriptorProto_ReservedRange& from); + using ::PROTOBUF_NAMESPACE_ID::Message::MergeFrom; + void MergeFrom(const DescriptorProto_ReservedRange& 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; + + size_t ByteSizeLong() const final; + const char* _InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) final; + uint8_t* _InternalSerialize( + uint8_t* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const final; + int GetCachedSize() const final { return _cached_size_.Get(); } + + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const final; + void InternalSwap(DescriptorProto_ReservedRange* other); + + private: + friend class ::PROTOBUF_NAMESPACE_ID::internal::AnyMetadata; + static ::PROTOBUF_NAMESPACE_ID::StringPiece FullMessageName() { + return "google.protobuf.DescriptorProto.ReservedRange"; + } + protected: + explicit DescriptorProto_ReservedRange(::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 ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + enum : int { + kStartFieldNumber = 1, + kEndFieldNumber = 2, + }; + // optional int32 start = 1; + bool has_start() const; + private: + bool _internal_has_start() const; + public: + void clear_start(); + arc_i32 start() const; + void set_start(arc_i32 value); + private: + arc_i32 _internal_start() const; + void _internal_set_start(arc_i32 value); + public: + + // optional int32 end = 2; + bool has_end() const; + private: + bool _internal_has_end() const; + public: + void clear_end(); + arc_i32 end() const; + void set_end(arc_i32 value); + private: + arc_i32 _internal_end() const; + void _internal_set_end(arc_i32 value); + public: + + // @@protoc_insertion_point(class_scope:google.protobuf.DescriptorProto.ReservedRange) + private: + class _Internal; + + template <typename T> friend class ::PROTOBUF_NAMESPACE_ID::Arena::InternalHelper; + typedef void InternalArenaConstructable_; + typedef void DestructorSkippable_; + ::PROTOBUF_NAMESPACE_ID::internal::HasBits<1> _has_bits_; + mutable ::PROTOBUF_NAMESPACE_ID::internal::CachedSize _cached_size_; + arc_i32 start_; + arc_i32 end_; + friend struct ::TableStruct_google_2fprotobuf_2fdescriptor_2eproto; +}; +// ------------------------------------------------------------------- + +class PROTOBUF_EXPORT DescriptorProto final : + public ::PROTOBUF_NAMESPACE_ID::Message /* @@protoc_insertion_point(class_definition:google.protobuf.DescriptorProto) */ { + public: + inline DescriptorProto() : DescriptorProto(nullptr) {} + ~DescriptorProto() override; + explicit constexpr DescriptorProto(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized); + + DescriptorProto(const DescriptorProto& from); + DescriptorProto(DescriptorProto&& from) noexcept + : DescriptorProto() { + *this = ::std::move(from); + } + + inline DescriptorProto& operator=(const DescriptorProto& from) { + CopyFrom(from); + return *this; + } + inline DescriptorProto& operator=(DescriptorProto&& from) noexcept { + if (this == &from) return *this; + if (GetOwningArena() == from.GetOwningArena() + #ifdef PROTOBUF_FORCE_COPY_IN_MOVE + && GetOwningArena() != nullptr + #endif // !PROTOBUF_FORCE_COPY_IN_MOVE + ) { + InternalSwap(&from); + } else { + CopyFrom(from); + } + return *this; + } + + inline const ::PROTOBUF_NAMESPACE_ID::UnknownFieldSet& unknown_fields() const { + return _internal_metadata_.unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(::PROTOBUF_NAMESPACE_ID::UnknownFieldSet::default_instance); + } + inline ::PROTOBUF_NAMESPACE_ID::UnknownFieldSet* mutable_unknown_fields() { + return _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(); + } + + static const ::PROTOBUF_NAMESPACE_ID::Descriptor* descriptor() { + return GetDescriptor(); + } + static const ::PROTOBUF_NAMESPACE_ID::Descriptor* GetDescriptor() { + return default_instance().GetMetadata().descriptor; + } + static const ::PROTOBUF_NAMESPACE_ID::Reflection* GetReflection() { + return default_instance().GetMetadata().reflection; + } + static const DescriptorProto& default_instance() { + return *internal_default_instance(); + } + static inline const DescriptorProto* internal_default_instance() { + return reinterpret_cast<const DescriptorProto*>( + &_DescriptorProto_default_instance_); + } + static constexpr int kIndexInFileMessages = + 4; + + friend void swap(DescriptorProto& a, DescriptorProto& b) { + a.Swap(&b); + } + inline void Swap(DescriptorProto* other) { + if (other == this) return; + #ifdef PROTOBUF_FORCE_COPY_IN_SWAP + if (GetOwningArena() != nullptr && + GetOwningArena() == other->GetOwningArena()) { + #else // PROTOBUF_FORCE_COPY_IN_SWAP + if (GetOwningArena() == other->GetOwningArena()) { + #endif // !PROTOBUF_FORCE_COPY_IN_SWAP + InternalSwap(other); + } else { + ::PROTOBUF_NAMESPACE_ID::internal::GenericSwap(this, other); + } + } + void UnsafeArenaSwap(DescriptorProto* other) { + if (other == this) return; + GOOGLE_DCHECK(GetOwningArena() == other->GetOwningArena()); + InternalSwap(other); + } + + // implements Message ---------------------------------------------- + + DescriptorProto* New(::PROTOBUF_NAMESPACE_ID::Arena* arena = nullptr) const final { + return CreateMaybeMessage<DescriptorProto>(arena); + } + using ::PROTOBUF_NAMESPACE_ID::Message::CopyFrom; + void CopyFrom(const DescriptorProto& from); + using ::PROTOBUF_NAMESPACE_ID::Message::MergeFrom; + void MergeFrom(const DescriptorProto& 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; + + size_t ByteSizeLong() const final; + const char* _InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) final; + uint8_t* _InternalSerialize( + uint8_t* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const final; + int GetCachedSize() const final { return _cached_size_.Get(); } + + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const final; + void InternalSwap(DescriptorProto* other); + + private: + friend class ::PROTOBUF_NAMESPACE_ID::internal::AnyMetadata; + static ::PROTOBUF_NAMESPACE_ID::StringPiece FullMessageName() { + return "google.protobuf.DescriptorProto"; + } + protected: + explicit DescriptorProto(::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 ---------------------------------------------------- + + typedef DescriptorProto_ExtensionRange ExtensionRange; + typedef DescriptorProto_ReservedRange ReservedRange; + + // accessors ------------------------------------------------------- + + enum : int { + kFieldFieldNumber = 2, + kNestedTypeFieldNumber = 3, + kEnumTypeFieldNumber = 4, + kExtensionRangeFieldNumber = 5, + kExtensionFieldNumber = 6, + kOneofDeclFieldNumber = 8, + kReservedRangeFieldNumber = 9, + kReservedNameFieldNumber = 10, + kNameFieldNumber = 1, + kOptionsFieldNumber = 7, + }; + // repeated .google.protobuf.FieldDescriptorProto field = 2; + int field_size() const; + private: + int _internal_field_size() const; + public: + void clear_field(); + ::PROTOBUF_NAMESPACE_ID::FieldDescriptorProto* mutable_field(int index); + ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::FieldDescriptorProto >* + mutable_field(); + private: + const ::PROTOBUF_NAMESPACE_ID::FieldDescriptorProto& _internal_field(int index) const; + ::PROTOBUF_NAMESPACE_ID::FieldDescriptorProto* _internal_add_field(); + public: + const ::PROTOBUF_NAMESPACE_ID::FieldDescriptorProto& field(int index) const; + ::PROTOBUF_NAMESPACE_ID::FieldDescriptorProto* add_field(); + const ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::FieldDescriptorProto >& + field() const; + + // repeated .google.protobuf.DescriptorProto nested_type = 3; + int nested_type_size() const; + private: + int _internal_nested_type_size() const; + public: + void clear_nested_type(); + ::PROTOBUF_NAMESPACE_ID::DescriptorProto* mutable_nested_type(int index); + ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::DescriptorProto >* + mutable_nested_type(); + private: + const ::PROTOBUF_NAMESPACE_ID::DescriptorProto& _internal_nested_type(int index) const; + ::PROTOBUF_NAMESPACE_ID::DescriptorProto* _internal_add_nested_type(); + public: + const ::PROTOBUF_NAMESPACE_ID::DescriptorProto& nested_type(int index) const; + ::PROTOBUF_NAMESPACE_ID::DescriptorProto* add_nested_type(); + const ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::DescriptorProto >& + nested_type() const; + + // repeated .google.protobuf.EnumDescriptorProto enum_type = 4; + int enum_type_size() const; + private: + int _internal_enum_type_size() const; + public: + void clear_enum_type(); + ::PROTOBUF_NAMESPACE_ID::EnumDescriptorProto* mutable_enum_type(int index); + ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::EnumDescriptorProto >* + mutable_enum_type(); + private: + const ::PROTOBUF_NAMESPACE_ID::EnumDescriptorProto& _internal_enum_type(int index) const; + ::PROTOBUF_NAMESPACE_ID::EnumDescriptorProto* _internal_add_enum_type(); + public: + const ::PROTOBUF_NAMESPACE_ID::EnumDescriptorProto& enum_type(int index) const; + ::PROTOBUF_NAMESPACE_ID::EnumDescriptorProto* add_enum_type(); + const ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::EnumDescriptorProto >& + enum_type() const; + + // repeated .google.protobuf.DescriptorProto.ExtensionRange extension_range = 5; + int extension_range_size() const; + private: + int _internal_extension_range_size() const; + public: + void clear_extension_range(); + ::PROTOBUF_NAMESPACE_ID::DescriptorProto_ExtensionRange* mutable_extension_range(int index); + ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::DescriptorProto_ExtensionRange >* + mutable_extension_range(); + private: + const ::PROTOBUF_NAMESPACE_ID::DescriptorProto_ExtensionRange& _internal_extension_range(int index) const; + ::PROTOBUF_NAMESPACE_ID::DescriptorProto_ExtensionRange* _internal_add_extension_range(); + public: + const ::PROTOBUF_NAMESPACE_ID::DescriptorProto_ExtensionRange& extension_range(int index) const; + ::PROTOBUF_NAMESPACE_ID::DescriptorProto_ExtensionRange* add_extension_range(); + const ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::DescriptorProto_ExtensionRange >& + extension_range() const; + + // repeated .google.protobuf.FieldDescriptorProto extension = 6; + int extension_size() const; + private: + int _internal_extension_size() const; + public: + void clear_extension(); + ::PROTOBUF_NAMESPACE_ID::FieldDescriptorProto* mutable_extension(int index); + ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::FieldDescriptorProto >* + mutable_extension(); + private: + const ::PROTOBUF_NAMESPACE_ID::FieldDescriptorProto& _internal_extension(int index) const; + ::PROTOBUF_NAMESPACE_ID::FieldDescriptorProto* _internal_add_extension(); + public: + const ::PROTOBUF_NAMESPACE_ID::FieldDescriptorProto& extension(int index) const; + ::PROTOBUF_NAMESPACE_ID::FieldDescriptorProto* add_extension(); + const ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::FieldDescriptorProto >& + extension() const; + + // repeated .google.protobuf.OneofDescriptorProto oneof_decl = 8; + int oneof_decl_size() const; + private: + int _internal_oneof_decl_size() const; + public: + void clear_oneof_decl(); + ::PROTOBUF_NAMESPACE_ID::OneofDescriptorProto* mutable_oneof_decl(int index); + ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::OneofDescriptorProto >* + mutable_oneof_decl(); + private: + const ::PROTOBUF_NAMESPACE_ID::OneofDescriptorProto& _internal_oneof_decl(int index) const; + ::PROTOBUF_NAMESPACE_ID::OneofDescriptorProto* _internal_add_oneof_decl(); + public: + const ::PROTOBUF_NAMESPACE_ID::OneofDescriptorProto& oneof_decl(int index) const; + ::PROTOBUF_NAMESPACE_ID::OneofDescriptorProto* add_oneof_decl(); + const ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::OneofDescriptorProto >& + oneof_decl() const; + + // repeated .google.protobuf.DescriptorProto.ReservedRange reserved_range = 9; + int reserved_range_size() const; + private: + int _internal_reserved_range_size() const; + public: + void clear_reserved_range(); + ::PROTOBUF_NAMESPACE_ID::DescriptorProto_ReservedRange* mutable_reserved_range(int index); + ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::DescriptorProto_ReservedRange >* + mutable_reserved_range(); + private: + const ::PROTOBUF_NAMESPACE_ID::DescriptorProto_ReservedRange& _internal_reserved_range(int index) const; + ::PROTOBUF_NAMESPACE_ID::DescriptorProto_ReservedRange* _internal_add_reserved_range(); + public: + const ::PROTOBUF_NAMESPACE_ID::DescriptorProto_ReservedRange& reserved_range(int index) const; + ::PROTOBUF_NAMESPACE_ID::DescriptorProto_ReservedRange* add_reserved_range(); + const ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::DescriptorProto_ReservedRange >& + reserved_range() const; + + // repeated string reserved_name = 10; + int reserved_name_size() const; + private: + int _internal_reserved_name_size() const; + public: + void clear_reserved_name(); + const TProtoStringType& reserved_name(int index) const; + TProtoStringType* mutable_reserved_name(int index); + void set_reserved_name(int index, const TProtoStringType& value); + void set_reserved_name(int index, TProtoStringType&& value); + void set_reserved_name(int index, const char* value); + void set_reserved_name(int index, const char* value, size_t size); + TProtoStringType* add_reserved_name(); + void add_reserved_name(const TProtoStringType& value); + void add_reserved_name(TProtoStringType&& value); + void add_reserved_name(const char* value); + void add_reserved_name(const char* value, size_t size); + const ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField<TProtoStringType>& reserved_name() const; + ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField<TProtoStringType>* mutable_reserved_name(); + private: + const TProtoStringType& _internal_reserved_name(int index) const; + TProtoStringType* _internal_add_reserved_name(); + public: + + // optional string name = 1; + bool has_name() const; + private: + bool _internal_has_name() const; + public: + void clear_name(); + const TProtoStringType& name() const; + template <typename ArgT0 = const TProtoStringType&, typename... ArgT> + void set_name(ArgT0&& arg0, ArgT... args); + TProtoStringType* mutable_name(); + PROTOBUF_NODISCARD TProtoStringType* release_name(); + void set_allocated_name(TProtoStringType* name); + private: + const TProtoStringType& _internal_name() const; + inline PROTOBUF_ALWAYS_INLINE void _internal_set_name(const TProtoStringType& value); + TProtoStringType* _internal_mutable_name(); + public: + + // optional .google.protobuf.MessageOptions options = 7; + bool has_options() const; + private: + bool _internal_has_options() const; + public: + void clear_options(); + const ::PROTOBUF_NAMESPACE_ID::MessageOptions& options() const; + PROTOBUF_NODISCARD ::PROTOBUF_NAMESPACE_ID::MessageOptions* release_options(); + ::PROTOBUF_NAMESPACE_ID::MessageOptions* mutable_options(); + void set_allocated_options(::PROTOBUF_NAMESPACE_ID::MessageOptions* options); + private: + const ::PROTOBUF_NAMESPACE_ID::MessageOptions& _internal_options() const; + ::PROTOBUF_NAMESPACE_ID::MessageOptions* _internal_mutable_options(); + public: + void unsafe_arena_set_allocated_options( + ::PROTOBUF_NAMESPACE_ID::MessageOptions* options); + ::PROTOBUF_NAMESPACE_ID::MessageOptions* unsafe_arena_release_options(); + + // @@protoc_insertion_point(class_scope:google.protobuf.DescriptorProto) + private: + class _Internal; + + template <typename T> friend class ::PROTOBUF_NAMESPACE_ID::Arena::InternalHelper; + typedef void InternalArenaConstructable_; + typedef void DestructorSkippable_; + ::PROTOBUF_NAMESPACE_ID::internal::HasBits<1> _has_bits_; + mutable ::PROTOBUF_NAMESPACE_ID::internal::CachedSize _cached_size_; + ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::FieldDescriptorProto > field_; + ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::DescriptorProto > nested_type_; + ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::EnumDescriptorProto > enum_type_; + ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::DescriptorProto_ExtensionRange > extension_range_; + ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::FieldDescriptorProto > extension_; + ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::OneofDescriptorProto > oneof_decl_; + ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::DescriptorProto_ReservedRange > reserved_range_; + ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField<TProtoStringType> reserved_name_; + ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr name_; + ::PROTOBUF_NAMESPACE_ID::MessageOptions* options_; + friend struct ::TableStruct_google_2fprotobuf_2fdescriptor_2eproto; +}; +// ------------------------------------------------------------------- + +class PROTOBUF_EXPORT ExtensionRangeOptions final : + public ::PROTOBUF_NAMESPACE_ID::Message /* @@protoc_insertion_point(class_definition:google.protobuf.ExtensionRangeOptions) */ { + public: + inline ExtensionRangeOptions() : ExtensionRangeOptions(nullptr) {} + ~ExtensionRangeOptions() override; + explicit constexpr ExtensionRangeOptions(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized); + + ExtensionRangeOptions(const ExtensionRangeOptions& from); + ExtensionRangeOptions(ExtensionRangeOptions&& from) noexcept + : ExtensionRangeOptions() { + *this = ::std::move(from); + } + + inline ExtensionRangeOptions& operator=(const ExtensionRangeOptions& from) { + CopyFrom(from); + return *this; + } + inline ExtensionRangeOptions& operator=(ExtensionRangeOptions&& from) noexcept { + if (this == &from) return *this; + if (GetOwningArena() == from.GetOwningArena() + #ifdef PROTOBUF_FORCE_COPY_IN_MOVE + && GetOwningArena() != nullptr + #endif // !PROTOBUF_FORCE_COPY_IN_MOVE + ) { + InternalSwap(&from); + } else { + CopyFrom(from); + } + return *this; + } + + inline const ::PROTOBUF_NAMESPACE_ID::UnknownFieldSet& unknown_fields() const { + return _internal_metadata_.unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(::PROTOBUF_NAMESPACE_ID::UnknownFieldSet::default_instance); + } + inline ::PROTOBUF_NAMESPACE_ID::UnknownFieldSet* mutable_unknown_fields() { + return _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(); + } + + static const ::PROTOBUF_NAMESPACE_ID::Descriptor* descriptor() { + return GetDescriptor(); + } + static const ::PROTOBUF_NAMESPACE_ID::Descriptor* GetDescriptor() { + return default_instance().GetMetadata().descriptor; + } + static const ::PROTOBUF_NAMESPACE_ID::Reflection* GetReflection() { + return default_instance().GetMetadata().reflection; + } + static const ExtensionRangeOptions& default_instance() { + return *internal_default_instance(); + } + static inline const ExtensionRangeOptions* internal_default_instance() { + return reinterpret_cast<const ExtensionRangeOptions*>( + &_ExtensionRangeOptions_default_instance_); + } + static constexpr int kIndexInFileMessages = + 5; + + friend void swap(ExtensionRangeOptions& a, ExtensionRangeOptions& b) { + a.Swap(&b); + } + inline void Swap(ExtensionRangeOptions* other) { + if (other == this) return; + #ifdef PROTOBUF_FORCE_COPY_IN_SWAP + if (GetOwningArena() != nullptr && + GetOwningArena() == other->GetOwningArena()) { + #else // PROTOBUF_FORCE_COPY_IN_SWAP + if (GetOwningArena() == other->GetOwningArena()) { + #endif // !PROTOBUF_FORCE_COPY_IN_SWAP + InternalSwap(other); + } else { + ::PROTOBUF_NAMESPACE_ID::internal::GenericSwap(this, other); + } + } + void UnsafeArenaSwap(ExtensionRangeOptions* other) { + if (other == this) return; + GOOGLE_DCHECK(GetOwningArena() == other->GetOwningArena()); + InternalSwap(other); + } + + // implements Message ---------------------------------------------- + + ExtensionRangeOptions* New(::PROTOBUF_NAMESPACE_ID::Arena* arena = nullptr) const final { + return CreateMaybeMessage<ExtensionRangeOptions>(arena); + } + using ::PROTOBUF_NAMESPACE_ID::Message::CopyFrom; + void CopyFrom(const ExtensionRangeOptions& from); + using ::PROTOBUF_NAMESPACE_ID::Message::MergeFrom; + void MergeFrom(const ExtensionRangeOptions& 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; + + size_t ByteSizeLong() const final; + const char* _InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) final; + uint8_t* _InternalSerialize( + uint8_t* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const final; + int GetCachedSize() const final { return _cached_size_.Get(); } + + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const final; + void InternalSwap(ExtensionRangeOptions* other); + + private: + friend class ::PROTOBUF_NAMESPACE_ID::internal::AnyMetadata; + static ::PROTOBUF_NAMESPACE_ID::StringPiece FullMessageName() { + return "google.protobuf.ExtensionRangeOptions"; + } + protected: + explicit ExtensionRangeOptions(::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 ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + enum : int { + kUninterpretedOptionFieldNumber = 999, + }; + // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999; + int uninterpreted_option_size() const; + private: + int _internal_uninterpreted_option_size() const; + public: + void clear_uninterpreted_option(); + ::PROTOBUF_NAMESPACE_ID::UninterpretedOption* mutable_uninterpreted_option(int index); + ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::UninterpretedOption >* + mutable_uninterpreted_option(); + private: + const ::PROTOBUF_NAMESPACE_ID::UninterpretedOption& _internal_uninterpreted_option(int index) const; + ::PROTOBUF_NAMESPACE_ID::UninterpretedOption* _internal_add_uninterpreted_option(); + public: + const ::PROTOBUF_NAMESPACE_ID::UninterpretedOption& uninterpreted_option(int index) const; + ::PROTOBUF_NAMESPACE_ID::UninterpretedOption* add_uninterpreted_option(); + const ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::UninterpretedOption >& + uninterpreted_option() const; + + + template <typename _proto_TypeTraits, + ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type, + bool _is_packed> + inline bool HasExtension( + const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier< + ExtensionRangeOptions, _proto_TypeTraits, _field_type, _is_packed>& id) const { + + return _extensions_.Has(id.number()); + } + + template <typename _proto_TypeTraits, + ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type, + bool _is_packed> + inline void ClearExtension( + const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier< + ExtensionRangeOptions, _proto_TypeTraits, _field_type, _is_packed>& id) { + _extensions_.ClearExtension(id.number()); + + } + + template <typename _proto_TypeTraits, + ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type, + bool _is_packed> + inline int ExtensionSize( + const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier< + ExtensionRangeOptions, _proto_TypeTraits, _field_type, _is_packed>& id) const { + + return _extensions_.ExtensionSize(id.number()); + } + + template <typename _proto_TypeTraits, + ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type, + bool _is_packed> + inline typename _proto_TypeTraits::Singular::ConstType GetExtension( + const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier< + ExtensionRangeOptions, _proto_TypeTraits, _field_type, _is_packed>& id) const { + + return _proto_TypeTraits::Get(id.number(), _extensions_, + id.default_value()); + } + + template <typename _proto_TypeTraits, + ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type, + bool _is_packed> + inline typename _proto_TypeTraits::Singular::MutableType MutableExtension( + const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier< + ExtensionRangeOptions, _proto_TypeTraits, _field_type, _is_packed>& id) { + + return _proto_TypeTraits::Mutable(id.number(), _field_type, + &_extensions_); + } + + template <typename _proto_TypeTraits, + ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type, + bool _is_packed> + inline void SetExtension( + const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier< + ExtensionRangeOptions, _proto_TypeTraits, _field_type, _is_packed>& id, + typename _proto_TypeTraits::Singular::ConstType value) { + _proto_TypeTraits::Set(id.number(), _field_type, value, &_extensions_); + + } + + template <typename _proto_TypeTraits, + ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type, + bool _is_packed> + inline void SetAllocatedExtension( + const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier< + ExtensionRangeOptions, _proto_TypeTraits, _field_type, _is_packed>& id, + typename _proto_TypeTraits::Singular::MutableType value) { + _proto_TypeTraits::SetAllocated(id.number(), _field_type, value, + &_extensions_); + + } + template <typename _proto_TypeTraits, + ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type, + bool _is_packed> + inline void UnsafeArenaSetAllocatedExtension( + const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier< + ExtensionRangeOptions, _proto_TypeTraits, _field_type, _is_packed>& id, + typename _proto_TypeTraits::Singular::MutableType value) { + _proto_TypeTraits::UnsafeArenaSetAllocated(id.number(), _field_type, + value, &_extensions_); + + } + template <typename _proto_TypeTraits, + ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type, + bool _is_packed> + PROTOBUF_NODISCARD inline + typename _proto_TypeTraits::Singular::MutableType + ReleaseExtension( + const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier< + ExtensionRangeOptions, _proto_TypeTraits, _field_type, _is_packed>& id) { + + return _proto_TypeTraits::Release(id.number(), _field_type, + &_extensions_); + } + template <typename _proto_TypeTraits, + ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type, + bool _is_packed> + inline typename _proto_TypeTraits::Singular::MutableType + UnsafeArenaReleaseExtension( + const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier< + ExtensionRangeOptions, _proto_TypeTraits, _field_type, _is_packed>& id) { + + return _proto_TypeTraits::UnsafeArenaRelease(id.number(), _field_type, + &_extensions_); + } + + template <typename _proto_TypeTraits, + ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type, + bool _is_packed> + inline typename _proto_TypeTraits::Repeated::ConstType GetExtension( + const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier< + ExtensionRangeOptions, _proto_TypeTraits, _field_type, _is_packed>& id, + int index) const { + + return _proto_TypeTraits::Get(id.number(), _extensions_, index); + } + + template <typename _proto_TypeTraits, + ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type, + bool _is_packed> + inline typename _proto_TypeTraits::Repeated::MutableType MutableExtension( + const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier< + ExtensionRangeOptions, _proto_TypeTraits, _field_type, _is_packed>& id, + int index) { + + return _proto_TypeTraits::Mutable(id.number(), index, &_extensions_); + } + + template <typename _proto_TypeTraits, + ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type, + bool _is_packed> + inline void SetExtension( + const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier< + ExtensionRangeOptions, _proto_TypeTraits, _field_type, _is_packed>& id, + int index, typename _proto_TypeTraits::Repeated::ConstType value) { + _proto_TypeTraits::Set(id.number(), index, value, &_extensions_); + + } + + template <typename _proto_TypeTraits, + ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type, + bool _is_packed> + inline typename _proto_TypeTraits::Repeated::MutableType AddExtension( + const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier< + ExtensionRangeOptions, _proto_TypeTraits, _field_type, _is_packed>& id) { + typename _proto_TypeTraits::Repeated::MutableType to_add = + _proto_TypeTraits::Add(id.number(), _field_type, &_extensions_); + + return to_add; + } + + template <typename _proto_TypeTraits, + ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type, + bool _is_packed> + inline void AddExtension( + const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier< + ExtensionRangeOptions, _proto_TypeTraits, _field_type, _is_packed>& id, + typename _proto_TypeTraits::Repeated::ConstType value) { + _proto_TypeTraits::Add(id.number(), _field_type, _is_packed, value, + &_extensions_); + + } + + template <typename _proto_TypeTraits, + ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type, + bool _is_packed> + inline const typename _proto_TypeTraits::Repeated::RepeatedFieldType& + GetRepeatedExtension( + const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier< + ExtensionRangeOptions, _proto_TypeTraits, _field_type, _is_packed>& id) const { + + return _proto_TypeTraits::GetRepeated(id.number(), _extensions_); + } + + template <typename _proto_TypeTraits, + ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type, + bool _is_packed> + inline typename _proto_TypeTraits::Repeated::RepeatedFieldType* + MutableRepeatedExtension( + const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier< + ExtensionRangeOptions, _proto_TypeTraits, _field_type, _is_packed>& id) { + + return _proto_TypeTraits::MutableRepeated(id.number(), _field_type, + _is_packed, &_extensions_); + } + + // @@protoc_insertion_point(class_scope:google.protobuf.ExtensionRangeOptions) + private: + class _Internal; + + ::PROTOBUF_NAMESPACE_ID::internal::ExtensionSet _extensions_; + + template <typename T> friend class ::PROTOBUF_NAMESPACE_ID::Arena::InternalHelper; + typedef void InternalArenaConstructable_; + typedef void DestructorSkippable_; + ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::UninterpretedOption > uninterpreted_option_; + mutable ::PROTOBUF_NAMESPACE_ID::internal::CachedSize _cached_size_; + friend struct ::TableStruct_google_2fprotobuf_2fdescriptor_2eproto; +}; +// ------------------------------------------------------------------- + +class PROTOBUF_EXPORT FieldDescriptorProto final : + public ::PROTOBUF_NAMESPACE_ID::Message /* @@protoc_insertion_point(class_definition:google.protobuf.FieldDescriptorProto) */ { + public: + inline FieldDescriptorProto() : FieldDescriptorProto(nullptr) {} + ~FieldDescriptorProto() override; + explicit constexpr FieldDescriptorProto(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized); + + FieldDescriptorProto(const FieldDescriptorProto& from); + FieldDescriptorProto(FieldDescriptorProto&& from) noexcept + : FieldDescriptorProto() { + *this = ::std::move(from); + } + + inline FieldDescriptorProto& operator=(const FieldDescriptorProto& from) { + CopyFrom(from); + return *this; + } + inline FieldDescriptorProto& operator=(FieldDescriptorProto&& from) noexcept { + if (this == &from) return *this; + if (GetOwningArena() == from.GetOwningArena() + #ifdef PROTOBUF_FORCE_COPY_IN_MOVE + && GetOwningArena() != nullptr + #endif // !PROTOBUF_FORCE_COPY_IN_MOVE + ) { + InternalSwap(&from); + } else { + CopyFrom(from); + } + return *this; + } + + inline const ::PROTOBUF_NAMESPACE_ID::UnknownFieldSet& unknown_fields() const { + return _internal_metadata_.unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(::PROTOBUF_NAMESPACE_ID::UnknownFieldSet::default_instance); + } + inline ::PROTOBUF_NAMESPACE_ID::UnknownFieldSet* mutable_unknown_fields() { + return _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(); + } + + static const ::PROTOBUF_NAMESPACE_ID::Descriptor* descriptor() { + return GetDescriptor(); + } + static const ::PROTOBUF_NAMESPACE_ID::Descriptor* GetDescriptor() { + return default_instance().GetMetadata().descriptor; + } + static const ::PROTOBUF_NAMESPACE_ID::Reflection* GetReflection() { + return default_instance().GetMetadata().reflection; + } + static const FieldDescriptorProto& default_instance() { + return *internal_default_instance(); + } + static inline const FieldDescriptorProto* internal_default_instance() { + return reinterpret_cast<const FieldDescriptorProto*>( + &_FieldDescriptorProto_default_instance_); + } + static constexpr int kIndexInFileMessages = + 6; + + friend void swap(FieldDescriptorProto& a, FieldDescriptorProto& b) { + a.Swap(&b); + } + inline void Swap(FieldDescriptorProto* other) { + if (other == this) return; + #ifdef PROTOBUF_FORCE_COPY_IN_SWAP + if (GetOwningArena() != nullptr && + GetOwningArena() == other->GetOwningArena()) { + #else // PROTOBUF_FORCE_COPY_IN_SWAP + if (GetOwningArena() == other->GetOwningArena()) { + #endif // !PROTOBUF_FORCE_COPY_IN_SWAP + InternalSwap(other); + } else { + ::PROTOBUF_NAMESPACE_ID::internal::GenericSwap(this, other); + } + } + void UnsafeArenaSwap(FieldDescriptorProto* other) { + if (other == this) return; + GOOGLE_DCHECK(GetOwningArena() == other->GetOwningArena()); + InternalSwap(other); + } + + // implements Message ---------------------------------------------- + + FieldDescriptorProto* New(::PROTOBUF_NAMESPACE_ID::Arena* arena = nullptr) const final { + return CreateMaybeMessage<FieldDescriptorProto>(arena); + } + using ::PROTOBUF_NAMESPACE_ID::Message::CopyFrom; + void CopyFrom(const FieldDescriptorProto& from); + using ::PROTOBUF_NAMESPACE_ID::Message::MergeFrom; + void MergeFrom(const FieldDescriptorProto& 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; + + size_t ByteSizeLong() const final; + const char* _InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) final; + uint8_t* _InternalSerialize( + uint8_t* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const final; + int GetCachedSize() const final { return _cached_size_.Get(); } + + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const final; + void InternalSwap(FieldDescriptorProto* other); + + private: + friend class ::PROTOBUF_NAMESPACE_ID::internal::AnyMetadata; + static ::PROTOBUF_NAMESPACE_ID::StringPiece FullMessageName() { + return "google.protobuf.FieldDescriptorProto"; + } + protected: + explicit FieldDescriptorProto(::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 ---------------------------------------------------- + + typedef FieldDescriptorProto_Type Type; + static constexpr Type TYPE_DOUBLE = + FieldDescriptorProto_Type_TYPE_DOUBLE; + static constexpr Type TYPE_FLOAT = + FieldDescriptorProto_Type_TYPE_FLOAT; + static constexpr Type TYPE_INT64 = + FieldDescriptorProto_Type_TYPE_INT64; + static constexpr Type TYPE_UINT64 = + FieldDescriptorProto_Type_TYPE_UINT64; + static constexpr Type TYPE_INT32 = + FieldDescriptorProto_Type_TYPE_INT32; + static constexpr Type TYPE_FIXED64 = + FieldDescriptorProto_Type_TYPE_FIXED64; + static constexpr Type TYPE_FIXED32 = + FieldDescriptorProto_Type_TYPE_FIXED32; + static constexpr Type TYPE_BOOL = + FieldDescriptorProto_Type_TYPE_BOOL; + static constexpr Type TYPE_STRING = + FieldDescriptorProto_Type_TYPE_STRING; + static constexpr Type TYPE_GROUP = + FieldDescriptorProto_Type_TYPE_GROUP; + static constexpr Type TYPE_MESSAGE = + FieldDescriptorProto_Type_TYPE_MESSAGE; + static constexpr Type TYPE_BYTES = + FieldDescriptorProto_Type_TYPE_BYTES; + static constexpr Type TYPE_UINT32 = + FieldDescriptorProto_Type_TYPE_UINT32; + static constexpr Type TYPE_ENUM = + FieldDescriptorProto_Type_TYPE_ENUM; + static constexpr Type TYPE_SFIXED32 = + FieldDescriptorProto_Type_TYPE_SFIXED32; + static constexpr Type TYPE_SFIXED64 = + FieldDescriptorProto_Type_TYPE_SFIXED64; + static constexpr Type TYPE_SINT32 = + FieldDescriptorProto_Type_TYPE_SINT32; + static constexpr Type TYPE_SINT64 = + FieldDescriptorProto_Type_TYPE_SINT64; + static inline bool Type_IsValid(int value) { + return FieldDescriptorProto_Type_IsValid(value); + } + static constexpr Type Type_MIN = + FieldDescriptorProto_Type_Type_MIN; + static constexpr Type Type_MAX = + FieldDescriptorProto_Type_Type_MAX; + static constexpr int Type_ARRAYSIZE = + FieldDescriptorProto_Type_Type_ARRAYSIZE; + static inline const ::PROTOBUF_NAMESPACE_ID::EnumDescriptor* + Type_descriptor() { + return FieldDescriptorProto_Type_descriptor(); + } + template<typename T> + static inline const TProtoStringType& Type_Name(T enum_t_value) { + static_assert(::std::is_same<T, Type>::value || + ::std::is_integral<T>::value, + "Incorrect type passed to function Type_Name."); + return FieldDescriptorProto_Type_Name(enum_t_value); + } + static inline bool Type_Parse(::PROTOBUF_NAMESPACE_ID::ConstStringParam name, + Type* value) { + return FieldDescriptorProto_Type_Parse(name, value); + } + + typedef FieldDescriptorProto_Label Label; + static constexpr Label LABEL_OPTIONAL = + FieldDescriptorProto_Label_LABEL_OPTIONAL; + static constexpr Label LABEL_REQUIRED = + FieldDescriptorProto_Label_LABEL_REQUIRED; + static constexpr Label LABEL_REPEATED = + FieldDescriptorProto_Label_LABEL_REPEATED; + static inline bool Label_IsValid(int value) { + return FieldDescriptorProto_Label_IsValid(value); + } + static constexpr Label Label_MIN = + FieldDescriptorProto_Label_Label_MIN; + static constexpr Label Label_MAX = + FieldDescriptorProto_Label_Label_MAX; + static constexpr int Label_ARRAYSIZE = + FieldDescriptorProto_Label_Label_ARRAYSIZE; + static inline const ::PROTOBUF_NAMESPACE_ID::EnumDescriptor* + Label_descriptor() { + return FieldDescriptorProto_Label_descriptor(); + } + template<typename T> + static inline const TProtoStringType& Label_Name(T enum_t_value) { + static_assert(::std::is_same<T, Label>::value || + ::std::is_integral<T>::value, + "Incorrect type passed to function Label_Name."); + return FieldDescriptorProto_Label_Name(enum_t_value); + } + static inline bool Label_Parse(::PROTOBUF_NAMESPACE_ID::ConstStringParam name, + Label* value) { + return FieldDescriptorProto_Label_Parse(name, value); + } + + // accessors ------------------------------------------------------- + + enum : int { + kNameFieldNumber = 1, + kExtendeeFieldNumber = 2, + kTypeNameFieldNumber = 6, + kDefaultValueFieldNumber = 7, + kJsonNameFieldNumber = 10, + kOptionsFieldNumber = 8, + kNumberFieldNumber = 3, + kOneofIndexFieldNumber = 9, + kProto3OptionalFieldNumber = 17, + kLabelFieldNumber = 4, + kTypeFieldNumber = 5, + }; + // optional string name = 1; + bool has_name() const; + private: + bool _internal_has_name() const; + public: + void clear_name(); + const TProtoStringType& name() const; + template <typename ArgT0 = const TProtoStringType&, typename... ArgT> + void set_name(ArgT0&& arg0, ArgT... args); + TProtoStringType* mutable_name(); + PROTOBUF_NODISCARD TProtoStringType* release_name(); + void set_allocated_name(TProtoStringType* name); + private: + const TProtoStringType& _internal_name() const; + inline PROTOBUF_ALWAYS_INLINE void _internal_set_name(const TProtoStringType& value); + TProtoStringType* _internal_mutable_name(); + public: + + // optional string extendee = 2; + bool has_extendee() const; + private: + bool _internal_has_extendee() const; + public: + void clear_extendee(); + const TProtoStringType& extendee() const; + template <typename ArgT0 = const TProtoStringType&, typename... ArgT> + void set_extendee(ArgT0&& arg0, ArgT... args); + TProtoStringType* mutable_extendee(); + PROTOBUF_NODISCARD TProtoStringType* release_extendee(); + void set_allocated_extendee(TProtoStringType* extendee); + private: + const TProtoStringType& _internal_extendee() const; + inline PROTOBUF_ALWAYS_INLINE void _internal_set_extendee(const TProtoStringType& value); + TProtoStringType* _internal_mutable_extendee(); + public: + + // optional string type_name = 6; + bool has_type_name() const; + private: + bool _internal_has_type_name() const; + public: + void clear_type_name(); + const TProtoStringType& type_name() const; + template <typename ArgT0 = const TProtoStringType&, typename... ArgT> + void set_type_name(ArgT0&& arg0, ArgT... args); + TProtoStringType* mutable_type_name(); + PROTOBUF_NODISCARD TProtoStringType* release_type_name(); + void set_allocated_type_name(TProtoStringType* type_name); + private: + const TProtoStringType& _internal_type_name() const; + inline PROTOBUF_ALWAYS_INLINE void _internal_set_type_name(const TProtoStringType& value); + TProtoStringType* _internal_mutable_type_name(); + public: + + // optional string default_value = 7; + bool has_default_value() const; + private: + bool _internal_has_default_value() const; + public: + void clear_default_value(); + const TProtoStringType& default_value() const; + template <typename ArgT0 = const TProtoStringType&, typename... ArgT> + void set_default_value(ArgT0&& arg0, ArgT... args); + TProtoStringType* mutable_default_value(); + PROTOBUF_NODISCARD TProtoStringType* release_default_value(); + void set_allocated_default_value(TProtoStringType* default_value); + private: + const TProtoStringType& _internal_default_value() const; + inline PROTOBUF_ALWAYS_INLINE void _internal_set_default_value(const TProtoStringType& value); + TProtoStringType* _internal_mutable_default_value(); + public: + + // optional string json_name = 10; + bool has_json_name() const; + private: + bool _internal_has_json_name() const; + public: + void clear_json_name(); + const TProtoStringType& json_name() const; + template <typename ArgT0 = const TProtoStringType&, typename... ArgT> + void set_json_name(ArgT0&& arg0, ArgT... args); + TProtoStringType* mutable_json_name(); + PROTOBUF_NODISCARD TProtoStringType* release_json_name(); + void set_allocated_json_name(TProtoStringType* json_name); + private: + const TProtoStringType& _internal_json_name() const; + inline PROTOBUF_ALWAYS_INLINE void _internal_set_json_name(const TProtoStringType& value); + TProtoStringType* _internal_mutable_json_name(); + public: + + // optional .google.protobuf.FieldOptions options = 8; + bool has_options() const; + private: + bool _internal_has_options() const; + public: + void clear_options(); + const ::PROTOBUF_NAMESPACE_ID::FieldOptions& options() const; + PROTOBUF_NODISCARD ::PROTOBUF_NAMESPACE_ID::FieldOptions* release_options(); + ::PROTOBUF_NAMESPACE_ID::FieldOptions* mutable_options(); + void set_allocated_options(::PROTOBUF_NAMESPACE_ID::FieldOptions* options); + private: + const ::PROTOBUF_NAMESPACE_ID::FieldOptions& _internal_options() const; + ::PROTOBUF_NAMESPACE_ID::FieldOptions* _internal_mutable_options(); + public: + void unsafe_arena_set_allocated_options( + ::PROTOBUF_NAMESPACE_ID::FieldOptions* options); + ::PROTOBUF_NAMESPACE_ID::FieldOptions* unsafe_arena_release_options(); + + // optional int32 number = 3; + bool has_number() const; + private: + bool _internal_has_number() const; + public: + void clear_number(); + arc_i32 number() const; + void set_number(arc_i32 value); + private: + arc_i32 _internal_number() const; + void _internal_set_number(arc_i32 value); + public: + + // optional int32 oneof_index = 9; + bool has_oneof_index() const; + private: + bool _internal_has_oneof_index() const; + public: + void clear_oneof_index(); + arc_i32 oneof_index() const; + void set_oneof_index(arc_i32 value); + private: + arc_i32 _internal_oneof_index() const; + void _internal_set_oneof_index(arc_i32 value); + public: + + // optional bool proto3_optional = 17; + bool has_proto3_optional() const; + private: + bool _internal_has_proto3_optional() const; + public: + void clear_proto3_optional(); + bool proto3_optional() const; + void set_proto3_optional(bool value); + private: + bool _internal_proto3_optional() const; + void _internal_set_proto3_optional(bool value); + public: + + // optional .google.protobuf.FieldDescriptorProto.Label label = 4; + bool has_label() const; + private: + bool _internal_has_label() const; + public: + void clear_label(); + ::PROTOBUF_NAMESPACE_ID::FieldDescriptorProto_Label label() const; + void set_label(::PROTOBUF_NAMESPACE_ID::FieldDescriptorProto_Label value); + private: + ::PROTOBUF_NAMESPACE_ID::FieldDescriptorProto_Label _internal_label() const; + void _internal_set_label(::PROTOBUF_NAMESPACE_ID::FieldDescriptorProto_Label value); + public: + + // optional .google.protobuf.FieldDescriptorProto.Type type = 5; + bool has_type() const; + private: + bool _internal_has_type() const; + public: + void clear_type(); + ::PROTOBUF_NAMESPACE_ID::FieldDescriptorProto_Type type() const; + void set_type(::PROTOBUF_NAMESPACE_ID::FieldDescriptorProto_Type value); + private: + ::PROTOBUF_NAMESPACE_ID::FieldDescriptorProto_Type _internal_type() const; + void _internal_set_type(::PROTOBUF_NAMESPACE_ID::FieldDescriptorProto_Type value); + public: + + // @@protoc_insertion_point(class_scope:google.protobuf.FieldDescriptorProto) + private: + class _Internal; + + template <typename T> friend class ::PROTOBUF_NAMESPACE_ID::Arena::InternalHelper; + typedef void InternalArenaConstructable_; + typedef void DestructorSkippable_; + ::PROTOBUF_NAMESPACE_ID::internal::HasBits<1> _has_bits_; + mutable ::PROTOBUF_NAMESPACE_ID::internal::CachedSize _cached_size_; + ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr name_; + ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr extendee_; + ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr type_name_; + ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr default_value_; + ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr json_name_; + ::PROTOBUF_NAMESPACE_ID::FieldOptions* options_; + arc_i32 number_; + arc_i32 oneof_index_; + bool proto3_optional_; + int label_; + int type_; + friend struct ::TableStruct_google_2fprotobuf_2fdescriptor_2eproto; +}; +// ------------------------------------------------------------------- + +class PROTOBUF_EXPORT OneofDescriptorProto final : + public ::PROTOBUF_NAMESPACE_ID::Message /* @@protoc_insertion_point(class_definition:google.protobuf.OneofDescriptorProto) */ { + public: + inline OneofDescriptorProto() : OneofDescriptorProto(nullptr) {} + ~OneofDescriptorProto() override; + explicit constexpr OneofDescriptorProto(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized); + + OneofDescriptorProto(const OneofDescriptorProto& from); + OneofDescriptorProto(OneofDescriptorProto&& from) noexcept + : OneofDescriptorProto() { + *this = ::std::move(from); + } + + inline OneofDescriptorProto& operator=(const OneofDescriptorProto& from) { + CopyFrom(from); + return *this; + } + inline OneofDescriptorProto& operator=(OneofDescriptorProto&& from) noexcept { + if (this == &from) return *this; + if (GetOwningArena() == from.GetOwningArena() + #ifdef PROTOBUF_FORCE_COPY_IN_MOVE + && GetOwningArena() != nullptr + #endif // !PROTOBUF_FORCE_COPY_IN_MOVE + ) { + InternalSwap(&from); + } else { + CopyFrom(from); + } + return *this; + } + + inline const ::PROTOBUF_NAMESPACE_ID::UnknownFieldSet& unknown_fields() const { + return _internal_metadata_.unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(::PROTOBUF_NAMESPACE_ID::UnknownFieldSet::default_instance); + } + inline ::PROTOBUF_NAMESPACE_ID::UnknownFieldSet* mutable_unknown_fields() { + return _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(); + } + + static const ::PROTOBUF_NAMESPACE_ID::Descriptor* descriptor() { + return GetDescriptor(); + } + static const ::PROTOBUF_NAMESPACE_ID::Descriptor* GetDescriptor() { + return default_instance().GetMetadata().descriptor; + } + static const ::PROTOBUF_NAMESPACE_ID::Reflection* GetReflection() { + return default_instance().GetMetadata().reflection; + } + static const OneofDescriptorProto& default_instance() { + return *internal_default_instance(); + } + static inline const OneofDescriptorProto* internal_default_instance() { + return reinterpret_cast<const OneofDescriptorProto*>( + &_OneofDescriptorProto_default_instance_); + } + static constexpr int kIndexInFileMessages = + 7; + + friend void swap(OneofDescriptorProto& a, OneofDescriptorProto& b) { + a.Swap(&b); + } + inline void Swap(OneofDescriptorProto* other) { + if (other == this) return; + #ifdef PROTOBUF_FORCE_COPY_IN_SWAP + if (GetOwningArena() != nullptr && + GetOwningArena() == other->GetOwningArena()) { + #else // PROTOBUF_FORCE_COPY_IN_SWAP + if (GetOwningArena() == other->GetOwningArena()) { + #endif // !PROTOBUF_FORCE_COPY_IN_SWAP + InternalSwap(other); + } else { + ::PROTOBUF_NAMESPACE_ID::internal::GenericSwap(this, other); + } + } + void UnsafeArenaSwap(OneofDescriptorProto* other) { + if (other == this) return; + GOOGLE_DCHECK(GetOwningArena() == other->GetOwningArena()); + InternalSwap(other); + } + + // implements Message ---------------------------------------------- + + OneofDescriptorProto* New(::PROTOBUF_NAMESPACE_ID::Arena* arena = nullptr) const final { + return CreateMaybeMessage<OneofDescriptorProto>(arena); + } + using ::PROTOBUF_NAMESPACE_ID::Message::CopyFrom; + void CopyFrom(const OneofDescriptorProto& from); + using ::PROTOBUF_NAMESPACE_ID::Message::MergeFrom; + void MergeFrom(const OneofDescriptorProto& 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; + + size_t ByteSizeLong() const final; + const char* _InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) final; + uint8_t* _InternalSerialize( + uint8_t* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const final; + int GetCachedSize() const final { return _cached_size_.Get(); } + + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const final; + void InternalSwap(OneofDescriptorProto* other); + + private: + friend class ::PROTOBUF_NAMESPACE_ID::internal::AnyMetadata; + static ::PROTOBUF_NAMESPACE_ID::StringPiece FullMessageName() { + return "google.protobuf.OneofDescriptorProto"; + } + protected: + explicit OneofDescriptorProto(::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 ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + enum : int { + kNameFieldNumber = 1, + kOptionsFieldNumber = 2, + }; + // optional string name = 1; + bool has_name() const; + private: + bool _internal_has_name() const; + public: + void clear_name(); + const TProtoStringType& name() const; + template <typename ArgT0 = const TProtoStringType&, typename... ArgT> + void set_name(ArgT0&& arg0, ArgT... args); + TProtoStringType* mutable_name(); + PROTOBUF_NODISCARD TProtoStringType* release_name(); + void set_allocated_name(TProtoStringType* name); + private: + const TProtoStringType& _internal_name() const; + inline PROTOBUF_ALWAYS_INLINE void _internal_set_name(const TProtoStringType& value); + TProtoStringType* _internal_mutable_name(); + public: + + // optional .google.protobuf.OneofOptions options = 2; + bool has_options() const; + private: + bool _internal_has_options() const; + public: + void clear_options(); + const ::PROTOBUF_NAMESPACE_ID::OneofOptions& options() const; + PROTOBUF_NODISCARD ::PROTOBUF_NAMESPACE_ID::OneofOptions* release_options(); + ::PROTOBUF_NAMESPACE_ID::OneofOptions* mutable_options(); + void set_allocated_options(::PROTOBUF_NAMESPACE_ID::OneofOptions* options); + private: + const ::PROTOBUF_NAMESPACE_ID::OneofOptions& _internal_options() const; + ::PROTOBUF_NAMESPACE_ID::OneofOptions* _internal_mutable_options(); + public: + void unsafe_arena_set_allocated_options( + ::PROTOBUF_NAMESPACE_ID::OneofOptions* options); + ::PROTOBUF_NAMESPACE_ID::OneofOptions* unsafe_arena_release_options(); + + // @@protoc_insertion_point(class_scope:google.protobuf.OneofDescriptorProto) + private: + class _Internal; + + template <typename T> friend class ::PROTOBUF_NAMESPACE_ID::Arena::InternalHelper; + typedef void InternalArenaConstructable_; + typedef void DestructorSkippable_; + ::PROTOBUF_NAMESPACE_ID::internal::HasBits<1> _has_bits_; + mutable ::PROTOBUF_NAMESPACE_ID::internal::CachedSize _cached_size_; + ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr name_; + ::PROTOBUF_NAMESPACE_ID::OneofOptions* options_; + friend struct ::TableStruct_google_2fprotobuf_2fdescriptor_2eproto; +}; +// ------------------------------------------------------------------- + +class PROTOBUF_EXPORT EnumDescriptorProto_EnumReservedRange final : + public ::PROTOBUF_NAMESPACE_ID::Message /* @@protoc_insertion_point(class_definition:google.protobuf.EnumDescriptorProto.EnumReservedRange) */ { + public: + inline EnumDescriptorProto_EnumReservedRange() : EnumDescriptorProto_EnumReservedRange(nullptr) {} + ~EnumDescriptorProto_EnumReservedRange() override; + explicit constexpr EnumDescriptorProto_EnumReservedRange(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized); + + EnumDescriptorProto_EnumReservedRange(const EnumDescriptorProto_EnumReservedRange& from); + EnumDescriptorProto_EnumReservedRange(EnumDescriptorProto_EnumReservedRange&& from) noexcept + : EnumDescriptorProto_EnumReservedRange() { + *this = ::std::move(from); + } + + inline EnumDescriptorProto_EnumReservedRange& operator=(const EnumDescriptorProto_EnumReservedRange& from) { + CopyFrom(from); + return *this; + } + inline EnumDescriptorProto_EnumReservedRange& operator=(EnumDescriptorProto_EnumReservedRange&& from) noexcept { + if (this == &from) return *this; + if (GetOwningArena() == from.GetOwningArena() + #ifdef PROTOBUF_FORCE_COPY_IN_MOVE + && GetOwningArena() != nullptr + #endif // !PROTOBUF_FORCE_COPY_IN_MOVE + ) { + InternalSwap(&from); + } else { + CopyFrom(from); + } + return *this; + } + + inline const ::PROTOBUF_NAMESPACE_ID::UnknownFieldSet& unknown_fields() const { + return _internal_metadata_.unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(::PROTOBUF_NAMESPACE_ID::UnknownFieldSet::default_instance); + } + inline ::PROTOBUF_NAMESPACE_ID::UnknownFieldSet* mutable_unknown_fields() { + return _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(); + } + + static const ::PROTOBUF_NAMESPACE_ID::Descriptor* descriptor() { + return GetDescriptor(); + } + static const ::PROTOBUF_NAMESPACE_ID::Descriptor* GetDescriptor() { + return default_instance().GetMetadata().descriptor; + } + static const ::PROTOBUF_NAMESPACE_ID::Reflection* GetReflection() { + return default_instance().GetMetadata().reflection; + } + static const EnumDescriptorProto_EnumReservedRange& default_instance() { + return *internal_default_instance(); + } + static inline const EnumDescriptorProto_EnumReservedRange* internal_default_instance() { + return reinterpret_cast<const EnumDescriptorProto_EnumReservedRange*>( + &_EnumDescriptorProto_EnumReservedRange_default_instance_); + } + static constexpr int kIndexInFileMessages = + 8; + + friend void swap(EnumDescriptorProto_EnumReservedRange& a, EnumDescriptorProto_EnumReservedRange& b) { + a.Swap(&b); + } + inline void Swap(EnumDescriptorProto_EnumReservedRange* other) { + if (other == this) return; + #ifdef PROTOBUF_FORCE_COPY_IN_SWAP + if (GetOwningArena() != nullptr && + GetOwningArena() == other->GetOwningArena()) { + #else // PROTOBUF_FORCE_COPY_IN_SWAP + if (GetOwningArena() == other->GetOwningArena()) { + #endif // !PROTOBUF_FORCE_COPY_IN_SWAP + InternalSwap(other); + } else { + ::PROTOBUF_NAMESPACE_ID::internal::GenericSwap(this, other); + } + } + void UnsafeArenaSwap(EnumDescriptorProto_EnumReservedRange* other) { + if (other == this) return; + GOOGLE_DCHECK(GetOwningArena() == other->GetOwningArena()); + InternalSwap(other); + } + + // implements Message ---------------------------------------------- + + EnumDescriptorProto_EnumReservedRange* New(::PROTOBUF_NAMESPACE_ID::Arena* arena = nullptr) const final { + return CreateMaybeMessage<EnumDescriptorProto_EnumReservedRange>(arena); + } + using ::PROTOBUF_NAMESPACE_ID::Message::CopyFrom; + void CopyFrom(const EnumDescriptorProto_EnumReservedRange& from); + using ::PROTOBUF_NAMESPACE_ID::Message::MergeFrom; + void MergeFrom(const EnumDescriptorProto_EnumReservedRange& 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; + + size_t ByteSizeLong() const final; + const char* _InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) final; + uint8_t* _InternalSerialize( + uint8_t* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const final; + int GetCachedSize() const final { return _cached_size_.Get(); } + + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const final; + void InternalSwap(EnumDescriptorProto_EnumReservedRange* other); + + private: + friend class ::PROTOBUF_NAMESPACE_ID::internal::AnyMetadata; + static ::PROTOBUF_NAMESPACE_ID::StringPiece FullMessageName() { + return "google.protobuf.EnumDescriptorProto.EnumReservedRange"; + } + protected: + explicit EnumDescriptorProto_EnumReservedRange(::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 ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + enum : int { + kStartFieldNumber = 1, + kEndFieldNumber = 2, + }; + // optional int32 start = 1; + bool has_start() const; + private: + bool _internal_has_start() const; + public: + void clear_start(); + arc_i32 start() const; + void set_start(arc_i32 value); + private: + arc_i32 _internal_start() const; + void _internal_set_start(arc_i32 value); + public: + + // optional int32 end = 2; + bool has_end() const; + private: + bool _internal_has_end() const; + public: + void clear_end(); + arc_i32 end() const; + void set_end(arc_i32 value); + private: + arc_i32 _internal_end() const; + void _internal_set_end(arc_i32 value); + public: + + // @@protoc_insertion_point(class_scope:google.protobuf.EnumDescriptorProto.EnumReservedRange) + private: + class _Internal; + + template <typename T> friend class ::PROTOBUF_NAMESPACE_ID::Arena::InternalHelper; + typedef void InternalArenaConstructable_; + typedef void DestructorSkippable_; + ::PROTOBUF_NAMESPACE_ID::internal::HasBits<1> _has_bits_; + mutable ::PROTOBUF_NAMESPACE_ID::internal::CachedSize _cached_size_; + arc_i32 start_; + arc_i32 end_; + friend struct ::TableStruct_google_2fprotobuf_2fdescriptor_2eproto; +}; +// ------------------------------------------------------------------- + +class PROTOBUF_EXPORT EnumDescriptorProto final : + public ::PROTOBUF_NAMESPACE_ID::Message /* @@protoc_insertion_point(class_definition:google.protobuf.EnumDescriptorProto) */ { + public: + inline EnumDescriptorProto() : EnumDescriptorProto(nullptr) {} + ~EnumDescriptorProto() override; + explicit constexpr EnumDescriptorProto(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized); + + EnumDescriptorProto(const EnumDescriptorProto& from); + EnumDescriptorProto(EnumDescriptorProto&& from) noexcept + : EnumDescriptorProto() { + *this = ::std::move(from); + } + + inline EnumDescriptorProto& operator=(const EnumDescriptorProto& from) { + CopyFrom(from); + return *this; + } + inline EnumDescriptorProto& operator=(EnumDescriptorProto&& from) noexcept { + if (this == &from) return *this; + if (GetOwningArena() == from.GetOwningArena() + #ifdef PROTOBUF_FORCE_COPY_IN_MOVE + && GetOwningArena() != nullptr + #endif // !PROTOBUF_FORCE_COPY_IN_MOVE + ) { + InternalSwap(&from); + } else { + CopyFrom(from); + } + return *this; + } + + inline const ::PROTOBUF_NAMESPACE_ID::UnknownFieldSet& unknown_fields() const { + return _internal_metadata_.unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(::PROTOBUF_NAMESPACE_ID::UnknownFieldSet::default_instance); + } + inline ::PROTOBUF_NAMESPACE_ID::UnknownFieldSet* mutable_unknown_fields() { + return _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(); + } + + static const ::PROTOBUF_NAMESPACE_ID::Descriptor* descriptor() { + return GetDescriptor(); + } + static const ::PROTOBUF_NAMESPACE_ID::Descriptor* GetDescriptor() { + return default_instance().GetMetadata().descriptor; + } + static const ::PROTOBUF_NAMESPACE_ID::Reflection* GetReflection() { + return default_instance().GetMetadata().reflection; + } + static const EnumDescriptorProto& default_instance() { + return *internal_default_instance(); + } + static inline const EnumDescriptorProto* internal_default_instance() { + return reinterpret_cast<const EnumDescriptorProto*>( + &_EnumDescriptorProto_default_instance_); + } + static constexpr int kIndexInFileMessages = + 9; + + friend void swap(EnumDescriptorProto& a, EnumDescriptorProto& b) { + a.Swap(&b); + } + inline void Swap(EnumDescriptorProto* other) { + if (other == this) return; + #ifdef PROTOBUF_FORCE_COPY_IN_SWAP + if (GetOwningArena() != nullptr && + GetOwningArena() == other->GetOwningArena()) { + #else // PROTOBUF_FORCE_COPY_IN_SWAP + if (GetOwningArena() == other->GetOwningArena()) { + #endif // !PROTOBUF_FORCE_COPY_IN_SWAP + InternalSwap(other); + } else { + ::PROTOBUF_NAMESPACE_ID::internal::GenericSwap(this, other); + } + } + void UnsafeArenaSwap(EnumDescriptorProto* other) { + if (other == this) return; + GOOGLE_DCHECK(GetOwningArena() == other->GetOwningArena()); + InternalSwap(other); + } + + // implements Message ---------------------------------------------- + + EnumDescriptorProto* New(::PROTOBUF_NAMESPACE_ID::Arena* arena = nullptr) const final { + return CreateMaybeMessage<EnumDescriptorProto>(arena); + } + using ::PROTOBUF_NAMESPACE_ID::Message::CopyFrom; + void CopyFrom(const EnumDescriptorProto& from); + using ::PROTOBUF_NAMESPACE_ID::Message::MergeFrom; + void MergeFrom(const EnumDescriptorProto& 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; + + size_t ByteSizeLong() const final; + const char* _InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) final; + uint8_t* _InternalSerialize( + uint8_t* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const final; + int GetCachedSize() const final { return _cached_size_.Get(); } + + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const final; + void InternalSwap(EnumDescriptorProto* other); + + private: + friend class ::PROTOBUF_NAMESPACE_ID::internal::AnyMetadata; + static ::PROTOBUF_NAMESPACE_ID::StringPiece FullMessageName() { + return "google.protobuf.EnumDescriptorProto"; + } + protected: + explicit EnumDescriptorProto(::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 ---------------------------------------------------- + + typedef EnumDescriptorProto_EnumReservedRange EnumReservedRange; + + // accessors ------------------------------------------------------- + + enum : int { + kValueFieldNumber = 2, + kReservedRangeFieldNumber = 4, + kReservedNameFieldNumber = 5, + kNameFieldNumber = 1, + kOptionsFieldNumber = 3, + }; + // repeated .google.protobuf.EnumValueDescriptorProto value = 2; + int value_size() const; + private: + int _internal_value_size() const; + public: + void clear_value(); + ::PROTOBUF_NAMESPACE_ID::EnumValueDescriptorProto* mutable_value(int index); + ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::EnumValueDescriptorProto >* + mutable_value(); + private: + const ::PROTOBUF_NAMESPACE_ID::EnumValueDescriptorProto& _internal_value(int index) const; + ::PROTOBUF_NAMESPACE_ID::EnumValueDescriptorProto* _internal_add_value(); + public: + const ::PROTOBUF_NAMESPACE_ID::EnumValueDescriptorProto& value(int index) const; + ::PROTOBUF_NAMESPACE_ID::EnumValueDescriptorProto* add_value(); + const ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::EnumValueDescriptorProto >& + value() const; + + // repeated .google.protobuf.EnumDescriptorProto.EnumReservedRange reserved_range = 4; + int reserved_range_size() const; + private: + int _internal_reserved_range_size() const; + public: + void clear_reserved_range(); + ::PROTOBUF_NAMESPACE_ID::EnumDescriptorProto_EnumReservedRange* mutable_reserved_range(int index); + ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::EnumDescriptorProto_EnumReservedRange >* + mutable_reserved_range(); + private: + const ::PROTOBUF_NAMESPACE_ID::EnumDescriptorProto_EnumReservedRange& _internal_reserved_range(int index) const; + ::PROTOBUF_NAMESPACE_ID::EnumDescriptorProto_EnumReservedRange* _internal_add_reserved_range(); + public: + const ::PROTOBUF_NAMESPACE_ID::EnumDescriptorProto_EnumReservedRange& reserved_range(int index) const; + ::PROTOBUF_NAMESPACE_ID::EnumDescriptorProto_EnumReservedRange* add_reserved_range(); + const ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::EnumDescriptorProto_EnumReservedRange >& + reserved_range() const; + + // repeated string reserved_name = 5; + int reserved_name_size() const; + private: + int _internal_reserved_name_size() const; + public: + void clear_reserved_name(); + const TProtoStringType& reserved_name(int index) const; + TProtoStringType* mutable_reserved_name(int index); + void set_reserved_name(int index, const TProtoStringType& value); + void set_reserved_name(int index, TProtoStringType&& value); + void set_reserved_name(int index, const char* value); + void set_reserved_name(int index, const char* value, size_t size); + TProtoStringType* add_reserved_name(); + void add_reserved_name(const TProtoStringType& value); + void add_reserved_name(TProtoStringType&& value); + void add_reserved_name(const char* value); + void add_reserved_name(const char* value, size_t size); + const ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField<TProtoStringType>& reserved_name() const; + ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField<TProtoStringType>* mutable_reserved_name(); + private: + const TProtoStringType& _internal_reserved_name(int index) const; + TProtoStringType* _internal_add_reserved_name(); + public: + + // optional string name = 1; + bool has_name() const; + private: + bool _internal_has_name() const; + public: + void clear_name(); + const TProtoStringType& name() const; + template <typename ArgT0 = const TProtoStringType&, typename... ArgT> + void set_name(ArgT0&& arg0, ArgT... args); + TProtoStringType* mutable_name(); + PROTOBUF_NODISCARD TProtoStringType* release_name(); + void set_allocated_name(TProtoStringType* name); + private: + const TProtoStringType& _internal_name() const; + inline PROTOBUF_ALWAYS_INLINE void _internal_set_name(const TProtoStringType& value); + TProtoStringType* _internal_mutable_name(); + public: + + // optional .google.protobuf.EnumOptions options = 3; + bool has_options() const; + private: + bool _internal_has_options() const; + public: + void clear_options(); + const ::PROTOBUF_NAMESPACE_ID::EnumOptions& options() const; + PROTOBUF_NODISCARD ::PROTOBUF_NAMESPACE_ID::EnumOptions* release_options(); + ::PROTOBUF_NAMESPACE_ID::EnumOptions* mutable_options(); + void set_allocated_options(::PROTOBUF_NAMESPACE_ID::EnumOptions* options); + private: + const ::PROTOBUF_NAMESPACE_ID::EnumOptions& _internal_options() const; + ::PROTOBUF_NAMESPACE_ID::EnumOptions* _internal_mutable_options(); + public: + void unsafe_arena_set_allocated_options( + ::PROTOBUF_NAMESPACE_ID::EnumOptions* options); + ::PROTOBUF_NAMESPACE_ID::EnumOptions* unsafe_arena_release_options(); + + // @@protoc_insertion_point(class_scope:google.protobuf.EnumDescriptorProto) + private: + class _Internal; + + template <typename T> friend class ::PROTOBUF_NAMESPACE_ID::Arena::InternalHelper; + typedef void InternalArenaConstructable_; + typedef void DestructorSkippable_; + ::PROTOBUF_NAMESPACE_ID::internal::HasBits<1> _has_bits_; + mutable ::PROTOBUF_NAMESPACE_ID::internal::CachedSize _cached_size_; + ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::EnumValueDescriptorProto > value_; + ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::EnumDescriptorProto_EnumReservedRange > reserved_range_; + ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField<TProtoStringType> reserved_name_; + ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr name_; + ::PROTOBUF_NAMESPACE_ID::EnumOptions* options_; + friend struct ::TableStruct_google_2fprotobuf_2fdescriptor_2eproto; +}; +// ------------------------------------------------------------------- + +class PROTOBUF_EXPORT EnumValueDescriptorProto final : + public ::PROTOBUF_NAMESPACE_ID::Message /* @@protoc_insertion_point(class_definition:google.protobuf.EnumValueDescriptorProto) */ { + public: + inline EnumValueDescriptorProto() : EnumValueDescriptorProto(nullptr) {} + ~EnumValueDescriptorProto() override; + explicit constexpr EnumValueDescriptorProto(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized); + + EnumValueDescriptorProto(const EnumValueDescriptorProto& from); + EnumValueDescriptorProto(EnumValueDescriptorProto&& from) noexcept + : EnumValueDescriptorProto() { + *this = ::std::move(from); + } + + inline EnumValueDescriptorProto& operator=(const EnumValueDescriptorProto& from) { + CopyFrom(from); + return *this; + } + inline EnumValueDescriptorProto& operator=(EnumValueDescriptorProto&& from) noexcept { + if (this == &from) return *this; + if (GetOwningArena() == from.GetOwningArena() + #ifdef PROTOBUF_FORCE_COPY_IN_MOVE + && GetOwningArena() != nullptr + #endif // !PROTOBUF_FORCE_COPY_IN_MOVE + ) { + InternalSwap(&from); + } else { + CopyFrom(from); + } + return *this; + } + + inline const ::PROTOBUF_NAMESPACE_ID::UnknownFieldSet& unknown_fields() const { + return _internal_metadata_.unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(::PROTOBUF_NAMESPACE_ID::UnknownFieldSet::default_instance); + } + inline ::PROTOBUF_NAMESPACE_ID::UnknownFieldSet* mutable_unknown_fields() { + return _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(); + } + + static const ::PROTOBUF_NAMESPACE_ID::Descriptor* descriptor() { + return GetDescriptor(); + } + static const ::PROTOBUF_NAMESPACE_ID::Descriptor* GetDescriptor() { + return default_instance().GetMetadata().descriptor; + } + static const ::PROTOBUF_NAMESPACE_ID::Reflection* GetReflection() { + return default_instance().GetMetadata().reflection; + } + static const EnumValueDescriptorProto& default_instance() { + return *internal_default_instance(); + } + static inline const EnumValueDescriptorProto* internal_default_instance() { + return reinterpret_cast<const EnumValueDescriptorProto*>( + &_EnumValueDescriptorProto_default_instance_); + } + static constexpr int kIndexInFileMessages = + 10; + + friend void swap(EnumValueDescriptorProto& a, EnumValueDescriptorProto& b) { + a.Swap(&b); + } + inline void Swap(EnumValueDescriptorProto* other) { + if (other == this) return; + #ifdef PROTOBUF_FORCE_COPY_IN_SWAP + if (GetOwningArena() != nullptr && + GetOwningArena() == other->GetOwningArena()) { + #else // PROTOBUF_FORCE_COPY_IN_SWAP + if (GetOwningArena() == other->GetOwningArena()) { + #endif // !PROTOBUF_FORCE_COPY_IN_SWAP + InternalSwap(other); + } else { + ::PROTOBUF_NAMESPACE_ID::internal::GenericSwap(this, other); + } + } + void UnsafeArenaSwap(EnumValueDescriptorProto* other) { + if (other == this) return; + GOOGLE_DCHECK(GetOwningArena() == other->GetOwningArena()); + InternalSwap(other); + } + + // implements Message ---------------------------------------------- + + EnumValueDescriptorProto* New(::PROTOBUF_NAMESPACE_ID::Arena* arena = nullptr) const final { + return CreateMaybeMessage<EnumValueDescriptorProto>(arena); + } + using ::PROTOBUF_NAMESPACE_ID::Message::CopyFrom; + void CopyFrom(const EnumValueDescriptorProto& from); + using ::PROTOBUF_NAMESPACE_ID::Message::MergeFrom; + void MergeFrom(const EnumValueDescriptorProto& 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; + + size_t ByteSizeLong() const final; + const char* _InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) final; + uint8_t* _InternalSerialize( + uint8_t* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const final; + int GetCachedSize() const final { return _cached_size_.Get(); } + + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const final; + void InternalSwap(EnumValueDescriptorProto* other); + + private: + friend class ::PROTOBUF_NAMESPACE_ID::internal::AnyMetadata; + static ::PROTOBUF_NAMESPACE_ID::StringPiece FullMessageName() { + return "google.protobuf.EnumValueDescriptorProto"; + } + protected: + explicit EnumValueDescriptorProto(::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 ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + enum : int { + kNameFieldNumber = 1, + kOptionsFieldNumber = 3, + kNumberFieldNumber = 2, + }; + // optional string name = 1; + bool has_name() const; + private: + bool _internal_has_name() const; + public: + void clear_name(); + const TProtoStringType& name() const; + template <typename ArgT0 = const TProtoStringType&, typename... ArgT> + void set_name(ArgT0&& arg0, ArgT... args); + TProtoStringType* mutable_name(); + PROTOBUF_NODISCARD TProtoStringType* release_name(); + void set_allocated_name(TProtoStringType* name); + private: + const TProtoStringType& _internal_name() const; + inline PROTOBUF_ALWAYS_INLINE void _internal_set_name(const TProtoStringType& value); + TProtoStringType* _internal_mutable_name(); + public: + + // optional .google.protobuf.EnumValueOptions options = 3; + bool has_options() const; + private: + bool _internal_has_options() const; + public: + void clear_options(); + const ::PROTOBUF_NAMESPACE_ID::EnumValueOptions& options() const; + PROTOBUF_NODISCARD ::PROTOBUF_NAMESPACE_ID::EnumValueOptions* release_options(); + ::PROTOBUF_NAMESPACE_ID::EnumValueOptions* mutable_options(); + void set_allocated_options(::PROTOBUF_NAMESPACE_ID::EnumValueOptions* options); + private: + const ::PROTOBUF_NAMESPACE_ID::EnumValueOptions& _internal_options() const; + ::PROTOBUF_NAMESPACE_ID::EnumValueOptions* _internal_mutable_options(); + public: + void unsafe_arena_set_allocated_options( + ::PROTOBUF_NAMESPACE_ID::EnumValueOptions* options); + ::PROTOBUF_NAMESPACE_ID::EnumValueOptions* unsafe_arena_release_options(); + + // optional int32 number = 2; + bool has_number() const; + private: + bool _internal_has_number() const; + public: + void clear_number(); + arc_i32 number() const; + void set_number(arc_i32 value); + private: + arc_i32 _internal_number() const; + void _internal_set_number(arc_i32 value); + public: + + // @@protoc_insertion_point(class_scope:google.protobuf.EnumValueDescriptorProto) + private: + class _Internal; + + template <typename T> friend class ::PROTOBUF_NAMESPACE_ID::Arena::InternalHelper; + typedef void InternalArenaConstructable_; + typedef void DestructorSkippable_; + ::PROTOBUF_NAMESPACE_ID::internal::HasBits<1> _has_bits_; + mutable ::PROTOBUF_NAMESPACE_ID::internal::CachedSize _cached_size_; + ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr name_; + ::PROTOBUF_NAMESPACE_ID::EnumValueOptions* options_; + arc_i32 number_; + friend struct ::TableStruct_google_2fprotobuf_2fdescriptor_2eproto; +}; +// ------------------------------------------------------------------- + +class PROTOBUF_EXPORT ServiceDescriptorProto final : + public ::PROTOBUF_NAMESPACE_ID::Message /* @@protoc_insertion_point(class_definition:google.protobuf.ServiceDescriptorProto) */ { + public: + inline ServiceDescriptorProto() : ServiceDescriptorProto(nullptr) {} + ~ServiceDescriptorProto() override; + explicit constexpr ServiceDescriptorProto(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized); + + ServiceDescriptorProto(const ServiceDescriptorProto& from); + ServiceDescriptorProto(ServiceDescriptorProto&& from) noexcept + : ServiceDescriptorProto() { + *this = ::std::move(from); + } + + inline ServiceDescriptorProto& operator=(const ServiceDescriptorProto& from) { + CopyFrom(from); + return *this; + } + inline ServiceDescriptorProto& operator=(ServiceDescriptorProto&& from) noexcept { + if (this == &from) return *this; + if (GetOwningArena() == from.GetOwningArena() + #ifdef PROTOBUF_FORCE_COPY_IN_MOVE + && GetOwningArena() != nullptr + #endif // !PROTOBUF_FORCE_COPY_IN_MOVE + ) { + InternalSwap(&from); + } else { + CopyFrom(from); + } + return *this; + } + + inline const ::PROTOBUF_NAMESPACE_ID::UnknownFieldSet& unknown_fields() const { + return _internal_metadata_.unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(::PROTOBUF_NAMESPACE_ID::UnknownFieldSet::default_instance); + } + inline ::PROTOBUF_NAMESPACE_ID::UnknownFieldSet* mutable_unknown_fields() { + return _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(); + } + + static const ::PROTOBUF_NAMESPACE_ID::Descriptor* descriptor() { + return GetDescriptor(); + } + static const ::PROTOBUF_NAMESPACE_ID::Descriptor* GetDescriptor() { + return default_instance().GetMetadata().descriptor; + } + static const ::PROTOBUF_NAMESPACE_ID::Reflection* GetReflection() { + return default_instance().GetMetadata().reflection; + } + static const ServiceDescriptorProto& default_instance() { + return *internal_default_instance(); + } + static inline const ServiceDescriptorProto* internal_default_instance() { + return reinterpret_cast<const ServiceDescriptorProto*>( + &_ServiceDescriptorProto_default_instance_); + } + static constexpr int kIndexInFileMessages = + 11; + + friend void swap(ServiceDescriptorProto& a, ServiceDescriptorProto& b) { + a.Swap(&b); + } + inline void Swap(ServiceDescriptorProto* other) { + if (other == this) return; + #ifdef PROTOBUF_FORCE_COPY_IN_SWAP + if (GetOwningArena() != nullptr && + GetOwningArena() == other->GetOwningArena()) { + #else // PROTOBUF_FORCE_COPY_IN_SWAP + if (GetOwningArena() == other->GetOwningArena()) { + #endif // !PROTOBUF_FORCE_COPY_IN_SWAP + InternalSwap(other); + } else { + ::PROTOBUF_NAMESPACE_ID::internal::GenericSwap(this, other); + } + } + void UnsafeArenaSwap(ServiceDescriptorProto* other) { + if (other == this) return; + GOOGLE_DCHECK(GetOwningArena() == other->GetOwningArena()); + InternalSwap(other); + } + + // implements Message ---------------------------------------------- + + ServiceDescriptorProto* New(::PROTOBUF_NAMESPACE_ID::Arena* arena = nullptr) const final { + return CreateMaybeMessage<ServiceDescriptorProto>(arena); + } + using ::PROTOBUF_NAMESPACE_ID::Message::CopyFrom; + void CopyFrom(const ServiceDescriptorProto& from); + using ::PROTOBUF_NAMESPACE_ID::Message::MergeFrom; + void MergeFrom(const ServiceDescriptorProto& 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; + + size_t ByteSizeLong() const final; + const char* _InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) final; + uint8_t* _InternalSerialize( + uint8_t* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const final; + int GetCachedSize() const final { return _cached_size_.Get(); } + + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const final; + void InternalSwap(ServiceDescriptorProto* other); + + private: + friend class ::PROTOBUF_NAMESPACE_ID::internal::AnyMetadata; + static ::PROTOBUF_NAMESPACE_ID::StringPiece FullMessageName() { + return "google.protobuf.ServiceDescriptorProto"; + } + protected: + explicit ServiceDescriptorProto(::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 ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + enum : int { + kMethodFieldNumber = 2, + kNameFieldNumber = 1, + kOptionsFieldNumber = 3, + }; + // repeated .google.protobuf.MethodDescriptorProto method = 2; + int method_size() const; + private: + int _internal_method_size() const; + public: + void clear_method(); + ::PROTOBUF_NAMESPACE_ID::MethodDescriptorProto* mutable_method(int index); + ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::MethodDescriptorProto >* + mutable_method(); + private: + const ::PROTOBUF_NAMESPACE_ID::MethodDescriptorProto& _internal_method(int index) const; + ::PROTOBUF_NAMESPACE_ID::MethodDescriptorProto* _internal_add_method(); + public: + const ::PROTOBUF_NAMESPACE_ID::MethodDescriptorProto& method(int index) const; + ::PROTOBUF_NAMESPACE_ID::MethodDescriptorProto* add_method(); + const ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::MethodDescriptorProto >& + method() const; + + // optional string name = 1; + bool has_name() const; + private: + bool _internal_has_name() const; + public: + void clear_name(); + const TProtoStringType& name() const; + template <typename ArgT0 = const TProtoStringType&, typename... ArgT> + void set_name(ArgT0&& arg0, ArgT... args); + TProtoStringType* mutable_name(); + PROTOBUF_NODISCARD TProtoStringType* release_name(); + void set_allocated_name(TProtoStringType* name); + private: + const TProtoStringType& _internal_name() const; + inline PROTOBUF_ALWAYS_INLINE void _internal_set_name(const TProtoStringType& value); + TProtoStringType* _internal_mutable_name(); + public: + + // optional .google.protobuf.ServiceOptions options = 3; + bool has_options() const; + private: + bool _internal_has_options() const; + public: + void clear_options(); + const ::PROTOBUF_NAMESPACE_ID::ServiceOptions& options() const; + PROTOBUF_NODISCARD ::PROTOBUF_NAMESPACE_ID::ServiceOptions* release_options(); + ::PROTOBUF_NAMESPACE_ID::ServiceOptions* mutable_options(); + void set_allocated_options(::PROTOBUF_NAMESPACE_ID::ServiceOptions* options); + private: + const ::PROTOBUF_NAMESPACE_ID::ServiceOptions& _internal_options() const; + ::PROTOBUF_NAMESPACE_ID::ServiceOptions* _internal_mutable_options(); + public: + void unsafe_arena_set_allocated_options( + ::PROTOBUF_NAMESPACE_ID::ServiceOptions* options); + ::PROTOBUF_NAMESPACE_ID::ServiceOptions* unsafe_arena_release_options(); + + // @@protoc_insertion_point(class_scope:google.protobuf.ServiceDescriptorProto) + private: + class _Internal; + + template <typename T> friend class ::PROTOBUF_NAMESPACE_ID::Arena::InternalHelper; + typedef void InternalArenaConstructable_; + typedef void DestructorSkippable_; + ::PROTOBUF_NAMESPACE_ID::internal::HasBits<1> _has_bits_; + mutable ::PROTOBUF_NAMESPACE_ID::internal::CachedSize _cached_size_; + ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::MethodDescriptorProto > method_; + ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr name_; + ::PROTOBUF_NAMESPACE_ID::ServiceOptions* options_; + friend struct ::TableStruct_google_2fprotobuf_2fdescriptor_2eproto; +}; +// ------------------------------------------------------------------- + +class PROTOBUF_EXPORT MethodDescriptorProto final : + public ::PROTOBUF_NAMESPACE_ID::Message /* @@protoc_insertion_point(class_definition:google.protobuf.MethodDescriptorProto) */ { + public: + inline MethodDescriptorProto() : MethodDescriptorProto(nullptr) {} + ~MethodDescriptorProto() override; + explicit constexpr MethodDescriptorProto(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized); + + MethodDescriptorProto(const MethodDescriptorProto& from); + MethodDescriptorProto(MethodDescriptorProto&& from) noexcept + : MethodDescriptorProto() { + *this = ::std::move(from); + } + + inline MethodDescriptorProto& operator=(const MethodDescriptorProto& from) { + CopyFrom(from); + return *this; + } + inline MethodDescriptorProto& operator=(MethodDescriptorProto&& from) noexcept { + if (this == &from) return *this; + if (GetOwningArena() == from.GetOwningArena() + #ifdef PROTOBUF_FORCE_COPY_IN_MOVE + && GetOwningArena() != nullptr + #endif // !PROTOBUF_FORCE_COPY_IN_MOVE + ) { + InternalSwap(&from); + } else { + CopyFrom(from); + } + return *this; + } + + inline const ::PROTOBUF_NAMESPACE_ID::UnknownFieldSet& unknown_fields() const { + return _internal_metadata_.unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(::PROTOBUF_NAMESPACE_ID::UnknownFieldSet::default_instance); + } + inline ::PROTOBUF_NAMESPACE_ID::UnknownFieldSet* mutable_unknown_fields() { + return _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(); + } + + static const ::PROTOBUF_NAMESPACE_ID::Descriptor* descriptor() { + return GetDescriptor(); + } + static const ::PROTOBUF_NAMESPACE_ID::Descriptor* GetDescriptor() { + return default_instance().GetMetadata().descriptor; + } + static const ::PROTOBUF_NAMESPACE_ID::Reflection* GetReflection() { + return default_instance().GetMetadata().reflection; + } + static const MethodDescriptorProto& default_instance() { + return *internal_default_instance(); + } + static inline const MethodDescriptorProto* internal_default_instance() { + return reinterpret_cast<const MethodDescriptorProto*>( + &_MethodDescriptorProto_default_instance_); + } + static constexpr int kIndexInFileMessages = + 12; + + friend void swap(MethodDescriptorProto& a, MethodDescriptorProto& b) { + a.Swap(&b); + } + inline void Swap(MethodDescriptorProto* other) { + if (other == this) return; + #ifdef PROTOBUF_FORCE_COPY_IN_SWAP + if (GetOwningArena() != nullptr && + GetOwningArena() == other->GetOwningArena()) { + #else // PROTOBUF_FORCE_COPY_IN_SWAP + if (GetOwningArena() == other->GetOwningArena()) { + #endif // !PROTOBUF_FORCE_COPY_IN_SWAP + InternalSwap(other); + } else { + ::PROTOBUF_NAMESPACE_ID::internal::GenericSwap(this, other); + } + } + void UnsafeArenaSwap(MethodDescriptorProto* other) { + if (other == this) return; + GOOGLE_DCHECK(GetOwningArena() == other->GetOwningArena()); + InternalSwap(other); + } + + // implements Message ---------------------------------------------- + + MethodDescriptorProto* New(::PROTOBUF_NAMESPACE_ID::Arena* arena = nullptr) const final { + return CreateMaybeMessage<MethodDescriptorProto>(arena); + } + using ::PROTOBUF_NAMESPACE_ID::Message::CopyFrom; + void CopyFrom(const MethodDescriptorProto& from); + using ::PROTOBUF_NAMESPACE_ID::Message::MergeFrom; + void MergeFrom(const MethodDescriptorProto& 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; + + size_t ByteSizeLong() const final; + const char* _InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) final; + uint8_t* _InternalSerialize( + uint8_t* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const final; + int GetCachedSize() const final { return _cached_size_.Get(); } + + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const final; + void InternalSwap(MethodDescriptorProto* other); + + private: + friend class ::PROTOBUF_NAMESPACE_ID::internal::AnyMetadata; + static ::PROTOBUF_NAMESPACE_ID::StringPiece FullMessageName() { + return "google.protobuf.MethodDescriptorProto"; + } + protected: + explicit MethodDescriptorProto(::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 ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + enum : int { + kNameFieldNumber = 1, + kInputTypeFieldNumber = 2, + kOutputTypeFieldNumber = 3, + kOptionsFieldNumber = 4, + kClientStreamingFieldNumber = 5, + kServerStreamingFieldNumber = 6, + }; + // optional string name = 1; + bool has_name() const; + private: + bool _internal_has_name() const; + public: + void clear_name(); + const TProtoStringType& name() const; + template <typename ArgT0 = const TProtoStringType&, typename... ArgT> + void set_name(ArgT0&& arg0, ArgT... args); + TProtoStringType* mutable_name(); + PROTOBUF_NODISCARD TProtoStringType* release_name(); + void set_allocated_name(TProtoStringType* name); + private: + const TProtoStringType& _internal_name() const; + inline PROTOBUF_ALWAYS_INLINE void _internal_set_name(const TProtoStringType& value); + TProtoStringType* _internal_mutable_name(); + public: + + // optional string input_type = 2; + bool has_input_type() const; + private: + bool _internal_has_input_type() const; + public: + void clear_input_type(); + const TProtoStringType& input_type() const; + template <typename ArgT0 = const TProtoStringType&, typename... ArgT> + void set_input_type(ArgT0&& arg0, ArgT... args); + TProtoStringType* mutable_input_type(); + PROTOBUF_NODISCARD TProtoStringType* release_input_type(); + void set_allocated_input_type(TProtoStringType* input_type); + private: + const TProtoStringType& _internal_input_type() const; + inline PROTOBUF_ALWAYS_INLINE void _internal_set_input_type(const TProtoStringType& value); + TProtoStringType* _internal_mutable_input_type(); + public: + + // optional string output_type = 3; + bool has_output_type() const; + private: + bool _internal_has_output_type() const; + public: + void clear_output_type(); + const TProtoStringType& output_type() const; + template <typename ArgT0 = const TProtoStringType&, typename... ArgT> + void set_output_type(ArgT0&& arg0, ArgT... args); + TProtoStringType* mutable_output_type(); + PROTOBUF_NODISCARD TProtoStringType* release_output_type(); + void set_allocated_output_type(TProtoStringType* output_type); + private: + const TProtoStringType& _internal_output_type() const; + inline PROTOBUF_ALWAYS_INLINE void _internal_set_output_type(const TProtoStringType& value); + TProtoStringType* _internal_mutable_output_type(); + public: + + // optional .google.protobuf.MethodOptions options = 4; + bool has_options() const; + private: + bool _internal_has_options() const; + public: + void clear_options(); + const ::PROTOBUF_NAMESPACE_ID::MethodOptions& options() const; + PROTOBUF_NODISCARD ::PROTOBUF_NAMESPACE_ID::MethodOptions* release_options(); + ::PROTOBUF_NAMESPACE_ID::MethodOptions* mutable_options(); + void set_allocated_options(::PROTOBUF_NAMESPACE_ID::MethodOptions* options); + private: + const ::PROTOBUF_NAMESPACE_ID::MethodOptions& _internal_options() const; + ::PROTOBUF_NAMESPACE_ID::MethodOptions* _internal_mutable_options(); + public: + void unsafe_arena_set_allocated_options( + ::PROTOBUF_NAMESPACE_ID::MethodOptions* options); + ::PROTOBUF_NAMESPACE_ID::MethodOptions* unsafe_arena_release_options(); + + // optional bool client_streaming = 5 [default = false]; + bool has_client_streaming() const; + private: + bool _internal_has_client_streaming() const; + public: + void clear_client_streaming(); + bool client_streaming() const; + void set_client_streaming(bool value); + private: + bool _internal_client_streaming() const; + void _internal_set_client_streaming(bool value); + public: + + // optional bool server_streaming = 6 [default = false]; + bool has_server_streaming() const; + private: + bool _internal_has_server_streaming() const; + public: + void clear_server_streaming(); + bool server_streaming() const; + void set_server_streaming(bool value); + private: + bool _internal_server_streaming() const; + void _internal_set_server_streaming(bool value); + public: + + // @@protoc_insertion_point(class_scope:google.protobuf.MethodDescriptorProto) + private: + class _Internal; + + template <typename T> friend class ::PROTOBUF_NAMESPACE_ID::Arena::InternalHelper; + typedef void InternalArenaConstructable_; + typedef void DestructorSkippable_; + ::PROTOBUF_NAMESPACE_ID::internal::HasBits<1> _has_bits_; + mutable ::PROTOBUF_NAMESPACE_ID::internal::CachedSize _cached_size_; + ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr name_; + ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr input_type_; + ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr output_type_; + ::PROTOBUF_NAMESPACE_ID::MethodOptions* options_; + bool client_streaming_; + bool server_streaming_; + friend struct ::TableStruct_google_2fprotobuf_2fdescriptor_2eproto; +}; +// ------------------------------------------------------------------- + +class PROTOBUF_EXPORT FileOptions final : + public ::PROTOBUF_NAMESPACE_ID::Message /* @@protoc_insertion_point(class_definition:google.protobuf.FileOptions) */ { + public: + inline FileOptions() : FileOptions(nullptr) {} + ~FileOptions() override; + explicit constexpr FileOptions(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized); + + FileOptions(const FileOptions& from); + FileOptions(FileOptions&& from) noexcept + : FileOptions() { + *this = ::std::move(from); + } + + inline FileOptions& operator=(const FileOptions& from) { + CopyFrom(from); + return *this; + } + inline FileOptions& operator=(FileOptions&& from) noexcept { + if (this == &from) return *this; + if (GetOwningArena() == from.GetOwningArena() + #ifdef PROTOBUF_FORCE_COPY_IN_MOVE + && GetOwningArena() != nullptr + #endif // !PROTOBUF_FORCE_COPY_IN_MOVE + ) { + InternalSwap(&from); + } else { + CopyFrom(from); + } + return *this; + } + + inline const ::PROTOBUF_NAMESPACE_ID::UnknownFieldSet& unknown_fields() const { + return _internal_metadata_.unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(::PROTOBUF_NAMESPACE_ID::UnknownFieldSet::default_instance); + } + inline ::PROTOBUF_NAMESPACE_ID::UnknownFieldSet* mutable_unknown_fields() { + return _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(); + } + + static const ::PROTOBUF_NAMESPACE_ID::Descriptor* descriptor() { + return GetDescriptor(); + } + static const ::PROTOBUF_NAMESPACE_ID::Descriptor* GetDescriptor() { + return default_instance().GetMetadata().descriptor; + } + static const ::PROTOBUF_NAMESPACE_ID::Reflection* GetReflection() { + return default_instance().GetMetadata().reflection; + } + static const FileOptions& default_instance() { + return *internal_default_instance(); + } + static inline const FileOptions* internal_default_instance() { + return reinterpret_cast<const FileOptions*>( + &_FileOptions_default_instance_); + } + static constexpr int kIndexInFileMessages = + 13; + + friend void swap(FileOptions& a, FileOptions& b) { + a.Swap(&b); + } + inline void Swap(FileOptions* other) { + if (other == this) return; + #ifdef PROTOBUF_FORCE_COPY_IN_SWAP + if (GetOwningArena() != nullptr && + GetOwningArena() == other->GetOwningArena()) { + #else // PROTOBUF_FORCE_COPY_IN_SWAP + if (GetOwningArena() == other->GetOwningArena()) { + #endif // !PROTOBUF_FORCE_COPY_IN_SWAP + InternalSwap(other); + } else { + ::PROTOBUF_NAMESPACE_ID::internal::GenericSwap(this, other); + } + } + void UnsafeArenaSwap(FileOptions* other) { + if (other == this) return; + GOOGLE_DCHECK(GetOwningArena() == other->GetOwningArena()); + InternalSwap(other); + } + + // implements Message ---------------------------------------------- + + FileOptions* New(::PROTOBUF_NAMESPACE_ID::Arena* arena = nullptr) const final { + return CreateMaybeMessage<FileOptions>(arena); + } + using ::PROTOBUF_NAMESPACE_ID::Message::CopyFrom; + void CopyFrom(const FileOptions& from); + using ::PROTOBUF_NAMESPACE_ID::Message::MergeFrom; + void MergeFrom(const FileOptions& 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; + + size_t ByteSizeLong() const final; + const char* _InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) final; + uint8_t* _InternalSerialize( + uint8_t* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const final; + int GetCachedSize() const final { return _cached_size_.Get(); } + + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const final; + void InternalSwap(FileOptions* other); + + private: + friend class ::PROTOBUF_NAMESPACE_ID::internal::AnyMetadata; + static ::PROTOBUF_NAMESPACE_ID::StringPiece FullMessageName() { + return "google.protobuf.FileOptions"; + } + protected: + explicit FileOptions(::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 ---------------------------------------------------- + + typedef FileOptions_OptimizeMode OptimizeMode; + static constexpr OptimizeMode SPEED = + FileOptions_OptimizeMode_SPEED; + static constexpr OptimizeMode CODE_SIZE = + FileOptions_OptimizeMode_CODE_SIZE; + static constexpr OptimizeMode LITE_RUNTIME = + FileOptions_OptimizeMode_LITE_RUNTIME; + static inline bool OptimizeMode_IsValid(int value) { + return FileOptions_OptimizeMode_IsValid(value); + } + static constexpr OptimizeMode OptimizeMode_MIN = + FileOptions_OptimizeMode_OptimizeMode_MIN; + static constexpr OptimizeMode OptimizeMode_MAX = + FileOptions_OptimizeMode_OptimizeMode_MAX; + static constexpr int OptimizeMode_ARRAYSIZE = + FileOptions_OptimizeMode_OptimizeMode_ARRAYSIZE; + static inline const ::PROTOBUF_NAMESPACE_ID::EnumDescriptor* + OptimizeMode_descriptor() { + return FileOptions_OptimizeMode_descriptor(); + } + template<typename T> + static inline const TProtoStringType& OptimizeMode_Name(T enum_t_value) { + static_assert(::std::is_same<T, OptimizeMode>::value || + ::std::is_integral<T>::value, + "Incorrect type passed to function OptimizeMode_Name."); + return FileOptions_OptimizeMode_Name(enum_t_value); + } + static inline bool OptimizeMode_Parse(::PROTOBUF_NAMESPACE_ID::ConstStringParam name, + OptimizeMode* value) { + return FileOptions_OptimizeMode_Parse(name, value); + } + + // accessors ------------------------------------------------------- + + enum : int { + kUninterpretedOptionFieldNumber = 999, + kJavaPackageFieldNumber = 1, + kJavaOuterClassnameFieldNumber = 8, + kGoPackageFieldNumber = 11, + kObjcClassPrefixFieldNumber = 36, + kCsharpNamespaceFieldNumber = 37, + kSwiftPrefixFieldNumber = 39, + kPhpClassPrefixFieldNumber = 40, + kPhpNamespaceFieldNumber = 41, + kPhpMetadataNamespaceFieldNumber = 44, + kRubyPackageFieldNumber = 45, + kJavaMultipleFilesFieldNumber = 10, + kJavaGenerateEqualsAndHashFieldNumber = 20, + kJavaStringCheckUtf8FieldNumber = 27, + kCcGenericServicesFieldNumber = 16, + kJavaGenericServicesFieldNumber = 17, + kPyGenericServicesFieldNumber = 18, + kPhpGenericServicesFieldNumber = 42, + kDeprecatedFieldNumber = 23, + kOptimizeForFieldNumber = 9, + kCcEnableArenasFieldNumber = 31, + }; + // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999; + int uninterpreted_option_size() const; + private: + int _internal_uninterpreted_option_size() const; + public: + void clear_uninterpreted_option(); + ::PROTOBUF_NAMESPACE_ID::UninterpretedOption* mutable_uninterpreted_option(int index); + ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::UninterpretedOption >* + mutable_uninterpreted_option(); + private: + const ::PROTOBUF_NAMESPACE_ID::UninterpretedOption& _internal_uninterpreted_option(int index) const; + ::PROTOBUF_NAMESPACE_ID::UninterpretedOption* _internal_add_uninterpreted_option(); + public: + const ::PROTOBUF_NAMESPACE_ID::UninterpretedOption& uninterpreted_option(int index) const; + ::PROTOBUF_NAMESPACE_ID::UninterpretedOption* add_uninterpreted_option(); + const ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::UninterpretedOption >& + uninterpreted_option() const; + + // optional string java_package = 1; + bool has_java_package() const; + private: + bool _internal_has_java_package() const; + public: + void clear_java_package(); + const TProtoStringType& java_package() const; + template <typename ArgT0 = const TProtoStringType&, typename... ArgT> + void set_java_package(ArgT0&& arg0, ArgT... args); + TProtoStringType* mutable_java_package(); + PROTOBUF_NODISCARD TProtoStringType* release_java_package(); + void set_allocated_java_package(TProtoStringType* java_package); + private: + const TProtoStringType& _internal_java_package() const; + inline PROTOBUF_ALWAYS_INLINE void _internal_set_java_package(const TProtoStringType& value); + TProtoStringType* _internal_mutable_java_package(); + public: + + // optional string java_outer_classname = 8; + bool has_java_outer_classname() const; + private: + bool _internal_has_java_outer_classname() const; + public: + void clear_java_outer_classname(); + const TProtoStringType& java_outer_classname() const; + template <typename ArgT0 = const TProtoStringType&, typename... ArgT> + void set_java_outer_classname(ArgT0&& arg0, ArgT... args); + TProtoStringType* mutable_java_outer_classname(); + PROTOBUF_NODISCARD TProtoStringType* release_java_outer_classname(); + void set_allocated_java_outer_classname(TProtoStringType* java_outer_classname); + private: + const TProtoStringType& _internal_java_outer_classname() const; + inline PROTOBUF_ALWAYS_INLINE void _internal_set_java_outer_classname(const TProtoStringType& value); + TProtoStringType* _internal_mutable_java_outer_classname(); + public: + + // optional string go_package = 11; + bool has_go_package() const; + private: + bool _internal_has_go_package() const; + public: + void clear_go_package(); + const TProtoStringType& go_package() const; + template <typename ArgT0 = const TProtoStringType&, typename... ArgT> + void set_go_package(ArgT0&& arg0, ArgT... args); + TProtoStringType* mutable_go_package(); + PROTOBUF_NODISCARD TProtoStringType* release_go_package(); + void set_allocated_go_package(TProtoStringType* go_package); + private: + const TProtoStringType& _internal_go_package() const; + inline PROTOBUF_ALWAYS_INLINE void _internal_set_go_package(const TProtoStringType& value); + TProtoStringType* _internal_mutable_go_package(); + public: + + // optional string objc_class_prefix = 36; + bool has_objc_class_prefix() const; + private: + bool _internal_has_objc_class_prefix() const; + public: + void clear_objc_class_prefix(); + const TProtoStringType& objc_class_prefix() const; + template <typename ArgT0 = const TProtoStringType&, typename... ArgT> + void set_objc_class_prefix(ArgT0&& arg0, ArgT... args); + TProtoStringType* mutable_objc_class_prefix(); + PROTOBUF_NODISCARD TProtoStringType* release_objc_class_prefix(); + void set_allocated_objc_class_prefix(TProtoStringType* objc_class_prefix); + private: + const TProtoStringType& _internal_objc_class_prefix() const; + inline PROTOBUF_ALWAYS_INLINE void _internal_set_objc_class_prefix(const TProtoStringType& value); + TProtoStringType* _internal_mutable_objc_class_prefix(); + public: + + // optional string csharp_namespace = 37; + bool has_csharp_namespace() const; + private: + bool _internal_has_csharp_namespace() const; + public: + void clear_csharp_namespace(); + const TProtoStringType& csharp_namespace() const; + template <typename ArgT0 = const TProtoStringType&, typename... ArgT> + void set_csharp_namespace(ArgT0&& arg0, ArgT... args); + TProtoStringType* mutable_csharp_namespace(); + PROTOBUF_NODISCARD TProtoStringType* release_csharp_namespace(); + void set_allocated_csharp_namespace(TProtoStringType* csharp_namespace); + private: + const TProtoStringType& _internal_csharp_namespace() const; + inline PROTOBUF_ALWAYS_INLINE void _internal_set_csharp_namespace(const TProtoStringType& value); + TProtoStringType* _internal_mutable_csharp_namespace(); + public: + + // optional string swift_prefix = 39; + bool has_swift_prefix() const; + private: + bool _internal_has_swift_prefix() const; + public: + void clear_swift_prefix(); + const TProtoStringType& swift_prefix() const; + template <typename ArgT0 = const TProtoStringType&, typename... ArgT> + void set_swift_prefix(ArgT0&& arg0, ArgT... args); + TProtoStringType* mutable_swift_prefix(); + PROTOBUF_NODISCARD TProtoStringType* release_swift_prefix(); + void set_allocated_swift_prefix(TProtoStringType* swift_prefix); + private: + const TProtoStringType& _internal_swift_prefix() const; + inline PROTOBUF_ALWAYS_INLINE void _internal_set_swift_prefix(const TProtoStringType& value); + TProtoStringType* _internal_mutable_swift_prefix(); + public: + + // optional string php_class_prefix = 40; + bool has_php_class_prefix() const; + private: + bool _internal_has_php_class_prefix() const; + public: + void clear_php_class_prefix(); + const TProtoStringType& php_class_prefix() const; + template <typename ArgT0 = const TProtoStringType&, typename... ArgT> + void set_php_class_prefix(ArgT0&& arg0, ArgT... args); + TProtoStringType* mutable_php_class_prefix(); + PROTOBUF_NODISCARD TProtoStringType* release_php_class_prefix(); + void set_allocated_php_class_prefix(TProtoStringType* php_class_prefix); + private: + const TProtoStringType& _internal_php_class_prefix() const; + inline PROTOBUF_ALWAYS_INLINE void _internal_set_php_class_prefix(const TProtoStringType& value); + TProtoStringType* _internal_mutable_php_class_prefix(); + public: + + // optional string php_namespace = 41; + bool has_php_namespace() const; + private: + bool _internal_has_php_namespace() const; + public: + void clear_php_namespace(); + const TProtoStringType& php_namespace() const; + template <typename ArgT0 = const TProtoStringType&, typename... ArgT> + void set_php_namespace(ArgT0&& arg0, ArgT... args); + TProtoStringType* mutable_php_namespace(); + PROTOBUF_NODISCARD TProtoStringType* release_php_namespace(); + void set_allocated_php_namespace(TProtoStringType* php_namespace); + private: + const TProtoStringType& _internal_php_namespace() const; + inline PROTOBUF_ALWAYS_INLINE void _internal_set_php_namespace(const TProtoStringType& value); + TProtoStringType* _internal_mutable_php_namespace(); + public: + + // optional string php_metadata_namespace = 44; + bool has_php_metadata_namespace() const; + private: + bool _internal_has_php_metadata_namespace() const; + public: + void clear_php_metadata_namespace(); + const TProtoStringType& php_metadata_namespace() const; + template <typename ArgT0 = const TProtoStringType&, typename... ArgT> + void set_php_metadata_namespace(ArgT0&& arg0, ArgT... args); + TProtoStringType* mutable_php_metadata_namespace(); + PROTOBUF_NODISCARD TProtoStringType* release_php_metadata_namespace(); + void set_allocated_php_metadata_namespace(TProtoStringType* php_metadata_namespace); + private: + const TProtoStringType& _internal_php_metadata_namespace() const; + inline PROTOBUF_ALWAYS_INLINE void _internal_set_php_metadata_namespace(const TProtoStringType& value); + TProtoStringType* _internal_mutable_php_metadata_namespace(); + public: + + // optional string ruby_package = 45; + bool has_ruby_package() const; + private: + bool _internal_has_ruby_package() const; + public: + void clear_ruby_package(); + const TProtoStringType& ruby_package() const; + template <typename ArgT0 = const TProtoStringType&, typename... ArgT> + void set_ruby_package(ArgT0&& arg0, ArgT... args); + TProtoStringType* mutable_ruby_package(); + PROTOBUF_NODISCARD TProtoStringType* release_ruby_package(); + void set_allocated_ruby_package(TProtoStringType* ruby_package); + private: + const TProtoStringType& _internal_ruby_package() const; + inline PROTOBUF_ALWAYS_INLINE void _internal_set_ruby_package(const TProtoStringType& value); + TProtoStringType* _internal_mutable_ruby_package(); + public: + + // optional bool java_multiple_files = 10 [default = false]; + bool has_java_multiple_files() const; + private: + bool _internal_has_java_multiple_files() const; + public: + void clear_java_multiple_files(); + bool java_multiple_files() const; + void set_java_multiple_files(bool value); + private: + bool _internal_java_multiple_files() const; + void _internal_set_java_multiple_files(bool value); + public: + + // optional bool java_generate_equals_and_hash = 20 [deprecated = true]; + PROTOBUF_DEPRECATED bool has_java_generate_equals_and_hash() const; + private: + bool _internal_has_java_generate_equals_and_hash() const; + public: + PROTOBUF_DEPRECATED void clear_java_generate_equals_and_hash(); + PROTOBUF_DEPRECATED bool java_generate_equals_and_hash() const; + PROTOBUF_DEPRECATED void set_java_generate_equals_and_hash(bool value); + private: + bool _internal_java_generate_equals_and_hash() const; + void _internal_set_java_generate_equals_and_hash(bool value); + public: + + // optional bool java_string_check_utf8 = 27 [default = false]; + bool has_java_string_check_utf8() const; + private: + bool _internal_has_java_string_check_utf8() const; + public: + void clear_java_string_check_utf8(); + bool java_string_check_utf8() const; + void set_java_string_check_utf8(bool value); + private: + bool _internal_java_string_check_utf8() const; + void _internal_set_java_string_check_utf8(bool value); + public: + + // optional bool cc_generic_services = 16 [default = false]; + bool has_cc_generic_services() const; + private: + bool _internal_has_cc_generic_services() const; + public: + void clear_cc_generic_services(); + bool cc_generic_services() const; + void set_cc_generic_services(bool value); + private: + bool _internal_cc_generic_services() const; + void _internal_set_cc_generic_services(bool value); + public: + + // optional bool java_generic_services = 17 [default = false]; + bool has_java_generic_services() const; + private: + bool _internal_has_java_generic_services() const; + public: + void clear_java_generic_services(); + bool java_generic_services() const; + void set_java_generic_services(bool value); + private: + bool _internal_java_generic_services() const; + void _internal_set_java_generic_services(bool value); + public: + + // optional bool py_generic_services = 18 [default = false]; + bool has_py_generic_services() const; + private: + bool _internal_has_py_generic_services() const; + public: + void clear_py_generic_services(); + bool py_generic_services() const; + void set_py_generic_services(bool value); + private: + bool _internal_py_generic_services() const; + void _internal_set_py_generic_services(bool value); + public: + + // optional bool php_generic_services = 42 [default = false]; + bool has_php_generic_services() const; + private: + bool _internal_has_php_generic_services() const; + public: + void clear_php_generic_services(); + bool php_generic_services() const; + void set_php_generic_services(bool value); + private: + bool _internal_php_generic_services() const; + void _internal_set_php_generic_services(bool value); + public: + + // optional bool deprecated = 23 [default = false]; + bool has_deprecated() const; + private: + bool _internal_has_deprecated() const; + public: + void clear_deprecated(); + bool deprecated() const; + void set_deprecated(bool value); + private: + bool _internal_deprecated() const; + void _internal_set_deprecated(bool value); + public: + + // optional .google.protobuf.FileOptions.OptimizeMode optimize_for = 9 [default = SPEED]; + bool has_optimize_for() const; + private: + bool _internal_has_optimize_for() const; + public: + void clear_optimize_for(); + ::PROTOBUF_NAMESPACE_ID::FileOptions_OptimizeMode optimize_for() const; + void set_optimize_for(::PROTOBUF_NAMESPACE_ID::FileOptions_OptimizeMode value); + private: + ::PROTOBUF_NAMESPACE_ID::FileOptions_OptimizeMode _internal_optimize_for() const; + void _internal_set_optimize_for(::PROTOBUF_NAMESPACE_ID::FileOptions_OptimizeMode value); + public: + + // optional bool cc_enable_arenas = 31 [default = true]; + bool has_cc_enable_arenas() const; + private: + bool _internal_has_cc_enable_arenas() const; + public: + void clear_cc_enable_arenas(); + bool cc_enable_arenas() const; + void set_cc_enable_arenas(bool value); + private: + bool _internal_cc_enable_arenas() const; + void _internal_set_cc_enable_arenas(bool value); + public: + + + template <typename _proto_TypeTraits, + ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type, + bool _is_packed> + inline bool HasExtension( + const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier< + FileOptions, _proto_TypeTraits, _field_type, _is_packed>& id) const { + + return _extensions_.Has(id.number()); + } + + template <typename _proto_TypeTraits, + ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type, + bool _is_packed> + inline void ClearExtension( + const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier< + FileOptions, _proto_TypeTraits, _field_type, _is_packed>& id) { + _extensions_.ClearExtension(id.number()); + + } + + template <typename _proto_TypeTraits, + ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type, + bool _is_packed> + inline int ExtensionSize( + const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier< + FileOptions, _proto_TypeTraits, _field_type, _is_packed>& id) const { + + return _extensions_.ExtensionSize(id.number()); + } + + template <typename _proto_TypeTraits, + ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type, + bool _is_packed> + inline typename _proto_TypeTraits::Singular::ConstType GetExtension( + const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier< + FileOptions, _proto_TypeTraits, _field_type, _is_packed>& id) const { + + return _proto_TypeTraits::Get(id.number(), _extensions_, + id.default_value()); + } + + template <typename _proto_TypeTraits, + ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type, + bool _is_packed> + inline typename _proto_TypeTraits::Singular::MutableType MutableExtension( + const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier< + FileOptions, _proto_TypeTraits, _field_type, _is_packed>& id) { + + return _proto_TypeTraits::Mutable(id.number(), _field_type, + &_extensions_); + } + + template <typename _proto_TypeTraits, + ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type, + bool _is_packed> + inline void SetExtension( + const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier< + FileOptions, _proto_TypeTraits, _field_type, _is_packed>& id, + typename _proto_TypeTraits::Singular::ConstType value) { + _proto_TypeTraits::Set(id.number(), _field_type, value, &_extensions_); + + } + + template <typename _proto_TypeTraits, + ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type, + bool _is_packed> + inline void SetAllocatedExtension( + const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier< + FileOptions, _proto_TypeTraits, _field_type, _is_packed>& id, + typename _proto_TypeTraits::Singular::MutableType value) { + _proto_TypeTraits::SetAllocated(id.number(), _field_type, value, + &_extensions_); + + } + template <typename _proto_TypeTraits, + ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type, + bool _is_packed> + inline void UnsafeArenaSetAllocatedExtension( + const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier< + FileOptions, _proto_TypeTraits, _field_type, _is_packed>& id, + typename _proto_TypeTraits::Singular::MutableType value) { + _proto_TypeTraits::UnsafeArenaSetAllocated(id.number(), _field_type, + value, &_extensions_); + + } + template <typename _proto_TypeTraits, + ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type, + bool _is_packed> + PROTOBUF_NODISCARD inline + typename _proto_TypeTraits::Singular::MutableType + ReleaseExtension( + const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier< + FileOptions, _proto_TypeTraits, _field_type, _is_packed>& id) { + + return _proto_TypeTraits::Release(id.number(), _field_type, + &_extensions_); + } + template <typename _proto_TypeTraits, + ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type, + bool _is_packed> + inline typename _proto_TypeTraits::Singular::MutableType + UnsafeArenaReleaseExtension( + const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier< + FileOptions, _proto_TypeTraits, _field_type, _is_packed>& id) { + + return _proto_TypeTraits::UnsafeArenaRelease(id.number(), _field_type, + &_extensions_); + } + + template <typename _proto_TypeTraits, + ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type, + bool _is_packed> + inline typename _proto_TypeTraits::Repeated::ConstType GetExtension( + const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier< + FileOptions, _proto_TypeTraits, _field_type, _is_packed>& id, + int index) const { + + return _proto_TypeTraits::Get(id.number(), _extensions_, index); + } + + template <typename _proto_TypeTraits, + ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type, + bool _is_packed> + inline typename _proto_TypeTraits::Repeated::MutableType MutableExtension( + const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier< + FileOptions, _proto_TypeTraits, _field_type, _is_packed>& id, + int index) { + + return _proto_TypeTraits::Mutable(id.number(), index, &_extensions_); + } + + template <typename _proto_TypeTraits, + ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type, + bool _is_packed> + inline void SetExtension( + const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier< + FileOptions, _proto_TypeTraits, _field_type, _is_packed>& id, + int index, typename _proto_TypeTraits::Repeated::ConstType value) { + _proto_TypeTraits::Set(id.number(), index, value, &_extensions_); + + } + + template <typename _proto_TypeTraits, + ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type, + bool _is_packed> + inline typename _proto_TypeTraits::Repeated::MutableType AddExtension( + const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier< + FileOptions, _proto_TypeTraits, _field_type, _is_packed>& id) { + typename _proto_TypeTraits::Repeated::MutableType to_add = + _proto_TypeTraits::Add(id.number(), _field_type, &_extensions_); + + return to_add; + } + + template <typename _proto_TypeTraits, + ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type, + bool _is_packed> + inline void AddExtension( + const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier< + FileOptions, _proto_TypeTraits, _field_type, _is_packed>& id, + typename _proto_TypeTraits::Repeated::ConstType value) { + _proto_TypeTraits::Add(id.number(), _field_type, _is_packed, value, + &_extensions_); + + } + + template <typename _proto_TypeTraits, + ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type, + bool _is_packed> + inline const typename _proto_TypeTraits::Repeated::RepeatedFieldType& + GetRepeatedExtension( + const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier< + FileOptions, _proto_TypeTraits, _field_type, _is_packed>& id) const { + + return _proto_TypeTraits::GetRepeated(id.number(), _extensions_); + } + + template <typename _proto_TypeTraits, + ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type, + bool _is_packed> + inline typename _proto_TypeTraits::Repeated::RepeatedFieldType* + MutableRepeatedExtension( + const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier< + FileOptions, _proto_TypeTraits, _field_type, _is_packed>& id) { + + return _proto_TypeTraits::MutableRepeated(id.number(), _field_type, + _is_packed, &_extensions_); + } + + // @@protoc_insertion_point(class_scope:google.protobuf.FileOptions) + private: + class _Internal; + + ::PROTOBUF_NAMESPACE_ID::internal::ExtensionSet _extensions_; + + template <typename T> friend class ::PROTOBUF_NAMESPACE_ID::Arena::InternalHelper; + typedef void InternalArenaConstructable_; + typedef void DestructorSkippable_; + ::PROTOBUF_NAMESPACE_ID::internal::HasBits<1> _has_bits_; + mutable ::PROTOBUF_NAMESPACE_ID::internal::CachedSize _cached_size_; + ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::UninterpretedOption > uninterpreted_option_; + ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr java_package_; + ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr java_outer_classname_; + ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr go_package_; + ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr objc_class_prefix_; + ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr csharp_namespace_; + ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr swift_prefix_; + ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr php_class_prefix_; + ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr php_namespace_; + ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr php_metadata_namespace_; + ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr ruby_package_; + bool java_multiple_files_; + bool java_generate_equals_and_hash_; + bool java_string_check_utf8_; + bool cc_generic_services_; + bool java_generic_services_; + bool py_generic_services_; + bool php_generic_services_; + bool deprecated_; + int optimize_for_; + bool cc_enable_arenas_; + friend struct ::TableStruct_google_2fprotobuf_2fdescriptor_2eproto; +}; +// ------------------------------------------------------------------- + +class PROTOBUF_EXPORT MessageOptions final : + public ::PROTOBUF_NAMESPACE_ID::Message /* @@protoc_insertion_point(class_definition:google.protobuf.MessageOptions) */ { + public: + inline MessageOptions() : MessageOptions(nullptr) {} + ~MessageOptions() override; + explicit constexpr MessageOptions(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized); + + MessageOptions(const MessageOptions& from); + MessageOptions(MessageOptions&& from) noexcept + : MessageOptions() { + *this = ::std::move(from); + } + + inline MessageOptions& operator=(const MessageOptions& from) { + CopyFrom(from); + return *this; + } + inline MessageOptions& operator=(MessageOptions&& from) noexcept { + if (this == &from) return *this; + if (GetOwningArena() == from.GetOwningArena() + #ifdef PROTOBUF_FORCE_COPY_IN_MOVE + && GetOwningArena() != nullptr + #endif // !PROTOBUF_FORCE_COPY_IN_MOVE + ) { + InternalSwap(&from); + } else { + CopyFrom(from); + } + return *this; + } + + inline const ::PROTOBUF_NAMESPACE_ID::UnknownFieldSet& unknown_fields() const { + return _internal_metadata_.unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(::PROTOBUF_NAMESPACE_ID::UnknownFieldSet::default_instance); + } + inline ::PROTOBUF_NAMESPACE_ID::UnknownFieldSet* mutable_unknown_fields() { + return _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(); + } + + static const ::PROTOBUF_NAMESPACE_ID::Descriptor* descriptor() { + return GetDescriptor(); + } + static const ::PROTOBUF_NAMESPACE_ID::Descriptor* GetDescriptor() { + return default_instance().GetMetadata().descriptor; + } + static const ::PROTOBUF_NAMESPACE_ID::Reflection* GetReflection() { + return default_instance().GetMetadata().reflection; + } + static const MessageOptions& default_instance() { + return *internal_default_instance(); + } + static inline const MessageOptions* internal_default_instance() { + return reinterpret_cast<const MessageOptions*>( + &_MessageOptions_default_instance_); + } + static constexpr int kIndexInFileMessages = + 14; + + friend void swap(MessageOptions& a, MessageOptions& b) { + a.Swap(&b); + } + inline void Swap(MessageOptions* other) { + if (other == this) return; + #ifdef PROTOBUF_FORCE_COPY_IN_SWAP + if (GetOwningArena() != nullptr && + GetOwningArena() == other->GetOwningArena()) { + #else // PROTOBUF_FORCE_COPY_IN_SWAP + if (GetOwningArena() == other->GetOwningArena()) { + #endif // !PROTOBUF_FORCE_COPY_IN_SWAP + InternalSwap(other); + } else { + ::PROTOBUF_NAMESPACE_ID::internal::GenericSwap(this, other); + } + } + void UnsafeArenaSwap(MessageOptions* other) { + if (other == this) return; + GOOGLE_DCHECK(GetOwningArena() == other->GetOwningArena()); + InternalSwap(other); + } + + // implements Message ---------------------------------------------- + + MessageOptions* New(::PROTOBUF_NAMESPACE_ID::Arena* arena = nullptr) const final { + return CreateMaybeMessage<MessageOptions>(arena); + } + using ::PROTOBUF_NAMESPACE_ID::Message::CopyFrom; + void CopyFrom(const MessageOptions& from); + using ::PROTOBUF_NAMESPACE_ID::Message::MergeFrom; + void MergeFrom(const MessageOptions& 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; + + size_t ByteSizeLong() const final; + const char* _InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) final; + uint8_t* _InternalSerialize( + uint8_t* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const final; + int GetCachedSize() const final { return _cached_size_.Get(); } + + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const final; + void InternalSwap(MessageOptions* other); + + private: + friend class ::PROTOBUF_NAMESPACE_ID::internal::AnyMetadata; + static ::PROTOBUF_NAMESPACE_ID::StringPiece FullMessageName() { + return "google.protobuf.MessageOptions"; + } + protected: + explicit MessageOptions(::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 ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + enum : int { + kUninterpretedOptionFieldNumber = 999, + kMessageSetWireFormatFieldNumber = 1, + kNoStandardDescriptorAccessorFieldNumber = 2, + kDeprecatedFieldNumber = 3, + kMapEntryFieldNumber = 7, + }; + // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999; + int uninterpreted_option_size() const; + private: + int _internal_uninterpreted_option_size() const; + public: + void clear_uninterpreted_option(); + ::PROTOBUF_NAMESPACE_ID::UninterpretedOption* mutable_uninterpreted_option(int index); + ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::UninterpretedOption >* + mutable_uninterpreted_option(); + private: + const ::PROTOBUF_NAMESPACE_ID::UninterpretedOption& _internal_uninterpreted_option(int index) const; + ::PROTOBUF_NAMESPACE_ID::UninterpretedOption* _internal_add_uninterpreted_option(); + public: + const ::PROTOBUF_NAMESPACE_ID::UninterpretedOption& uninterpreted_option(int index) const; + ::PROTOBUF_NAMESPACE_ID::UninterpretedOption* add_uninterpreted_option(); + const ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::UninterpretedOption >& + uninterpreted_option() const; + + // optional bool message_set_wire_format = 1 [default = false]; + bool has_message_set_wire_format() const; + private: + bool _internal_has_message_set_wire_format() const; + public: + void clear_message_set_wire_format(); + bool message_set_wire_format() const; + void set_message_set_wire_format(bool value); + private: + bool _internal_message_set_wire_format() const; + void _internal_set_message_set_wire_format(bool value); + public: + + // optional bool no_standard_descriptor_accessor = 2 [default = false]; + bool has_no_standard_descriptor_accessor() const; + private: + bool _internal_has_no_standard_descriptor_accessor() const; + public: + void clear_no_standard_descriptor_accessor(); + bool no_standard_descriptor_accessor() const; + void set_no_standard_descriptor_accessor(bool value); + private: + bool _internal_no_standard_descriptor_accessor() const; + void _internal_set_no_standard_descriptor_accessor(bool value); + public: + + // optional bool deprecated = 3 [default = false]; + bool has_deprecated() const; + private: + bool _internal_has_deprecated() const; + public: + void clear_deprecated(); + bool deprecated() const; + void set_deprecated(bool value); + private: + bool _internal_deprecated() const; + void _internal_set_deprecated(bool value); + public: + + // optional bool map_entry = 7; + bool has_map_entry() const; + private: + bool _internal_has_map_entry() const; + public: + void clear_map_entry(); + bool map_entry() const; + void set_map_entry(bool value); + private: + bool _internal_map_entry() const; + void _internal_set_map_entry(bool value); + public: + + + template <typename _proto_TypeTraits, + ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type, + bool _is_packed> + inline bool HasExtension( + const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier< + MessageOptions, _proto_TypeTraits, _field_type, _is_packed>& id) const { + + return _extensions_.Has(id.number()); + } + + template <typename _proto_TypeTraits, + ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type, + bool _is_packed> + inline void ClearExtension( + const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier< + MessageOptions, _proto_TypeTraits, _field_type, _is_packed>& id) { + _extensions_.ClearExtension(id.number()); + + } + + template <typename _proto_TypeTraits, + ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type, + bool _is_packed> + inline int ExtensionSize( + const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier< + MessageOptions, _proto_TypeTraits, _field_type, _is_packed>& id) const { + + return _extensions_.ExtensionSize(id.number()); + } + + template <typename _proto_TypeTraits, + ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type, + bool _is_packed> + inline typename _proto_TypeTraits::Singular::ConstType GetExtension( + const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier< + MessageOptions, _proto_TypeTraits, _field_type, _is_packed>& id) const { + + return _proto_TypeTraits::Get(id.number(), _extensions_, + id.default_value()); + } + + template <typename _proto_TypeTraits, + ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type, + bool _is_packed> + inline typename _proto_TypeTraits::Singular::MutableType MutableExtension( + const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier< + MessageOptions, _proto_TypeTraits, _field_type, _is_packed>& id) { + + return _proto_TypeTraits::Mutable(id.number(), _field_type, + &_extensions_); + } + + template <typename _proto_TypeTraits, + ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type, + bool _is_packed> + inline void SetExtension( + const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier< + MessageOptions, _proto_TypeTraits, _field_type, _is_packed>& id, + typename _proto_TypeTraits::Singular::ConstType value) { + _proto_TypeTraits::Set(id.number(), _field_type, value, &_extensions_); + + } + + template <typename _proto_TypeTraits, + ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type, + bool _is_packed> + inline void SetAllocatedExtension( + const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier< + MessageOptions, _proto_TypeTraits, _field_type, _is_packed>& id, + typename _proto_TypeTraits::Singular::MutableType value) { + _proto_TypeTraits::SetAllocated(id.number(), _field_type, value, + &_extensions_); + + } + template <typename _proto_TypeTraits, + ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type, + bool _is_packed> + inline void UnsafeArenaSetAllocatedExtension( + const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier< + MessageOptions, _proto_TypeTraits, _field_type, _is_packed>& id, + typename _proto_TypeTraits::Singular::MutableType value) { + _proto_TypeTraits::UnsafeArenaSetAllocated(id.number(), _field_type, + value, &_extensions_); + + } + template <typename _proto_TypeTraits, + ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type, + bool _is_packed> + PROTOBUF_NODISCARD inline + typename _proto_TypeTraits::Singular::MutableType + ReleaseExtension( + const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier< + MessageOptions, _proto_TypeTraits, _field_type, _is_packed>& id) { + + return _proto_TypeTraits::Release(id.number(), _field_type, + &_extensions_); + } + template <typename _proto_TypeTraits, + ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type, + bool _is_packed> + inline typename _proto_TypeTraits::Singular::MutableType + UnsafeArenaReleaseExtension( + const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier< + MessageOptions, _proto_TypeTraits, _field_type, _is_packed>& id) { + + return _proto_TypeTraits::UnsafeArenaRelease(id.number(), _field_type, + &_extensions_); + } + + template <typename _proto_TypeTraits, + ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type, + bool _is_packed> + inline typename _proto_TypeTraits::Repeated::ConstType GetExtension( + const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier< + MessageOptions, _proto_TypeTraits, _field_type, _is_packed>& id, + int index) const { + + return _proto_TypeTraits::Get(id.number(), _extensions_, index); + } + + template <typename _proto_TypeTraits, + ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type, + bool _is_packed> + inline typename _proto_TypeTraits::Repeated::MutableType MutableExtension( + const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier< + MessageOptions, _proto_TypeTraits, _field_type, _is_packed>& id, + int index) { + + return _proto_TypeTraits::Mutable(id.number(), index, &_extensions_); + } + + template <typename _proto_TypeTraits, + ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type, + bool _is_packed> + inline void SetExtension( + const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier< + MessageOptions, _proto_TypeTraits, _field_type, _is_packed>& id, + int index, typename _proto_TypeTraits::Repeated::ConstType value) { + _proto_TypeTraits::Set(id.number(), index, value, &_extensions_); + + } + + template <typename _proto_TypeTraits, + ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type, + bool _is_packed> + inline typename _proto_TypeTraits::Repeated::MutableType AddExtension( + const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier< + MessageOptions, _proto_TypeTraits, _field_type, _is_packed>& id) { + typename _proto_TypeTraits::Repeated::MutableType to_add = + _proto_TypeTraits::Add(id.number(), _field_type, &_extensions_); + + return to_add; + } + + template <typename _proto_TypeTraits, + ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type, + bool _is_packed> + inline void AddExtension( + const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier< + MessageOptions, _proto_TypeTraits, _field_type, _is_packed>& id, + typename _proto_TypeTraits::Repeated::ConstType value) { + _proto_TypeTraits::Add(id.number(), _field_type, _is_packed, value, + &_extensions_); + + } + + template <typename _proto_TypeTraits, + ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type, + bool _is_packed> + inline const typename _proto_TypeTraits::Repeated::RepeatedFieldType& + GetRepeatedExtension( + const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier< + MessageOptions, _proto_TypeTraits, _field_type, _is_packed>& id) const { + + return _proto_TypeTraits::GetRepeated(id.number(), _extensions_); + } + + template <typename _proto_TypeTraits, + ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type, + bool _is_packed> + inline typename _proto_TypeTraits::Repeated::RepeatedFieldType* + MutableRepeatedExtension( + const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier< + MessageOptions, _proto_TypeTraits, _field_type, _is_packed>& id) { + + return _proto_TypeTraits::MutableRepeated(id.number(), _field_type, + _is_packed, &_extensions_); + } + + // @@protoc_insertion_point(class_scope:google.protobuf.MessageOptions) + private: + class _Internal; + + ::PROTOBUF_NAMESPACE_ID::internal::ExtensionSet _extensions_; + + template <typename T> friend class ::PROTOBUF_NAMESPACE_ID::Arena::InternalHelper; + typedef void InternalArenaConstructable_; + typedef void DestructorSkippable_; + ::PROTOBUF_NAMESPACE_ID::internal::HasBits<1> _has_bits_; + mutable ::PROTOBUF_NAMESPACE_ID::internal::CachedSize _cached_size_; + ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::UninterpretedOption > uninterpreted_option_; + bool message_set_wire_format_; + bool no_standard_descriptor_accessor_; + bool deprecated_; + bool map_entry_; + friend struct ::TableStruct_google_2fprotobuf_2fdescriptor_2eproto; +}; +// ------------------------------------------------------------------- + +class PROTOBUF_EXPORT FieldOptions final : + public ::PROTOBUF_NAMESPACE_ID::Message /* @@protoc_insertion_point(class_definition:google.protobuf.FieldOptions) */ { + public: + inline FieldOptions() : FieldOptions(nullptr) {} + ~FieldOptions() override; + explicit constexpr FieldOptions(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized); + + FieldOptions(const FieldOptions& from); + FieldOptions(FieldOptions&& from) noexcept + : FieldOptions() { + *this = ::std::move(from); + } + + inline FieldOptions& operator=(const FieldOptions& from) { + CopyFrom(from); + return *this; + } + inline FieldOptions& operator=(FieldOptions&& from) noexcept { + if (this == &from) return *this; + if (GetOwningArena() == from.GetOwningArena() + #ifdef PROTOBUF_FORCE_COPY_IN_MOVE + && GetOwningArena() != nullptr + #endif // !PROTOBUF_FORCE_COPY_IN_MOVE + ) { + InternalSwap(&from); + } else { + CopyFrom(from); + } + return *this; + } + + inline const ::PROTOBUF_NAMESPACE_ID::UnknownFieldSet& unknown_fields() const { + return _internal_metadata_.unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(::PROTOBUF_NAMESPACE_ID::UnknownFieldSet::default_instance); + } + inline ::PROTOBUF_NAMESPACE_ID::UnknownFieldSet* mutable_unknown_fields() { + return _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(); + } + + static const ::PROTOBUF_NAMESPACE_ID::Descriptor* descriptor() { + return GetDescriptor(); + } + static const ::PROTOBUF_NAMESPACE_ID::Descriptor* GetDescriptor() { + return default_instance().GetMetadata().descriptor; + } + static const ::PROTOBUF_NAMESPACE_ID::Reflection* GetReflection() { + return default_instance().GetMetadata().reflection; + } + static const FieldOptions& default_instance() { + return *internal_default_instance(); + } + static inline const FieldOptions* internal_default_instance() { + return reinterpret_cast<const FieldOptions*>( + &_FieldOptions_default_instance_); + } + static constexpr int kIndexInFileMessages = + 15; + + friend void swap(FieldOptions& a, FieldOptions& b) { + a.Swap(&b); + } + inline void Swap(FieldOptions* other) { + if (other == this) return; + #ifdef PROTOBUF_FORCE_COPY_IN_SWAP + if (GetOwningArena() != nullptr && + GetOwningArena() == other->GetOwningArena()) { + #else // PROTOBUF_FORCE_COPY_IN_SWAP + if (GetOwningArena() == other->GetOwningArena()) { + #endif // !PROTOBUF_FORCE_COPY_IN_SWAP + InternalSwap(other); + } else { + ::PROTOBUF_NAMESPACE_ID::internal::GenericSwap(this, other); + } + } + void UnsafeArenaSwap(FieldOptions* other) { + if (other == this) return; + GOOGLE_DCHECK(GetOwningArena() == other->GetOwningArena()); + InternalSwap(other); + } + + // implements Message ---------------------------------------------- + + FieldOptions* New(::PROTOBUF_NAMESPACE_ID::Arena* arena = nullptr) const final { + return CreateMaybeMessage<FieldOptions>(arena); + } + using ::PROTOBUF_NAMESPACE_ID::Message::CopyFrom; + void CopyFrom(const FieldOptions& from); + using ::PROTOBUF_NAMESPACE_ID::Message::MergeFrom; + void MergeFrom(const FieldOptions& 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; + + size_t ByteSizeLong() const final; + const char* _InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) final; + uint8_t* _InternalSerialize( + uint8_t* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const final; + int GetCachedSize() const final { return _cached_size_.Get(); } + + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const final; + void InternalSwap(FieldOptions* other); + + private: + friend class ::PROTOBUF_NAMESPACE_ID::internal::AnyMetadata; + static ::PROTOBUF_NAMESPACE_ID::StringPiece FullMessageName() { + return "google.protobuf.FieldOptions"; + } + protected: + explicit FieldOptions(::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 ---------------------------------------------------- + + typedef FieldOptions_CType CType; + static constexpr CType STRING = + FieldOptions_CType_STRING; + static constexpr CType CORD = + FieldOptions_CType_CORD; + static constexpr CType STRING_PIECE = + FieldOptions_CType_STRING_PIECE; + static inline bool CType_IsValid(int value) { + return FieldOptions_CType_IsValid(value); + } + static constexpr CType CType_MIN = + FieldOptions_CType_CType_MIN; + static constexpr CType CType_MAX = + FieldOptions_CType_CType_MAX; + static constexpr int CType_ARRAYSIZE = + FieldOptions_CType_CType_ARRAYSIZE; + static inline const ::PROTOBUF_NAMESPACE_ID::EnumDescriptor* + CType_descriptor() { + return FieldOptions_CType_descriptor(); + } + template<typename T> + static inline const TProtoStringType& CType_Name(T enum_t_value) { + static_assert(::std::is_same<T, CType>::value || + ::std::is_integral<T>::value, + "Incorrect type passed to function CType_Name."); + return FieldOptions_CType_Name(enum_t_value); + } + static inline bool CType_Parse(::PROTOBUF_NAMESPACE_ID::ConstStringParam name, + CType* value) { + return FieldOptions_CType_Parse(name, value); + } + + typedef FieldOptions_JSType JSType; + static constexpr JSType JS_NORMAL = + FieldOptions_JSType_JS_NORMAL; + static constexpr JSType JS_STRING = + FieldOptions_JSType_JS_STRING; + static constexpr JSType JS_NUMBER = + FieldOptions_JSType_JS_NUMBER; + static inline bool JSType_IsValid(int value) { + return FieldOptions_JSType_IsValid(value); + } + static constexpr JSType JSType_MIN = + FieldOptions_JSType_JSType_MIN; + static constexpr JSType JSType_MAX = + FieldOptions_JSType_JSType_MAX; + static constexpr int JSType_ARRAYSIZE = + FieldOptions_JSType_JSType_ARRAYSIZE; + static inline const ::PROTOBUF_NAMESPACE_ID::EnumDescriptor* + JSType_descriptor() { + return FieldOptions_JSType_descriptor(); + } + template<typename T> + static inline const TProtoStringType& JSType_Name(T enum_t_value) { + static_assert(::std::is_same<T, JSType>::value || + ::std::is_integral<T>::value, + "Incorrect type passed to function JSType_Name."); + return FieldOptions_JSType_Name(enum_t_value); + } + static inline bool JSType_Parse(::PROTOBUF_NAMESPACE_ID::ConstStringParam name, + JSType* value) { + return FieldOptions_JSType_Parse(name, value); + } + + // accessors ------------------------------------------------------- + + enum : int { + kUninterpretedOptionFieldNumber = 999, + kCtypeFieldNumber = 1, + kPackedFieldNumber = 2, + kLazyFieldNumber = 5, + kDeprecatedFieldNumber = 3, + kWeakFieldNumber = 10, + kJstypeFieldNumber = 6, + }; + // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999; + int uninterpreted_option_size() const; + private: + int _internal_uninterpreted_option_size() const; + public: + void clear_uninterpreted_option(); + ::PROTOBUF_NAMESPACE_ID::UninterpretedOption* mutable_uninterpreted_option(int index); + ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::UninterpretedOption >* + mutable_uninterpreted_option(); + private: + const ::PROTOBUF_NAMESPACE_ID::UninterpretedOption& _internal_uninterpreted_option(int index) const; + ::PROTOBUF_NAMESPACE_ID::UninterpretedOption* _internal_add_uninterpreted_option(); + public: + const ::PROTOBUF_NAMESPACE_ID::UninterpretedOption& uninterpreted_option(int index) const; + ::PROTOBUF_NAMESPACE_ID::UninterpretedOption* add_uninterpreted_option(); + const ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::UninterpretedOption >& + uninterpreted_option() const; + + // optional .google.protobuf.FieldOptions.CType ctype = 1 [default = STRING]; + bool has_ctype() const; + private: + bool _internal_has_ctype() const; + public: + void clear_ctype(); + ::PROTOBUF_NAMESPACE_ID::FieldOptions_CType ctype() const; + void set_ctype(::PROTOBUF_NAMESPACE_ID::FieldOptions_CType value); + private: + ::PROTOBUF_NAMESPACE_ID::FieldOptions_CType _internal_ctype() const; + void _internal_set_ctype(::PROTOBUF_NAMESPACE_ID::FieldOptions_CType value); + public: + + // optional bool packed = 2; + bool has_packed() const; + private: + bool _internal_has_packed() const; + public: + void clear_packed(); + bool packed() const; + void set_packed(bool value); + private: + bool _internal_packed() const; + void _internal_set_packed(bool value); + public: + + // optional bool lazy = 5 [default = false]; + bool has_lazy() const; + private: + bool _internal_has_lazy() const; + public: + void clear_lazy(); + bool lazy() const; + void set_lazy(bool value); + private: + bool _internal_lazy() const; + void _internal_set_lazy(bool value); + public: + + // optional bool deprecated = 3 [default = false]; + bool has_deprecated() const; + private: + bool _internal_has_deprecated() const; + public: + void clear_deprecated(); + bool deprecated() const; + void set_deprecated(bool value); + private: + bool _internal_deprecated() const; + void _internal_set_deprecated(bool value); + public: + + // optional bool weak = 10 [default = false]; + bool has_weak() const; + private: + bool _internal_has_weak() const; + public: + void clear_weak(); + bool weak() const; + void set_weak(bool value); + private: + bool _internal_weak() const; + void _internal_set_weak(bool value); + public: + + // optional .google.protobuf.FieldOptions.JSType jstype = 6 [default = JS_NORMAL]; + bool has_jstype() const; + private: + bool _internal_has_jstype() const; + public: + void clear_jstype(); + ::PROTOBUF_NAMESPACE_ID::FieldOptions_JSType jstype() const; + void set_jstype(::PROTOBUF_NAMESPACE_ID::FieldOptions_JSType value); + private: + ::PROTOBUF_NAMESPACE_ID::FieldOptions_JSType _internal_jstype() const; + void _internal_set_jstype(::PROTOBUF_NAMESPACE_ID::FieldOptions_JSType value); + public: + + + template <typename _proto_TypeTraits, + ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type, + bool _is_packed> + inline bool HasExtension( + const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier< + FieldOptions, _proto_TypeTraits, _field_type, _is_packed>& id) const { + + return _extensions_.Has(id.number()); + } + + template <typename _proto_TypeTraits, + ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type, + bool _is_packed> + inline void ClearExtension( + const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier< + FieldOptions, _proto_TypeTraits, _field_type, _is_packed>& id) { + _extensions_.ClearExtension(id.number()); + + } + + template <typename _proto_TypeTraits, + ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type, + bool _is_packed> + inline int ExtensionSize( + const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier< + FieldOptions, _proto_TypeTraits, _field_type, _is_packed>& id) const { + + return _extensions_.ExtensionSize(id.number()); + } + + template <typename _proto_TypeTraits, + ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type, + bool _is_packed> + inline typename _proto_TypeTraits::Singular::ConstType GetExtension( + const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier< + FieldOptions, _proto_TypeTraits, _field_type, _is_packed>& id) const { + + return _proto_TypeTraits::Get(id.number(), _extensions_, + id.default_value()); + } + + template <typename _proto_TypeTraits, + ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type, + bool _is_packed> + inline typename _proto_TypeTraits::Singular::MutableType MutableExtension( + const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier< + FieldOptions, _proto_TypeTraits, _field_type, _is_packed>& id) { + + return _proto_TypeTraits::Mutable(id.number(), _field_type, + &_extensions_); + } + + template <typename _proto_TypeTraits, + ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type, + bool _is_packed> + inline void SetExtension( + const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier< + FieldOptions, _proto_TypeTraits, _field_type, _is_packed>& id, + typename _proto_TypeTraits::Singular::ConstType value) { + _proto_TypeTraits::Set(id.number(), _field_type, value, &_extensions_); + + } + + template <typename _proto_TypeTraits, + ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type, + bool _is_packed> + inline void SetAllocatedExtension( + const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier< + FieldOptions, _proto_TypeTraits, _field_type, _is_packed>& id, + typename _proto_TypeTraits::Singular::MutableType value) { + _proto_TypeTraits::SetAllocated(id.number(), _field_type, value, + &_extensions_); + + } + template <typename _proto_TypeTraits, + ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type, + bool _is_packed> + inline void UnsafeArenaSetAllocatedExtension( + const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier< + FieldOptions, _proto_TypeTraits, _field_type, _is_packed>& id, + typename _proto_TypeTraits::Singular::MutableType value) { + _proto_TypeTraits::UnsafeArenaSetAllocated(id.number(), _field_type, + value, &_extensions_); + + } + template <typename _proto_TypeTraits, + ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type, + bool _is_packed> + PROTOBUF_NODISCARD inline + typename _proto_TypeTraits::Singular::MutableType + ReleaseExtension( + const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier< + FieldOptions, _proto_TypeTraits, _field_type, _is_packed>& id) { + + return _proto_TypeTraits::Release(id.number(), _field_type, + &_extensions_); + } + template <typename _proto_TypeTraits, + ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type, + bool _is_packed> + inline typename _proto_TypeTraits::Singular::MutableType + UnsafeArenaReleaseExtension( + const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier< + FieldOptions, _proto_TypeTraits, _field_type, _is_packed>& id) { + + return _proto_TypeTraits::UnsafeArenaRelease(id.number(), _field_type, + &_extensions_); + } + + template <typename _proto_TypeTraits, + ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type, + bool _is_packed> + inline typename _proto_TypeTraits::Repeated::ConstType GetExtension( + const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier< + FieldOptions, _proto_TypeTraits, _field_type, _is_packed>& id, + int index) const { + + return _proto_TypeTraits::Get(id.number(), _extensions_, index); + } + + template <typename _proto_TypeTraits, + ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type, + bool _is_packed> + inline typename _proto_TypeTraits::Repeated::MutableType MutableExtension( + const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier< + FieldOptions, _proto_TypeTraits, _field_type, _is_packed>& id, + int index) { + + return _proto_TypeTraits::Mutable(id.number(), index, &_extensions_); + } + + template <typename _proto_TypeTraits, + ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type, + bool _is_packed> + inline void SetExtension( + const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier< + FieldOptions, _proto_TypeTraits, _field_type, _is_packed>& id, + int index, typename _proto_TypeTraits::Repeated::ConstType value) { + _proto_TypeTraits::Set(id.number(), index, value, &_extensions_); + + } + + template <typename _proto_TypeTraits, + ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type, + bool _is_packed> + inline typename _proto_TypeTraits::Repeated::MutableType AddExtension( + const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier< + FieldOptions, _proto_TypeTraits, _field_type, _is_packed>& id) { + typename _proto_TypeTraits::Repeated::MutableType to_add = + _proto_TypeTraits::Add(id.number(), _field_type, &_extensions_); + + return to_add; + } + + template <typename _proto_TypeTraits, + ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type, + bool _is_packed> + inline void AddExtension( + const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier< + FieldOptions, _proto_TypeTraits, _field_type, _is_packed>& id, + typename _proto_TypeTraits::Repeated::ConstType value) { + _proto_TypeTraits::Add(id.number(), _field_type, _is_packed, value, + &_extensions_); + + } + + template <typename _proto_TypeTraits, + ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type, + bool _is_packed> + inline const typename _proto_TypeTraits::Repeated::RepeatedFieldType& + GetRepeatedExtension( + const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier< + FieldOptions, _proto_TypeTraits, _field_type, _is_packed>& id) const { + + return _proto_TypeTraits::GetRepeated(id.number(), _extensions_); + } + + template <typename _proto_TypeTraits, + ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type, + bool _is_packed> + inline typename _proto_TypeTraits::Repeated::RepeatedFieldType* + MutableRepeatedExtension( + const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier< + FieldOptions, _proto_TypeTraits, _field_type, _is_packed>& id) { + + return _proto_TypeTraits::MutableRepeated(id.number(), _field_type, + _is_packed, &_extensions_); + } + + // @@protoc_insertion_point(class_scope:google.protobuf.FieldOptions) + private: + class _Internal; + + ::PROTOBUF_NAMESPACE_ID::internal::ExtensionSet _extensions_; + + template <typename T> friend class ::PROTOBUF_NAMESPACE_ID::Arena::InternalHelper; + typedef void InternalArenaConstructable_; + typedef void DestructorSkippable_; + ::PROTOBUF_NAMESPACE_ID::internal::HasBits<1> _has_bits_; + mutable ::PROTOBUF_NAMESPACE_ID::internal::CachedSize _cached_size_; + ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::UninterpretedOption > uninterpreted_option_; + int ctype_; + bool packed_; + bool lazy_; + bool deprecated_; + bool weak_; + int jstype_; + friend struct ::TableStruct_google_2fprotobuf_2fdescriptor_2eproto; +}; +// ------------------------------------------------------------------- + +class PROTOBUF_EXPORT OneofOptions final : + public ::PROTOBUF_NAMESPACE_ID::Message /* @@protoc_insertion_point(class_definition:google.protobuf.OneofOptions) */ { + public: + inline OneofOptions() : OneofOptions(nullptr) {} + ~OneofOptions() override; + explicit constexpr OneofOptions(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized); + + OneofOptions(const OneofOptions& from); + OneofOptions(OneofOptions&& from) noexcept + : OneofOptions() { + *this = ::std::move(from); + } + + inline OneofOptions& operator=(const OneofOptions& from) { + CopyFrom(from); + return *this; + } + inline OneofOptions& operator=(OneofOptions&& from) noexcept { + if (this == &from) return *this; + if (GetOwningArena() == from.GetOwningArena() + #ifdef PROTOBUF_FORCE_COPY_IN_MOVE + && GetOwningArena() != nullptr + #endif // !PROTOBUF_FORCE_COPY_IN_MOVE + ) { + InternalSwap(&from); + } else { + CopyFrom(from); + } + return *this; + } + + inline const ::PROTOBUF_NAMESPACE_ID::UnknownFieldSet& unknown_fields() const { + return _internal_metadata_.unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(::PROTOBUF_NAMESPACE_ID::UnknownFieldSet::default_instance); + } + inline ::PROTOBUF_NAMESPACE_ID::UnknownFieldSet* mutable_unknown_fields() { + return _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(); + } + + static const ::PROTOBUF_NAMESPACE_ID::Descriptor* descriptor() { + return GetDescriptor(); + } + static const ::PROTOBUF_NAMESPACE_ID::Descriptor* GetDescriptor() { + return default_instance().GetMetadata().descriptor; + } + static const ::PROTOBUF_NAMESPACE_ID::Reflection* GetReflection() { + return default_instance().GetMetadata().reflection; + } + static const OneofOptions& default_instance() { + return *internal_default_instance(); + } + static inline const OneofOptions* internal_default_instance() { + return reinterpret_cast<const OneofOptions*>( + &_OneofOptions_default_instance_); + } + static constexpr int kIndexInFileMessages = + 16; + + friend void swap(OneofOptions& a, OneofOptions& b) { + a.Swap(&b); + } + inline void Swap(OneofOptions* other) { + if (other == this) return; + #ifdef PROTOBUF_FORCE_COPY_IN_SWAP + if (GetOwningArena() != nullptr && + GetOwningArena() == other->GetOwningArena()) { + #else // PROTOBUF_FORCE_COPY_IN_SWAP + if (GetOwningArena() == other->GetOwningArena()) { + #endif // !PROTOBUF_FORCE_COPY_IN_SWAP + InternalSwap(other); + } else { + ::PROTOBUF_NAMESPACE_ID::internal::GenericSwap(this, other); + } + } + void UnsafeArenaSwap(OneofOptions* other) { + if (other == this) return; + GOOGLE_DCHECK(GetOwningArena() == other->GetOwningArena()); + InternalSwap(other); + } + + // implements Message ---------------------------------------------- + + OneofOptions* New(::PROTOBUF_NAMESPACE_ID::Arena* arena = nullptr) const final { + return CreateMaybeMessage<OneofOptions>(arena); + } + using ::PROTOBUF_NAMESPACE_ID::Message::CopyFrom; + void CopyFrom(const OneofOptions& from); + using ::PROTOBUF_NAMESPACE_ID::Message::MergeFrom; + void MergeFrom(const OneofOptions& 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; + + size_t ByteSizeLong() const final; + const char* _InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) final; + uint8_t* _InternalSerialize( + uint8_t* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const final; + int GetCachedSize() const final { return _cached_size_.Get(); } + + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const final; + void InternalSwap(OneofOptions* other); + + private: + friend class ::PROTOBUF_NAMESPACE_ID::internal::AnyMetadata; + static ::PROTOBUF_NAMESPACE_ID::StringPiece FullMessageName() { + return "google.protobuf.OneofOptions"; + } + protected: + explicit OneofOptions(::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 ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + enum : int { + kUninterpretedOptionFieldNumber = 999, + }; + // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999; + int uninterpreted_option_size() const; + private: + int _internal_uninterpreted_option_size() const; + public: + void clear_uninterpreted_option(); + ::PROTOBUF_NAMESPACE_ID::UninterpretedOption* mutable_uninterpreted_option(int index); + ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::UninterpretedOption >* + mutable_uninterpreted_option(); + private: + const ::PROTOBUF_NAMESPACE_ID::UninterpretedOption& _internal_uninterpreted_option(int index) const; + ::PROTOBUF_NAMESPACE_ID::UninterpretedOption* _internal_add_uninterpreted_option(); + public: + const ::PROTOBUF_NAMESPACE_ID::UninterpretedOption& uninterpreted_option(int index) const; + ::PROTOBUF_NAMESPACE_ID::UninterpretedOption* add_uninterpreted_option(); + const ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::UninterpretedOption >& + uninterpreted_option() const; + + + template <typename _proto_TypeTraits, + ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type, + bool _is_packed> + inline bool HasExtension( + const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier< + OneofOptions, _proto_TypeTraits, _field_type, _is_packed>& id) const { + + return _extensions_.Has(id.number()); + } + + template <typename _proto_TypeTraits, + ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type, + bool _is_packed> + inline void ClearExtension( + const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier< + OneofOptions, _proto_TypeTraits, _field_type, _is_packed>& id) { + _extensions_.ClearExtension(id.number()); + + } + + template <typename _proto_TypeTraits, + ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type, + bool _is_packed> + inline int ExtensionSize( + const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier< + OneofOptions, _proto_TypeTraits, _field_type, _is_packed>& id) const { + + return _extensions_.ExtensionSize(id.number()); + } + + template <typename _proto_TypeTraits, + ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type, + bool _is_packed> + inline typename _proto_TypeTraits::Singular::ConstType GetExtension( + const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier< + OneofOptions, _proto_TypeTraits, _field_type, _is_packed>& id) const { + + return _proto_TypeTraits::Get(id.number(), _extensions_, + id.default_value()); + } + + template <typename _proto_TypeTraits, + ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type, + bool _is_packed> + inline typename _proto_TypeTraits::Singular::MutableType MutableExtension( + const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier< + OneofOptions, _proto_TypeTraits, _field_type, _is_packed>& id) { + + return _proto_TypeTraits::Mutable(id.number(), _field_type, + &_extensions_); + } + + template <typename _proto_TypeTraits, + ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type, + bool _is_packed> + inline void SetExtension( + const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier< + OneofOptions, _proto_TypeTraits, _field_type, _is_packed>& id, + typename _proto_TypeTraits::Singular::ConstType value) { + _proto_TypeTraits::Set(id.number(), _field_type, value, &_extensions_); + + } + + template <typename _proto_TypeTraits, + ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type, + bool _is_packed> + inline void SetAllocatedExtension( + const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier< + OneofOptions, _proto_TypeTraits, _field_type, _is_packed>& id, + typename _proto_TypeTraits::Singular::MutableType value) { + _proto_TypeTraits::SetAllocated(id.number(), _field_type, value, + &_extensions_); + + } + template <typename _proto_TypeTraits, + ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type, + bool _is_packed> + inline void UnsafeArenaSetAllocatedExtension( + const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier< + OneofOptions, _proto_TypeTraits, _field_type, _is_packed>& id, + typename _proto_TypeTraits::Singular::MutableType value) { + _proto_TypeTraits::UnsafeArenaSetAllocated(id.number(), _field_type, + value, &_extensions_); + + } + template <typename _proto_TypeTraits, + ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type, + bool _is_packed> + PROTOBUF_NODISCARD inline + typename _proto_TypeTraits::Singular::MutableType + ReleaseExtension( + const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier< + OneofOptions, _proto_TypeTraits, _field_type, _is_packed>& id) { + + return _proto_TypeTraits::Release(id.number(), _field_type, + &_extensions_); + } + template <typename _proto_TypeTraits, + ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type, + bool _is_packed> + inline typename _proto_TypeTraits::Singular::MutableType + UnsafeArenaReleaseExtension( + const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier< + OneofOptions, _proto_TypeTraits, _field_type, _is_packed>& id) { + + return _proto_TypeTraits::UnsafeArenaRelease(id.number(), _field_type, + &_extensions_); + } + + template <typename _proto_TypeTraits, + ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type, + bool _is_packed> + inline typename _proto_TypeTraits::Repeated::ConstType GetExtension( + const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier< + OneofOptions, _proto_TypeTraits, _field_type, _is_packed>& id, + int index) const { + + return _proto_TypeTraits::Get(id.number(), _extensions_, index); + } + + template <typename _proto_TypeTraits, + ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type, + bool _is_packed> + inline typename _proto_TypeTraits::Repeated::MutableType MutableExtension( + const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier< + OneofOptions, _proto_TypeTraits, _field_type, _is_packed>& id, + int index) { + + return _proto_TypeTraits::Mutable(id.number(), index, &_extensions_); + } + + template <typename _proto_TypeTraits, + ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type, + bool _is_packed> + inline void SetExtension( + const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier< + OneofOptions, _proto_TypeTraits, _field_type, _is_packed>& id, + int index, typename _proto_TypeTraits::Repeated::ConstType value) { + _proto_TypeTraits::Set(id.number(), index, value, &_extensions_); + + } + + template <typename _proto_TypeTraits, + ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type, + bool _is_packed> + inline typename _proto_TypeTraits::Repeated::MutableType AddExtension( + const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier< + OneofOptions, _proto_TypeTraits, _field_type, _is_packed>& id) { + typename _proto_TypeTraits::Repeated::MutableType to_add = + _proto_TypeTraits::Add(id.number(), _field_type, &_extensions_); + + return to_add; + } + + template <typename _proto_TypeTraits, + ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type, + bool _is_packed> + inline void AddExtension( + const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier< + OneofOptions, _proto_TypeTraits, _field_type, _is_packed>& id, + typename _proto_TypeTraits::Repeated::ConstType value) { + _proto_TypeTraits::Add(id.number(), _field_type, _is_packed, value, + &_extensions_); + + } + + template <typename _proto_TypeTraits, + ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type, + bool _is_packed> + inline const typename _proto_TypeTraits::Repeated::RepeatedFieldType& + GetRepeatedExtension( + const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier< + OneofOptions, _proto_TypeTraits, _field_type, _is_packed>& id) const { + + return _proto_TypeTraits::GetRepeated(id.number(), _extensions_); + } + + template <typename _proto_TypeTraits, + ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type, + bool _is_packed> + inline typename _proto_TypeTraits::Repeated::RepeatedFieldType* + MutableRepeatedExtension( + const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier< + OneofOptions, _proto_TypeTraits, _field_type, _is_packed>& id) { + + return _proto_TypeTraits::MutableRepeated(id.number(), _field_type, + _is_packed, &_extensions_); + } + + // @@protoc_insertion_point(class_scope:google.protobuf.OneofOptions) + private: + class _Internal; + + ::PROTOBUF_NAMESPACE_ID::internal::ExtensionSet _extensions_; + + template <typename T> friend class ::PROTOBUF_NAMESPACE_ID::Arena::InternalHelper; + typedef void InternalArenaConstructable_; + typedef void DestructorSkippable_; + ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::UninterpretedOption > uninterpreted_option_; + mutable ::PROTOBUF_NAMESPACE_ID::internal::CachedSize _cached_size_; + friend struct ::TableStruct_google_2fprotobuf_2fdescriptor_2eproto; +}; +// ------------------------------------------------------------------- + +class PROTOBUF_EXPORT EnumOptions final : + public ::PROTOBUF_NAMESPACE_ID::Message /* @@protoc_insertion_point(class_definition:google.protobuf.EnumOptions) */ { + public: + inline EnumOptions() : EnumOptions(nullptr) {} + ~EnumOptions() override; + explicit constexpr EnumOptions(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized); + + EnumOptions(const EnumOptions& from); + EnumOptions(EnumOptions&& from) noexcept + : EnumOptions() { + *this = ::std::move(from); + } + + inline EnumOptions& operator=(const EnumOptions& from) { + CopyFrom(from); + return *this; + } + inline EnumOptions& operator=(EnumOptions&& from) noexcept { + if (this == &from) return *this; + if (GetOwningArena() == from.GetOwningArena() + #ifdef PROTOBUF_FORCE_COPY_IN_MOVE + && GetOwningArena() != nullptr + #endif // !PROTOBUF_FORCE_COPY_IN_MOVE + ) { + InternalSwap(&from); + } else { + CopyFrom(from); + } + return *this; + } + + inline const ::PROTOBUF_NAMESPACE_ID::UnknownFieldSet& unknown_fields() const { + return _internal_metadata_.unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(::PROTOBUF_NAMESPACE_ID::UnknownFieldSet::default_instance); + } + inline ::PROTOBUF_NAMESPACE_ID::UnknownFieldSet* mutable_unknown_fields() { + return _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(); + } + + static const ::PROTOBUF_NAMESPACE_ID::Descriptor* descriptor() { + return GetDescriptor(); + } + static const ::PROTOBUF_NAMESPACE_ID::Descriptor* GetDescriptor() { + return default_instance().GetMetadata().descriptor; + } + static const ::PROTOBUF_NAMESPACE_ID::Reflection* GetReflection() { + return default_instance().GetMetadata().reflection; + } + static const EnumOptions& default_instance() { + return *internal_default_instance(); + } + static inline const EnumOptions* internal_default_instance() { + return reinterpret_cast<const EnumOptions*>( + &_EnumOptions_default_instance_); + } + static constexpr int kIndexInFileMessages = + 17; + + friend void swap(EnumOptions& a, EnumOptions& b) { + a.Swap(&b); + } + inline void Swap(EnumOptions* other) { + if (other == this) return; + #ifdef PROTOBUF_FORCE_COPY_IN_SWAP + if (GetOwningArena() != nullptr && + GetOwningArena() == other->GetOwningArena()) { + #else // PROTOBUF_FORCE_COPY_IN_SWAP + if (GetOwningArena() == other->GetOwningArena()) { + #endif // !PROTOBUF_FORCE_COPY_IN_SWAP + InternalSwap(other); + } else { + ::PROTOBUF_NAMESPACE_ID::internal::GenericSwap(this, other); + } + } + void UnsafeArenaSwap(EnumOptions* other) { + if (other == this) return; + GOOGLE_DCHECK(GetOwningArena() == other->GetOwningArena()); + InternalSwap(other); + } + + // implements Message ---------------------------------------------- + + EnumOptions* New(::PROTOBUF_NAMESPACE_ID::Arena* arena = nullptr) const final { + return CreateMaybeMessage<EnumOptions>(arena); + } + using ::PROTOBUF_NAMESPACE_ID::Message::CopyFrom; + void CopyFrom(const EnumOptions& from); + using ::PROTOBUF_NAMESPACE_ID::Message::MergeFrom; + void MergeFrom(const EnumOptions& 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; + + size_t ByteSizeLong() const final; + const char* _InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) final; + uint8_t* _InternalSerialize( + uint8_t* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const final; + int GetCachedSize() const final { return _cached_size_.Get(); } + + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const final; + void InternalSwap(EnumOptions* other); + + private: + friend class ::PROTOBUF_NAMESPACE_ID::internal::AnyMetadata; + static ::PROTOBUF_NAMESPACE_ID::StringPiece FullMessageName() { + return "google.protobuf.EnumOptions"; + } + protected: + explicit EnumOptions(::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 ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + enum : int { + kUninterpretedOptionFieldNumber = 999, + kAllowAliasFieldNumber = 2, + kDeprecatedFieldNumber = 3, + }; + // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999; + int uninterpreted_option_size() const; + private: + int _internal_uninterpreted_option_size() const; + public: + void clear_uninterpreted_option(); + ::PROTOBUF_NAMESPACE_ID::UninterpretedOption* mutable_uninterpreted_option(int index); + ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::UninterpretedOption >* + mutable_uninterpreted_option(); + private: + const ::PROTOBUF_NAMESPACE_ID::UninterpretedOption& _internal_uninterpreted_option(int index) const; + ::PROTOBUF_NAMESPACE_ID::UninterpretedOption* _internal_add_uninterpreted_option(); + public: + const ::PROTOBUF_NAMESPACE_ID::UninterpretedOption& uninterpreted_option(int index) const; + ::PROTOBUF_NAMESPACE_ID::UninterpretedOption* add_uninterpreted_option(); + const ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::UninterpretedOption >& + uninterpreted_option() const; + + // optional bool allow_alias = 2; + bool has_allow_alias() const; + private: + bool _internal_has_allow_alias() const; + public: + void clear_allow_alias(); + bool allow_alias() const; + void set_allow_alias(bool value); + private: + bool _internal_allow_alias() const; + void _internal_set_allow_alias(bool value); + public: + + // optional bool deprecated = 3 [default = false]; + bool has_deprecated() const; + private: + bool _internal_has_deprecated() const; + public: + void clear_deprecated(); + bool deprecated() const; + void set_deprecated(bool value); + private: + bool _internal_deprecated() const; + void _internal_set_deprecated(bool value); + public: + + + template <typename _proto_TypeTraits, + ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type, + bool _is_packed> + inline bool HasExtension( + const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier< + EnumOptions, _proto_TypeTraits, _field_type, _is_packed>& id) const { + + return _extensions_.Has(id.number()); + } + + template <typename _proto_TypeTraits, + ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type, + bool _is_packed> + inline void ClearExtension( + const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier< + EnumOptions, _proto_TypeTraits, _field_type, _is_packed>& id) { + _extensions_.ClearExtension(id.number()); + + } + + template <typename _proto_TypeTraits, + ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type, + bool _is_packed> + inline int ExtensionSize( + const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier< + EnumOptions, _proto_TypeTraits, _field_type, _is_packed>& id) const { + + return _extensions_.ExtensionSize(id.number()); + } + + template <typename _proto_TypeTraits, + ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type, + bool _is_packed> + inline typename _proto_TypeTraits::Singular::ConstType GetExtension( + const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier< + EnumOptions, _proto_TypeTraits, _field_type, _is_packed>& id) const { + + return _proto_TypeTraits::Get(id.number(), _extensions_, + id.default_value()); + } + + template <typename _proto_TypeTraits, + ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type, + bool _is_packed> + inline typename _proto_TypeTraits::Singular::MutableType MutableExtension( + const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier< + EnumOptions, _proto_TypeTraits, _field_type, _is_packed>& id) { + + return _proto_TypeTraits::Mutable(id.number(), _field_type, + &_extensions_); + } + + template <typename _proto_TypeTraits, + ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type, + bool _is_packed> + inline void SetExtension( + const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier< + EnumOptions, _proto_TypeTraits, _field_type, _is_packed>& id, + typename _proto_TypeTraits::Singular::ConstType value) { + _proto_TypeTraits::Set(id.number(), _field_type, value, &_extensions_); + + } + + template <typename _proto_TypeTraits, + ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type, + bool _is_packed> + inline void SetAllocatedExtension( + const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier< + EnumOptions, _proto_TypeTraits, _field_type, _is_packed>& id, + typename _proto_TypeTraits::Singular::MutableType value) { + _proto_TypeTraits::SetAllocated(id.number(), _field_type, value, + &_extensions_); + + } + template <typename _proto_TypeTraits, + ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type, + bool _is_packed> + inline void UnsafeArenaSetAllocatedExtension( + const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier< + EnumOptions, _proto_TypeTraits, _field_type, _is_packed>& id, + typename _proto_TypeTraits::Singular::MutableType value) { + _proto_TypeTraits::UnsafeArenaSetAllocated(id.number(), _field_type, + value, &_extensions_); + + } + template <typename _proto_TypeTraits, + ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type, + bool _is_packed> + PROTOBUF_NODISCARD inline + typename _proto_TypeTraits::Singular::MutableType + ReleaseExtension( + const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier< + EnumOptions, _proto_TypeTraits, _field_type, _is_packed>& id) { + + return _proto_TypeTraits::Release(id.number(), _field_type, + &_extensions_); + } + template <typename _proto_TypeTraits, + ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type, + bool _is_packed> + inline typename _proto_TypeTraits::Singular::MutableType + UnsafeArenaReleaseExtension( + const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier< + EnumOptions, _proto_TypeTraits, _field_type, _is_packed>& id) { + + return _proto_TypeTraits::UnsafeArenaRelease(id.number(), _field_type, + &_extensions_); + } + + template <typename _proto_TypeTraits, + ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type, + bool _is_packed> + inline typename _proto_TypeTraits::Repeated::ConstType GetExtension( + const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier< + EnumOptions, _proto_TypeTraits, _field_type, _is_packed>& id, + int index) const { + + return _proto_TypeTraits::Get(id.number(), _extensions_, index); + } + + template <typename _proto_TypeTraits, + ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type, + bool _is_packed> + inline typename _proto_TypeTraits::Repeated::MutableType MutableExtension( + const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier< + EnumOptions, _proto_TypeTraits, _field_type, _is_packed>& id, + int index) { + + return _proto_TypeTraits::Mutable(id.number(), index, &_extensions_); + } + + template <typename _proto_TypeTraits, + ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type, + bool _is_packed> + inline void SetExtension( + const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier< + EnumOptions, _proto_TypeTraits, _field_type, _is_packed>& id, + int index, typename _proto_TypeTraits::Repeated::ConstType value) { + _proto_TypeTraits::Set(id.number(), index, value, &_extensions_); + + } + + template <typename _proto_TypeTraits, + ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type, + bool _is_packed> + inline typename _proto_TypeTraits::Repeated::MutableType AddExtension( + const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier< + EnumOptions, _proto_TypeTraits, _field_type, _is_packed>& id) { + typename _proto_TypeTraits::Repeated::MutableType to_add = + _proto_TypeTraits::Add(id.number(), _field_type, &_extensions_); + + return to_add; + } + + template <typename _proto_TypeTraits, + ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type, + bool _is_packed> + inline void AddExtension( + const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier< + EnumOptions, _proto_TypeTraits, _field_type, _is_packed>& id, + typename _proto_TypeTraits::Repeated::ConstType value) { + _proto_TypeTraits::Add(id.number(), _field_type, _is_packed, value, + &_extensions_); + + } + + template <typename _proto_TypeTraits, + ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type, + bool _is_packed> + inline const typename _proto_TypeTraits::Repeated::RepeatedFieldType& + GetRepeatedExtension( + const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier< + EnumOptions, _proto_TypeTraits, _field_type, _is_packed>& id) const { + + return _proto_TypeTraits::GetRepeated(id.number(), _extensions_); + } + + template <typename _proto_TypeTraits, + ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type, + bool _is_packed> + inline typename _proto_TypeTraits::Repeated::RepeatedFieldType* + MutableRepeatedExtension( + const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier< + EnumOptions, _proto_TypeTraits, _field_type, _is_packed>& id) { + + return _proto_TypeTraits::MutableRepeated(id.number(), _field_type, + _is_packed, &_extensions_); + } + + // @@protoc_insertion_point(class_scope:google.protobuf.EnumOptions) + private: + class _Internal; + + ::PROTOBUF_NAMESPACE_ID::internal::ExtensionSet _extensions_; + + template <typename T> friend class ::PROTOBUF_NAMESPACE_ID::Arena::InternalHelper; + typedef void InternalArenaConstructable_; + typedef void DestructorSkippable_; + ::PROTOBUF_NAMESPACE_ID::internal::HasBits<1> _has_bits_; + mutable ::PROTOBUF_NAMESPACE_ID::internal::CachedSize _cached_size_; + ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::UninterpretedOption > uninterpreted_option_; + bool allow_alias_; + bool deprecated_; + friend struct ::TableStruct_google_2fprotobuf_2fdescriptor_2eproto; +}; +// ------------------------------------------------------------------- + +class PROTOBUF_EXPORT EnumValueOptions final : + public ::PROTOBUF_NAMESPACE_ID::Message /* @@protoc_insertion_point(class_definition:google.protobuf.EnumValueOptions) */ { + public: + inline EnumValueOptions() : EnumValueOptions(nullptr) {} + ~EnumValueOptions() override; + explicit constexpr EnumValueOptions(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized); + + EnumValueOptions(const EnumValueOptions& from); + EnumValueOptions(EnumValueOptions&& from) noexcept + : EnumValueOptions() { + *this = ::std::move(from); + } + + inline EnumValueOptions& operator=(const EnumValueOptions& from) { + CopyFrom(from); + return *this; + } + inline EnumValueOptions& operator=(EnumValueOptions&& from) noexcept { + if (this == &from) return *this; + if (GetOwningArena() == from.GetOwningArena() + #ifdef PROTOBUF_FORCE_COPY_IN_MOVE + && GetOwningArena() != nullptr + #endif // !PROTOBUF_FORCE_COPY_IN_MOVE + ) { + InternalSwap(&from); + } else { + CopyFrom(from); + } + return *this; + } + + inline const ::PROTOBUF_NAMESPACE_ID::UnknownFieldSet& unknown_fields() const { + return _internal_metadata_.unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(::PROTOBUF_NAMESPACE_ID::UnknownFieldSet::default_instance); + } + inline ::PROTOBUF_NAMESPACE_ID::UnknownFieldSet* mutable_unknown_fields() { + return _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(); + } + + static const ::PROTOBUF_NAMESPACE_ID::Descriptor* descriptor() { + return GetDescriptor(); + } + static const ::PROTOBUF_NAMESPACE_ID::Descriptor* GetDescriptor() { + return default_instance().GetMetadata().descriptor; + } + static const ::PROTOBUF_NAMESPACE_ID::Reflection* GetReflection() { + return default_instance().GetMetadata().reflection; + } + static const EnumValueOptions& default_instance() { + return *internal_default_instance(); + } + static inline const EnumValueOptions* internal_default_instance() { + return reinterpret_cast<const EnumValueOptions*>( + &_EnumValueOptions_default_instance_); + } + static constexpr int kIndexInFileMessages = + 18; + + friend void swap(EnumValueOptions& a, EnumValueOptions& b) { + a.Swap(&b); + } + inline void Swap(EnumValueOptions* other) { + if (other == this) return; + #ifdef PROTOBUF_FORCE_COPY_IN_SWAP + if (GetOwningArena() != nullptr && + GetOwningArena() == other->GetOwningArena()) { + #else // PROTOBUF_FORCE_COPY_IN_SWAP + if (GetOwningArena() == other->GetOwningArena()) { + #endif // !PROTOBUF_FORCE_COPY_IN_SWAP + InternalSwap(other); + } else { + ::PROTOBUF_NAMESPACE_ID::internal::GenericSwap(this, other); + } + } + void UnsafeArenaSwap(EnumValueOptions* other) { + if (other == this) return; + GOOGLE_DCHECK(GetOwningArena() == other->GetOwningArena()); + InternalSwap(other); + } + + // implements Message ---------------------------------------------- + + EnumValueOptions* New(::PROTOBUF_NAMESPACE_ID::Arena* arena = nullptr) const final { + return CreateMaybeMessage<EnumValueOptions>(arena); + } + using ::PROTOBUF_NAMESPACE_ID::Message::CopyFrom; + void CopyFrom(const EnumValueOptions& from); + using ::PROTOBUF_NAMESPACE_ID::Message::MergeFrom; + void MergeFrom(const EnumValueOptions& 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; + + size_t ByteSizeLong() const final; + const char* _InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) final; + uint8_t* _InternalSerialize( + uint8_t* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const final; + int GetCachedSize() const final { return _cached_size_.Get(); } + + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const final; + void InternalSwap(EnumValueOptions* other); + + private: + friend class ::PROTOBUF_NAMESPACE_ID::internal::AnyMetadata; + static ::PROTOBUF_NAMESPACE_ID::StringPiece FullMessageName() { + return "google.protobuf.EnumValueOptions"; + } + protected: + explicit EnumValueOptions(::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 ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + enum : int { + kUninterpretedOptionFieldNumber = 999, + kDeprecatedFieldNumber = 1, + }; + // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999; + int uninterpreted_option_size() const; + private: + int _internal_uninterpreted_option_size() const; + public: + void clear_uninterpreted_option(); + ::PROTOBUF_NAMESPACE_ID::UninterpretedOption* mutable_uninterpreted_option(int index); + ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::UninterpretedOption >* + mutable_uninterpreted_option(); + private: + const ::PROTOBUF_NAMESPACE_ID::UninterpretedOption& _internal_uninterpreted_option(int index) const; + ::PROTOBUF_NAMESPACE_ID::UninterpretedOption* _internal_add_uninterpreted_option(); + public: + const ::PROTOBUF_NAMESPACE_ID::UninterpretedOption& uninterpreted_option(int index) const; + ::PROTOBUF_NAMESPACE_ID::UninterpretedOption* add_uninterpreted_option(); + const ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::UninterpretedOption >& + uninterpreted_option() const; + + // optional bool deprecated = 1 [default = false]; + bool has_deprecated() const; + private: + bool _internal_has_deprecated() const; + public: + void clear_deprecated(); + bool deprecated() const; + void set_deprecated(bool value); + private: + bool _internal_deprecated() const; + void _internal_set_deprecated(bool value); + public: + + + template <typename _proto_TypeTraits, + ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type, + bool _is_packed> + inline bool HasExtension( + const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier< + EnumValueOptions, _proto_TypeTraits, _field_type, _is_packed>& id) const { + + return _extensions_.Has(id.number()); + } + + template <typename _proto_TypeTraits, + ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type, + bool _is_packed> + inline void ClearExtension( + const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier< + EnumValueOptions, _proto_TypeTraits, _field_type, _is_packed>& id) { + _extensions_.ClearExtension(id.number()); + + } + + template <typename _proto_TypeTraits, + ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type, + bool _is_packed> + inline int ExtensionSize( + const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier< + EnumValueOptions, _proto_TypeTraits, _field_type, _is_packed>& id) const { + + return _extensions_.ExtensionSize(id.number()); + } + + template <typename _proto_TypeTraits, + ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type, + bool _is_packed> + inline typename _proto_TypeTraits::Singular::ConstType GetExtension( + const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier< + EnumValueOptions, _proto_TypeTraits, _field_type, _is_packed>& id) const { + + return _proto_TypeTraits::Get(id.number(), _extensions_, + id.default_value()); + } + + template <typename _proto_TypeTraits, + ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type, + bool _is_packed> + inline typename _proto_TypeTraits::Singular::MutableType MutableExtension( + const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier< + EnumValueOptions, _proto_TypeTraits, _field_type, _is_packed>& id) { + + return _proto_TypeTraits::Mutable(id.number(), _field_type, + &_extensions_); + } + + template <typename _proto_TypeTraits, + ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type, + bool _is_packed> + inline void SetExtension( + const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier< + EnumValueOptions, _proto_TypeTraits, _field_type, _is_packed>& id, + typename _proto_TypeTraits::Singular::ConstType value) { + _proto_TypeTraits::Set(id.number(), _field_type, value, &_extensions_); + + } + + template <typename _proto_TypeTraits, + ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type, + bool _is_packed> + inline void SetAllocatedExtension( + const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier< + EnumValueOptions, _proto_TypeTraits, _field_type, _is_packed>& id, + typename _proto_TypeTraits::Singular::MutableType value) { + _proto_TypeTraits::SetAllocated(id.number(), _field_type, value, + &_extensions_); + + } + template <typename _proto_TypeTraits, + ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type, + bool _is_packed> + inline void UnsafeArenaSetAllocatedExtension( + const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier< + EnumValueOptions, _proto_TypeTraits, _field_type, _is_packed>& id, + typename _proto_TypeTraits::Singular::MutableType value) { + _proto_TypeTraits::UnsafeArenaSetAllocated(id.number(), _field_type, + value, &_extensions_); + + } + template <typename _proto_TypeTraits, + ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type, + bool _is_packed> + PROTOBUF_NODISCARD inline + typename _proto_TypeTraits::Singular::MutableType + ReleaseExtension( + const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier< + EnumValueOptions, _proto_TypeTraits, _field_type, _is_packed>& id) { + + return _proto_TypeTraits::Release(id.number(), _field_type, + &_extensions_); + } + template <typename _proto_TypeTraits, + ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type, + bool _is_packed> + inline typename _proto_TypeTraits::Singular::MutableType + UnsafeArenaReleaseExtension( + const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier< + EnumValueOptions, _proto_TypeTraits, _field_type, _is_packed>& id) { + + return _proto_TypeTraits::UnsafeArenaRelease(id.number(), _field_type, + &_extensions_); + } + + template <typename _proto_TypeTraits, + ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type, + bool _is_packed> + inline typename _proto_TypeTraits::Repeated::ConstType GetExtension( + const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier< + EnumValueOptions, _proto_TypeTraits, _field_type, _is_packed>& id, + int index) const { + + return _proto_TypeTraits::Get(id.number(), _extensions_, index); + } + + template <typename _proto_TypeTraits, + ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type, + bool _is_packed> + inline typename _proto_TypeTraits::Repeated::MutableType MutableExtension( + const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier< + EnumValueOptions, _proto_TypeTraits, _field_type, _is_packed>& id, + int index) { + + return _proto_TypeTraits::Mutable(id.number(), index, &_extensions_); + } + + template <typename _proto_TypeTraits, + ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type, + bool _is_packed> + inline void SetExtension( + const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier< + EnumValueOptions, _proto_TypeTraits, _field_type, _is_packed>& id, + int index, typename _proto_TypeTraits::Repeated::ConstType value) { + _proto_TypeTraits::Set(id.number(), index, value, &_extensions_); + + } + + template <typename _proto_TypeTraits, + ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type, + bool _is_packed> + inline typename _proto_TypeTraits::Repeated::MutableType AddExtension( + const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier< + EnumValueOptions, _proto_TypeTraits, _field_type, _is_packed>& id) { + typename _proto_TypeTraits::Repeated::MutableType to_add = + _proto_TypeTraits::Add(id.number(), _field_type, &_extensions_); + + return to_add; + } + + template <typename _proto_TypeTraits, + ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type, + bool _is_packed> + inline void AddExtension( + const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier< + EnumValueOptions, _proto_TypeTraits, _field_type, _is_packed>& id, + typename _proto_TypeTraits::Repeated::ConstType value) { + _proto_TypeTraits::Add(id.number(), _field_type, _is_packed, value, + &_extensions_); + + } + + template <typename _proto_TypeTraits, + ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type, + bool _is_packed> + inline const typename _proto_TypeTraits::Repeated::RepeatedFieldType& + GetRepeatedExtension( + const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier< + EnumValueOptions, _proto_TypeTraits, _field_type, _is_packed>& id) const { + + return _proto_TypeTraits::GetRepeated(id.number(), _extensions_); + } + + template <typename _proto_TypeTraits, + ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type, + bool _is_packed> + inline typename _proto_TypeTraits::Repeated::RepeatedFieldType* + MutableRepeatedExtension( + const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier< + EnumValueOptions, _proto_TypeTraits, _field_type, _is_packed>& id) { + + return _proto_TypeTraits::MutableRepeated(id.number(), _field_type, + _is_packed, &_extensions_); + } + + // @@protoc_insertion_point(class_scope:google.protobuf.EnumValueOptions) + private: + class _Internal; + + ::PROTOBUF_NAMESPACE_ID::internal::ExtensionSet _extensions_; + + template <typename T> friend class ::PROTOBUF_NAMESPACE_ID::Arena::InternalHelper; + typedef void InternalArenaConstructable_; + typedef void DestructorSkippable_; + ::PROTOBUF_NAMESPACE_ID::internal::HasBits<1> _has_bits_; + mutable ::PROTOBUF_NAMESPACE_ID::internal::CachedSize _cached_size_; + ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::UninterpretedOption > uninterpreted_option_; + bool deprecated_; + friend struct ::TableStruct_google_2fprotobuf_2fdescriptor_2eproto; +}; +// ------------------------------------------------------------------- + +class PROTOBUF_EXPORT ServiceOptions final : + public ::PROTOBUF_NAMESPACE_ID::Message /* @@protoc_insertion_point(class_definition:google.protobuf.ServiceOptions) */ { + public: + inline ServiceOptions() : ServiceOptions(nullptr) {} + ~ServiceOptions() override; + explicit constexpr ServiceOptions(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized); + + ServiceOptions(const ServiceOptions& from); + ServiceOptions(ServiceOptions&& from) noexcept + : ServiceOptions() { + *this = ::std::move(from); + } + + inline ServiceOptions& operator=(const ServiceOptions& from) { + CopyFrom(from); + return *this; + } + inline ServiceOptions& operator=(ServiceOptions&& from) noexcept { + if (this == &from) return *this; + if (GetOwningArena() == from.GetOwningArena() + #ifdef PROTOBUF_FORCE_COPY_IN_MOVE + && GetOwningArena() != nullptr + #endif // !PROTOBUF_FORCE_COPY_IN_MOVE + ) { + InternalSwap(&from); + } else { + CopyFrom(from); + } + return *this; + } + + inline const ::PROTOBUF_NAMESPACE_ID::UnknownFieldSet& unknown_fields() const { + return _internal_metadata_.unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(::PROTOBUF_NAMESPACE_ID::UnknownFieldSet::default_instance); + } + inline ::PROTOBUF_NAMESPACE_ID::UnknownFieldSet* mutable_unknown_fields() { + return _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(); + } + + static const ::PROTOBUF_NAMESPACE_ID::Descriptor* descriptor() { + return GetDescriptor(); + } + static const ::PROTOBUF_NAMESPACE_ID::Descriptor* GetDescriptor() { + return default_instance().GetMetadata().descriptor; + } + static const ::PROTOBUF_NAMESPACE_ID::Reflection* GetReflection() { + return default_instance().GetMetadata().reflection; + } + static const ServiceOptions& default_instance() { + return *internal_default_instance(); + } + static inline const ServiceOptions* internal_default_instance() { + return reinterpret_cast<const ServiceOptions*>( + &_ServiceOptions_default_instance_); + } + static constexpr int kIndexInFileMessages = + 19; + + friend void swap(ServiceOptions& a, ServiceOptions& b) { + a.Swap(&b); + } + inline void Swap(ServiceOptions* other) { + if (other == this) return; + #ifdef PROTOBUF_FORCE_COPY_IN_SWAP + if (GetOwningArena() != nullptr && + GetOwningArena() == other->GetOwningArena()) { + #else // PROTOBUF_FORCE_COPY_IN_SWAP + if (GetOwningArena() == other->GetOwningArena()) { + #endif // !PROTOBUF_FORCE_COPY_IN_SWAP + InternalSwap(other); + } else { + ::PROTOBUF_NAMESPACE_ID::internal::GenericSwap(this, other); + } + } + void UnsafeArenaSwap(ServiceOptions* other) { + if (other == this) return; + GOOGLE_DCHECK(GetOwningArena() == other->GetOwningArena()); + InternalSwap(other); + } + + // implements Message ---------------------------------------------- + + ServiceOptions* New(::PROTOBUF_NAMESPACE_ID::Arena* arena = nullptr) const final { + return CreateMaybeMessage<ServiceOptions>(arena); + } + using ::PROTOBUF_NAMESPACE_ID::Message::CopyFrom; + void CopyFrom(const ServiceOptions& from); + using ::PROTOBUF_NAMESPACE_ID::Message::MergeFrom; + void MergeFrom(const ServiceOptions& 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; + + size_t ByteSizeLong() const final; + const char* _InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) final; + uint8_t* _InternalSerialize( + uint8_t* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const final; + int GetCachedSize() const final { return _cached_size_.Get(); } + + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const final; + void InternalSwap(ServiceOptions* other); + + private: + friend class ::PROTOBUF_NAMESPACE_ID::internal::AnyMetadata; + static ::PROTOBUF_NAMESPACE_ID::StringPiece FullMessageName() { + return "google.protobuf.ServiceOptions"; + } + protected: + explicit ServiceOptions(::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 ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + enum : int { + kUninterpretedOptionFieldNumber = 999, + kDeprecatedFieldNumber = 33, + }; + // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999; + int uninterpreted_option_size() const; + private: + int _internal_uninterpreted_option_size() const; + public: + void clear_uninterpreted_option(); + ::PROTOBUF_NAMESPACE_ID::UninterpretedOption* mutable_uninterpreted_option(int index); + ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::UninterpretedOption >* + mutable_uninterpreted_option(); + private: + const ::PROTOBUF_NAMESPACE_ID::UninterpretedOption& _internal_uninterpreted_option(int index) const; + ::PROTOBUF_NAMESPACE_ID::UninterpretedOption* _internal_add_uninterpreted_option(); + public: + const ::PROTOBUF_NAMESPACE_ID::UninterpretedOption& uninterpreted_option(int index) const; + ::PROTOBUF_NAMESPACE_ID::UninterpretedOption* add_uninterpreted_option(); + const ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::UninterpretedOption >& + uninterpreted_option() const; + + // optional bool deprecated = 33 [default = false]; + bool has_deprecated() const; + private: + bool _internal_has_deprecated() const; + public: + void clear_deprecated(); + bool deprecated() const; + void set_deprecated(bool value); + private: + bool _internal_deprecated() const; + void _internal_set_deprecated(bool value); + public: + + + template <typename _proto_TypeTraits, + ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type, + bool _is_packed> + inline bool HasExtension( + const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier< + ServiceOptions, _proto_TypeTraits, _field_type, _is_packed>& id) const { + + return _extensions_.Has(id.number()); + } + + template <typename _proto_TypeTraits, + ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type, + bool _is_packed> + inline void ClearExtension( + const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier< + ServiceOptions, _proto_TypeTraits, _field_type, _is_packed>& id) { + _extensions_.ClearExtension(id.number()); + + } + + template <typename _proto_TypeTraits, + ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type, + bool _is_packed> + inline int ExtensionSize( + const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier< + ServiceOptions, _proto_TypeTraits, _field_type, _is_packed>& id) const { + + return _extensions_.ExtensionSize(id.number()); + } + + template <typename _proto_TypeTraits, + ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type, + bool _is_packed> + inline typename _proto_TypeTraits::Singular::ConstType GetExtension( + const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier< + ServiceOptions, _proto_TypeTraits, _field_type, _is_packed>& id) const { + + return _proto_TypeTraits::Get(id.number(), _extensions_, + id.default_value()); + } + + template <typename _proto_TypeTraits, + ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type, + bool _is_packed> + inline typename _proto_TypeTraits::Singular::MutableType MutableExtension( + const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier< + ServiceOptions, _proto_TypeTraits, _field_type, _is_packed>& id) { + + return _proto_TypeTraits::Mutable(id.number(), _field_type, + &_extensions_); + } + + template <typename _proto_TypeTraits, + ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type, + bool _is_packed> + inline void SetExtension( + const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier< + ServiceOptions, _proto_TypeTraits, _field_type, _is_packed>& id, + typename _proto_TypeTraits::Singular::ConstType value) { + _proto_TypeTraits::Set(id.number(), _field_type, value, &_extensions_); + + } + + template <typename _proto_TypeTraits, + ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type, + bool _is_packed> + inline void SetAllocatedExtension( + const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier< + ServiceOptions, _proto_TypeTraits, _field_type, _is_packed>& id, + typename _proto_TypeTraits::Singular::MutableType value) { + _proto_TypeTraits::SetAllocated(id.number(), _field_type, value, + &_extensions_); + + } + template <typename _proto_TypeTraits, + ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type, + bool _is_packed> + inline void UnsafeArenaSetAllocatedExtension( + const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier< + ServiceOptions, _proto_TypeTraits, _field_type, _is_packed>& id, + typename _proto_TypeTraits::Singular::MutableType value) { + _proto_TypeTraits::UnsafeArenaSetAllocated(id.number(), _field_type, + value, &_extensions_); + + } + template <typename _proto_TypeTraits, + ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type, + bool _is_packed> + PROTOBUF_NODISCARD inline + typename _proto_TypeTraits::Singular::MutableType + ReleaseExtension( + const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier< + ServiceOptions, _proto_TypeTraits, _field_type, _is_packed>& id) { + + return _proto_TypeTraits::Release(id.number(), _field_type, + &_extensions_); + } + template <typename _proto_TypeTraits, + ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type, + bool _is_packed> + inline typename _proto_TypeTraits::Singular::MutableType + UnsafeArenaReleaseExtension( + const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier< + ServiceOptions, _proto_TypeTraits, _field_type, _is_packed>& id) { + + return _proto_TypeTraits::UnsafeArenaRelease(id.number(), _field_type, + &_extensions_); + } + + template <typename _proto_TypeTraits, + ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type, + bool _is_packed> + inline typename _proto_TypeTraits::Repeated::ConstType GetExtension( + const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier< + ServiceOptions, _proto_TypeTraits, _field_type, _is_packed>& id, + int index) const { + + return _proto_TypeTraits::Get(id.number(), _extensions_, index); + } + + template <typename _proto_TypeTraits, + ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type, + bool _is_packed> + inline typename _proto_TypeTraits::Repeated::MutableType MutableExtension( + const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier< + ServiceOptions, _proto_TypeTraits, _field_type, _is_packed>& id, + int index) { + + return _proto_TypeTraits::Mutable(id.number(), index, &_extensions_); + } + + template <typename _proto_TypeTraits, + ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type, + bool _is_packed> + inline void SetExtension( + const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier< + ServiceOptions, _proto_TypeTraits, _field_type, _is_packed>& id, + int index, typename _proto_TypeTraits::Repeated::ConstType value) { + _proto_TypeTraits::Set(id.number(), index, value, &_extensions_); + + } + + template <typename _proto_TypeTraits, + ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type, + bool _is_packed> + inline typename _proto_TypeTraits::Repeated::MutableType AddExtension( + const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier< + ServiceOptions, _proto_TypeTraits, _field_type, _is_packed>& id) { + typename _proto_TypeTraits::Repeated::MutableType to_add = + _proto_TypeTraits::Add(id.number(), _field_type, &_extensions_); + + return to_add; + } + + template <typename _proto_TypeTraits, + ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type, + bool _is_packed> + inline void AddExtension( + const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier< + ServiceOptions, _proto_TypeTraits, _field_type, _is_packed>& id, + typename _proto_TypeTraits::Repeated::ConstType value) { + _proto_TypeTraits::Add(id.number(), _field_type, _is_packed, value, + &_extensions_); + + } + + template <typename _proto_TypeTraits, + ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type, + bool _is_packed> + inline const typename _proto_TypeTraits::Repeated::RepeatedFieldType& + GetRepeatedExtension( + const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier< + ServiceOptions, _proto_TypeTraits, _field_type, _is_packed>& id) const { + + return _proto_TypeTraits::GetRepeated(id.number(), _extensions_); + } + + template <typename _proto_TypeTraits, + ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type, + bool _is_packed> + inline typename _proto_TypeTraits::Repeated::RepeatedFieldType* + MutableRepeatedExtension( + const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier< + ServiceOptions, _proto_TypeTraits, _field_type, _is_packed>& id) { + + return _proto_TypeTraits::MutableRepeated(id.number(), _field_type, + _is_packed, &_extensions_); + } + + // @@protoc_insertion_point(class_scope:google.protobuf.ServiceOptions) + private: + class _Internal; + + ::PROTOBUF_NAMESPACE_ID::internal::ExtensionSet _extensions_; + + template <typename T> friend class ::PROTOBUF_NAMESPACE_ID::Arena::InternalHelper; + typedef void InternalArenaConstructable_; + typedef void DestructorSkippable_; + ::PROTOBUF_NAMESPACE_ID::internal::HasBits<1> _has_bits_; + mutable ::PROTOBUF_NAMESPACE_ID::internal::CachedSize _cached_size_; + ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::UninterpretedOption > uninterpreted_option_; + bool deprecated_; + friend struct ::TableStruct_google_2fprotobuf_2fdescriptor_2eproto; +}; +// ------------------------------------------------------------------- + +class PROTOBUF_EXPORT MethodOptions final : + public ::PROTOBUF_NAMESPACE_ID::Message /* @@protoc_insertion_point(class_definition:google.protobuf.MethodOptions) */ { + public: + inline MethodOptions() : MethodOptions(nullptr) {} + ~MethodOptions() override; + explicit constexpr MethodOptions(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized); + + MethodOptions(const MethodOptions& from); + MethodOptions(MethodOptions&& from) noexcept + : MethodOptions() { + *this = ::std::move(from); + } + + inline MethodOptions& operator=(const MethodOptions& from) { + CopyFrom(from); + return *this; + } + inline MethodOptions& operator=(MethodOptions&& from) noexcept { + if (this == &from) return *this; + if (GetOwningArena() == from.GetOwningArena() + #ifdef PROTOBUF_FORCE_COPY_IN_MOVE + && GetOwningArena() != nullptr + #endif // !PROTOBUF_FORCE_COPY_IN_MOVE + ) { + InternalSwap(&from); + } else { + CopyFrom(from); + } + return *this; + } + + inline const ::PROTOBUF_NAMESPACE_ID::UnknownFieldSet& unknown_fields() const { + return _internal_metadata_.unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(::PROTOBUF_NAMESPACE_ID::UnknownFieldSet::default_instance); + } + inline ::PROTOBUF_NAMESPACE_ID::UnknownFieldSet* mutable_unknown_fields() { + return _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(); + } + + static const ::PROTOBUF_NAMESPACE_ID::Descriptor* descriptor() { + return GetDescriptor(); + } + static const ::PROTOBUF_NAMESPACE_ID::Descriptor* GetDescriptor() { + return default_instance().GetMetadata().descriptor; + } + static const ::PROTOBUF_NAMESPACE_ID::Reflection* GetReflection() { + return default_instance().GetMetadata().reflection; + } + static const MethodOptions& default_instance() { + return *internal_default_instance(); + } + static inline const MethodOptions* internal_default_instance() { + return reinterpret_cast<const MethodOptions*>( + &_MethodOptions_default_instance_); + } + static constexpr int kIndexInFileMessages = + 20; + + friend void swap(MethodOptions& a, MethodOptions& b) { + a.Swap(&b); + } + inline void Swap(MethodOptions* other) { + if (other == this) return; + #ifdef PROTOBUF_FORCE_COPY_IN_SWAP + if (GetOwningArena() != nullptr && + GetOwningArena() == other->GetOwningArena()) { + #else // PROTOBUF_FORCE_COPY_IN_SWAP + if (GetOwningArena() == other->GetOwningArena()) { + #endif // !PROTOBUF_FORCE_COPY_IN_SWAP + InternalSwap(other); + } else { + ::PROTOBUF_NAMESPACE_ID::internal::GenericSwap(this, other); + } + } + void UnsafeArenaSwap(MethodOptions* other) { + if (other == this) return; + GOOGLE_DCHECK(GetOwningArena() == other->GetOwningArena()); + InternalSwap(other); + } + + // implements Message ---------------------------------------------- + + MethodOptions* New(::PROTOBUF_NAMESPACE_ID::Arena* arena = nullptr) const final { + return CreateMaybeMessage<MethodOptions>(arena); + } + using ::PROTOBUF_NAMESPACE_ID::Message::CopyFrom; + void CopyFrom(const MethodOptions& from); + using ::PROTOBUF_NAMESPACE_ID::Message::MergeFrom; + void MergeFrom(const MethodOptions& 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; + + size_t ByteSizeLong() const final; + const char* _InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) final; + uint8_t* _InternalSerialize( + uint8_t* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const final; + int GetCachedSize() const final { return _cached_size_.Get(); } + + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const final; + void InternalSwap(MethodOptions* other); + + private: + friend class ::PROTOBUF_NAMESPACE_ID::internal::AnyMetadata; + static ::PROTOBUF_NAMESPACE_ID::StringPiece FullMessageName() { + return "google.protobuf.MethodOptions"; + } + protected: + explicit MethodOptions(::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 ---------------------------------------------------- + + typedef MethodOptions_IdempotencyLevel IdempotencyLevel; + static constexpr IdempotencyLevel IDEMPOTENCY_UNKNOWN = + MethodOptions_IdempotencyLevel_IDEMPOTENCY_UNKNOWN; + static constexpr IdempotencyLevel NO_SIDE_EFFECTS = + MethodOptions_IdempotencyLevel_NO_SIDE_EFFECTS; + static constexpr IdempotencyLevel IDEMPOTENT = + MethodOptions_IdempotencyLevel_IDEMPOTENT; + static inline bool IdempotencyLevel_IsValid(int value) { + return MethodOptions_IdempotencyLevel_IsValid(value); + } + static constexpr IdempotencyLevel IdempotencyLevel_MIN = + MethodOptions_IdempotencyLevel_IdempotencyLevel_MIN; + static constexpr IdempotencyLevel IdempotencyLevel_MAX = + MethodOptions_IdempotencyLevel_IdempotencyLevel_MAX; + static constexpr int IdempotencyLevel_ARRAYSIZE = + MethodOptions_IdempotencyLevel_IdempotencyLevel_ARRAYSIZE; + static inline const ::PROTOBUF_NAMESPACE_ID::EnumDescriptor* + IdempotencyLevel_descriptor() { + return MethodOptions_IdempotencyLevel_descriptor(); + } + template<typename T> + static inline const TProtoStringType& IdempotencyLevel_Name(T enum_t_value) { + static_assert(::std::is_same<T, IdempotencyLevel>::value || + ::std::is_integral<T>::value, + "Incorrect type passed to function IdempotencyLevel_Name."); + return MethodOptions_IdempotencyLevel_Name(enum_t_value); + } + static inline bool IdempotencyLevel_Parse(::PROTOBUF_NAMESPACE_ID::ConstStringParam name, + IdempotencyLevel* value) { + return MethodOptions_IdempotencyLevel_Parse(name, value); + } + + // accessors ------------------------------------------------------- + + enum : int { + kUninterpretedOptionFieldNumber = 999, + kDeprecatedFieldNumber = 33, + kIdempotencyLevelFieldNumber = 34, + }; + // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999; + int uninterpreted_option_size() const; + private: + int _internal_uninterpreted_option_size() const; + public: + void clear_uninterpreted_option(); + ::PROTOBUF_NAMESPACE_ID::UninterpretedOption* mutable_uninterpreted_option(int index); + ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::UninterpretedOption >* + mutable_uninterpreted_option(); + private: + const ::PROTOBUF_NAMESPACE_ID::UninterpretedOption& _internal_uninterpreted_option(int index) const; + ::PROTOBUF_NAMESPACE_ID::UninterpretedOption* _internal_add_uninterpreted_option(); + public: + const ::PROTOBUF_NAMESPACE_ID::UninterpretedOption& uninterpreted_option(int index) const; + ::PROTOBUF_NAMESPACE_ID::UninterpretedOption* add_uninterpreted_option(); + const ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::UninterpretedOption >& + uninterpreted_option() const; + + // optional bool deprecated = 33 [default = false]; + bool has_deprecated() const; + private: + bool _internal_has_deprecated() const; + public: + void clear_deprecated(); + bool deprecated() const; + void set_deprecated(bool value); + private: + bool _internal_deprecated() const; + void _internal_set_deprecated(bool value); + public: + + // optional .google.protobuf.MethodOptions.IdempotencyLevel idempotency_level = 34 [default = IDEMPOTENCY_UNKNOWN]; + bool has_idempotency_level() const; + private: + bool _internal_has_idempotency_level() const; + public: + void clear_idempotency_level(); + ::PROTOBUF_NAMESPACE_ID::MethodOptions_IdempotencyLevel idempotency_level() const; + void set_idempotency_level(::PROTOBUF_NAMESPACE_ID::MethodOptions_IdempotencyLevel value); + private: + ::PROTOBUF_NAMESPACE_ID::MethodOptions_IdempotencyLevel _internal_idempotency_level() const; + void _internal_set_idempotency_level(::PROTOBUF_NAMESPACE_ID::MethodOptions_IdempotencyLevel value); + public: + + + template <typename _proto_TypeTraits, + ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type, + bool _is_packed> + inline bool HasExtension( + const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier< + MethodOptions, _proto_TypeTraits, _field_type, _is_packed>& id) const { + + return _extensions_.Has(id.number()); + } + + template <typename _proto_TypeTraits, + ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type, + bool _is_packed> + inline void ClearExtension( + const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier< + MethodOptions, _proto_TypeTraits, _field_type, _is_packed>& id) { + _extensions_.ClearExtension(id.number()); + + } + + template <typename _proto_TypeTraits, + ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type, + bool _is_packed> + inline int ExtensionSize( + const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier< + MethodOptions, _proto_TypeTraits, _field_type, _is_packed>& id) const { + + return _extensions_.ExtensionSize(id.number()); + } + + template <typename _proto_TypeTraits, + ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type, + bool _is_packed> + inline typename _proto_TypeTraits::Singular::ConstType GetExtension( + const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier< + MethodOptions, _proto_TypeTraits, _field_type, _is_packed>& id) const { + + return _proto_TypeTraits::Get(id.number(), _extensions_, + id.default_value()); + } + + template <typename _proto_TypeTraits, + ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type, + bool _is_packed> + inline typename _proto_TypeTraits::Singular::MutableType MutableExtension( + const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier< + MethodOptions, _proto_TypeTraits, _field_type, _is_packed>& id) { + + return _proto_TypeTraits::Mutable(id.number(), _field_type, + &_extensions_); + } + + template <typename _proto_TypeTraits, + ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type, + bool _is_packed> + inline void SetExtension( + const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier< + MethodOptions, _proto_TypeTraits, _field_type, _is_packed>& id, + typename _proto_TypeTraits::Singular::ConstType value) { + _proto_TypeTraits::Set(id.number(), _field_type, value, &_extensions_); + + } + + template <typename _proto_TypeTraits, + ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type, + bool _is_packed> + inline void SetAllocatedExtension( + const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier< + MethodOptions, _proto_TypeTraits, _field_type, _is_packed>& id, + typename _proto_TypeTraits::Singular::MutableType value) { + _proto_TypeTraits::SetAllocated(id.number(), _field_type, value, + &_extensions_); + + } + template <typename _proto_TypeTraits, + ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type, + bool _is_packed> + inline void UnsafeArenaSetAllocatedExtension( + const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier< + MethodOptions, _proto_TypeTraits, _field_type, _is_packed>& id, + typename _proto_TypeTraits::Singular::MutableType value) { + _proto_TypeTraits::UnsafeArenaSetAllocated(id.number(), _field_type, + value, &_extensions_); + + } + template <typename _proto_TypeTraits, + ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type, + bool _is_packed> + PROTOBUF_NODISCARD inline + typename _proto_TypeTraits::Singular::MutableType + ReleaseExtension( + const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier< + MethodOptions, _proto_TypeTraits, _field_type, _is_packed>& id) { + + return _proto_TypeTraits::Release(id.number(), _field_type, + &_extensions_); + } + template <typename _proto_TypeTraits, + ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type, + bool _is_packed> + inline typename _proto_TypeTraits::Singular::MutableType + UnsafeArenaReleaseExtension( + const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier< + MethodOptions, _proto_TypeTraits, _field_type, _is_packed>& id) { + + return _proto_TypeTraits::UnsafeArenaRelease(id.number(), _field_type, + &_extensions_); + } + + template <typename _proto_TypeTraits, + ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type, + bool _is_packed> + inline typename _proto_TypeTraits::Repeated::ConstType GetExtension( + const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier< + MethodOptions, _proto_TypeTraits, _field_type, _is_packed>& id, + int index) const { + + return _proto_TypeTraits::Get(id.number(), _extensions_, index); + } + + template <typename _proto_TypeTraits, + ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type, + bool _is_packed> + inline typename _proto_TypeTraits::Repeated::MutableType MutableExtension( + const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier< + MethodOptions, _proto_TypeTraits, _field_type, _is_packed>& id, + int index) { + + return _proto_TypeTraits::Mutable(id.number(), index, &_extensions_); + } + + template <typename _proto_TypeTraits, + ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type, + bool _is_packed> + inline void SetExtension( + const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier< + MethodOptions, _proto_TypeTraits, _field_type, _is_packed>& id, + int index, typename _proto_TypeTraits::Repeated::ConstType value) { + _proto_TypeTraits::Set(id.number(), index, value, &_extensions_); + + } + + template <typename _proto_TypeTraits, + ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type, + bool _is_packed> + inline typename _proto_TypeTraits::Repeated::MutableType AddExtension( + const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier< + MethodOptions, _proto_TypeTraits, _field_type, _is_packed>& id) { + typename _proto_TypeTraits::Repeated::MutableType to_add = + _proto_TypeTraits::Add(id.number(), _field_type, &_extensions_); + + return to_add; + } + + template <typename _proto_TypeTraits, + ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type, + bool _is_packed> + inline void AddExtension( + const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier< + MethodOptions, _proto_TypeTraits, _field_type, _is_packed>& id, + typename _proto_TypeTraits::Repeated::ConstType value) { + _proto_TypeTraits::Add(id.number(), _field_type, _is_packed, value, + &_extensions_); + + } + + template <typename _proto_TypeTraits, + ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type, + bool _is_packed> + inline const typename _proto_TypeTraits::Repeated::RepeatedFieldType& + GetRepeatedExtension( + const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier< + MethodOptions, _proto_TypeTraits, _field_type, _is_packed>& id) const { + + return _proto_TypeTraits::GetRepeated(id.number(), _extensions_); + } + + template <typename _proto_TypeTraits, + ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type, + bool _is_packed> + inline typename _proto_TypeTraits::Repeated::RepeatedFieldType* + MutableRepeatedExtension( + const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier< + MethodOptions, _proto_TypeTraits, _field_type, _is_packed>& id) { + + return _proto_TypeTraits::MutableRepeated(id.number(), _field_type, + _is_packed, &_extensions_); + } + + // @@protoc_insertion_point(class_scope:google.protobuf.MethodOptions) + private: + class _Internal; + + ::PROTOBUF_NAMESPACE_ID::internal::ExtensionSet _extensions_; + + template <typename T> friend class ::PROTOBUF_NAMESPACE_ID::Arena::InternalHelper; + typedef void InternalArenaConstructable_; + typedef void DestructorSkippable_; + ::PROTOBUF_NAMESPACE_ID::internal::HasBits<1> _has_bits_; + mutable ::PROTOBUF_NAMESPACE_ID::internal::CachedSize _cached_size_; + ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::UninterpretedOption > uninterpreted_option_; + bool deprecated_; + int idempotency_level_; + friend struct ::TableStruct_google_2fprotobuf_2fdescriptor_2eproto; +}; +// ------------------------------------------------------------------- + +class PROTOBUF_EXPORT UninterpretedOption_NamePart final : + public ::PROTOBUF_NAMESPACE_ID::Message /* @@protoc_insertion_point(class_definition:google.protobuf.UninterpretedOption.NamePart) */ { + public: + inline UninterpretedOption_NamePart() : UninterpretedOption_NamePart(nullptr) {} + ~UninterpretedOption_NamePart() override; + explicit constexpr UninterpretedOption_NamePart(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized); + + UninterpretedOption_NamePart(const UninterpretedOption_NamePart& from); + UninterpretedOption_NamePart(UninterpretedOption_NamePart&& from) noexcept + : UninterpretedOption_NamePart() { + *this = ::std::move(from); + } + + inline UninterpretedOption_NamePart& operator=(const UninterpretedOption_NamePart& from) { + CopyFrom(from); + return *this; + } + inline UninterpretedOption_NamePart& operator=(UninterpretedOption_NamePart&& from) noexcept { + if (this == &from) return *this; + if (GetOwningArena() == from.GetOwningArena() + #ifdef PROTOBUF_FORCE_COPY_IN_MOVE + && GetOwningArena() != nullptr + #endif // !PROTOBUF_FORCE_COPY_IN_MOVE + ) { + InternalSwap(&from); + } else { + CopyFrom(from); + } + return *this; + } + + inline const ::PROTOBUF_NAMESPACE_ID::UnknownFieldSet& unknown_fields() const { + return _internal_metadata_.unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(::PROTOBUF_NAMESPACE_ID::UnknownFieldSet::default_instance); + } + inline ::PROTOBUF_NAMESPACE_ID::UnknownFieldSet* mutable_unknown_fields() { + return _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(); + } + + static const ::PROTOBUF_NAMESPACE_ID::Descriptor* descriptor() { + return GetDescriptor(); + } + static const ::PROTOBUF_NAMESPACE_ID::Descriptor* GetDescriptor() { + return default_instance().GetMetadata().descriptor; + } + static const ::PROTOBUF_NAMESPACE_ID::Reflection* GetReflection() { + return default_instance().GetMetadata().reflection; + } + static const UninterpretedOption_NamePart& default_instance() { + return *internal_default_instance(); + } + static inline const UninterpretedOption_NamePart* internal_default_instance() { + return reinterpret_cast<const UninterpretedOption_NamePart*>( + &_UninterpretedOption_NamePart_default_instance_); + } + static constexpr int kIndexInFileMessages = + 21; + + friend void swap(UninterpretedOption_NamePart& a, UninterpretedOption_NamePart& b) { + a.Swap(&b); + } + inline void Swap(UninterpretedOption_NamePart* other) { + if (other == this) return; + #ifdef PROTOBUF_FORCE_COPY_IN_SWAP + if (GetOwningArena() != nullptr && + GetOwningArena() == other->GetOwningArena()) { + #else // PROTOBUF_FORCE_COPY_IN_SWAP + if (GetOwningArena() == other->GetOwningArena()) { + #endif // !PROTOBUF_FORCE_COPY_IN_SWAP + InternalSwap(other); + } else { + ::PROTOBUF_NAMESPACE_ID::internal::GenericSwap(this, other); + } + } + void UnsafeArenaSwap(UninterpretedOption_NamePart* other) { + if (other == this) return; + GOOGLE_DCHECK(GetOwningArena() == other->GetOwningArena()); + InternalSwap(other); + } + + // implements Message ---------------------------------------------- + + UninterpretedOption_NamePart* New(::PROTOBUF_NAMESPACE_ID::Arena* arena = nullptr) const final { + return CreateMaybeMessage<UninterpretedOption_NamePart>(arena); + } + using ::PROTOBUF_NAMESPACE_ID::Message::CopyFrom; + void CopyFrom(const UninterpretedOption_NamePart& from); + using ::PROTOBUF_NAMESPACE_ID::Message::MergeFrom; + void MergeFrom(const UninterpretedOption_NamePart& 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; + + size_t ByteSizeLong() const final; + const char* _InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) final; + uint8_t* _InternalSerialize( + uint8_t* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const final; + int GetCachedSize() const final { return _cached_size_.Get(); } + + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const final; + void InternalSwap(UninterpretedOption_NamePart* other); + + private: + friend class ::PROTOBUF_NAMESPACE_ID::internal::AnyMetadata; + static ::PROTOBUF_NAMESPACE_ID::StringPiece FullMessageName() { + return "google.protobuf.UninterpretedOption.NamePart"; + } + protected: + explicit UninterpretedOption_NamePart(::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 ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + enum : int { + kNamePartFieldNumber = 1, + kIsExtensionFieldNumber = 2, + }; + // required string name_part = 1; + bool has_name_part() const; + private: + bool _internal_has_name_part() const; + public: + void clear_name_part(); + const TProtoStringType& name_part() const; + template <typename ArgT0 = const TProtoStringType&, typename... ArgT> + void set_name_part(ArgT0&& arg0, ArgT... args); + TProtoStringType* mutable_name_part(); + PROTOBUF_NODISCARD TProtoStringType* release_name_part(); + void set_allocated_name_part(TProtoStringType* name_part); + private: + const TProtoStringType& _internal_name_part() const; + inline PROTOBUF_ALWAYS_INLINE void _internal_set_name_part(const TProtoStringType& value); + TProtoStringType* _internal_mutable_name_part(); + public: + + // required bool is_extension = 2; + bool has_is_extension() const; + private: + bool _internal_has_is_extension() const; + public: + void clear_is_extension(); + bool is_extension() const; + void set_is_extension(bool value); + private: + bool _internal_is_extension() const; + void _internal_set_is_extension(bool value); + public: + + // @@protoc_insertion_point(class_scope:google.protobuf.UninterpretedOption.NamePart) + private: + class _Internal; + + // helper for ByteSizeLong() + size_t RequiredFieldsByteSizeFallback() const; + + template <typename T> friend class ::PROTOBUF_NAMESPACE_ID::Arena::InternalHelper; + typedef void InternalArenaConstructable_; + typedef void DestructorSkippable_; + ::PROTOBUF_NAMESPACE_ID::internal::HasBits<1> _has_bits_; + mutable ::PROTOBUF_NAMESPACE_ID::internal::CachedSize _cached_size_; + ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr name_part_; + bool is_extension_; + friend struct ::TableStruct_google_2fprotobuf_2fdescriptor_2eproto; +}; +// ------------------------------------------------------------------- + +class PROTOBUF_EXPORT UninterpretedOption final : + public ::PROTOBUF_NAMESPACE_ID::Message /* @@protoc_insertion_point(class_definition:google.protobuf.UninterpretedOption) */ { + public: + inline UninterpretedOption() : UninterpretedOption(nullptr) {} + ~UninterpretedOption() override; + explicit constexpr UninterpretedOption(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized); + + UninterpretedOption(const UninterpretedOption& from); + UninterpretedOption(UninterpretedOption&& from) noexcept + : UninterpretedOption() { + *this = ::std::move(from); + } + + inline UninterpretedOption& operator=(const UninterpretedOption& from) { + CopyFrom(from); + return *this; + } + inline UninterpretedOption& operator=(UninterpretedOption&& from) noexcept { + if (this == &from) return *this; + if (GetOwningArena() == from.GetOwningArena() + #ifdef PROTOBUF_FORCE_COPY_IN_MOVE + && GetOwningArena() != nullptr + #endif // !PROTOBUF_FORCE_COPY_IN_MOVE + ) { + InternalSwap(&from); + } else { + CopyFrom(from); + } + return *this; + } + + inline const ::PROTOBUF_NAMESPACE_ID::UnknownFieldSet& unknown_fields() const { + return _internal_metadata_.unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(::PROTOBUF_NAMESPACE_ID::UnknownFieldSet::default_instance); + } + inline ::PROTOBUF_NAMESPACE_ID::UnknownFieldSet* mutable_unknown_fields() { + return _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(); + } + + static const ::PROTOBUF_NAMESPACE_ID::Descriptor* descriptor() { + return GetDescriptor(); + } + static const ::PROTOBUF_NAMESPACE_ID::Descriptor* GetDescriptor() { + return default_instance().GetMetadata().descriptor; + } + static const ::PROTOBUF_NAMESPACE_ID::Reflection* GetReflection() { + return default_instance().GetMetadata().reflection; + } + static const UninterpretedOption& default_instance() { + return *internal_default_instance(); + } + static inline const UninterpretedOption* internal_default_instance() { + return reinterpret_cast<const UninterpretedOption*>( + &_UninterpretedOption_default_instance_); + } + static constexpr int kIndexInFileMessages = + 22; + + friend void swap(UninterpretedOption& a, UninterpretedOption& b) { + a.Swap(&b); + } + inline void Swap(UninterpretedOption* other) { + if (other == this) return; + #ifdef PROTOBUF_FORCE_COPY_IN_SWAP + if (GetOwningArena() != nullptr && + GetOwningArena() == other->GetOwningArena()) { + #else // PROTOBUF_FORCE_COPY_IN_SWAP + if (GetOwningArena() == other->GetOwningArena()) { + #endif // !PROTOBUF_FORCE_COPY_IN_SWAP + InternalSwap(other); + } else { + ::PROTOBUF_NAMESPACE_ID::internal::GenericSwap(this, other); + } + } + void UnsafeArenaSwap(UninterpretedOption* other) { + if (other == this) return; + GOOGLE_DCHECK(GetOwningArena() == other->GetOwningArena()); + InternalSwap(other); + } + + // implements Message ---------------------------------------------- + + UninterpretedOption* New(::PROTOBUF_NAMESPACE_ID::Arena* arena = nullptr) const final { + return CreateMaybeMessage<UninterpretedOption>(arena); + } + using ::PROTOBUF_NAMESPACE_ID::Message::CopyFrom; + void CopyFrom(const UninterpretedOption& from); + using ::PROTOBUF_NAMESPACE_ID::Message::MergeFrom; + void MergeFrom(const UninterpretedOption& 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; + + size_t ByteSizeLong() const final; + const char* _InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) final; + uint8_t* _InternalSerialize( + uint8_t* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const final; + int GetCachedSize() const final { return _cached_size_.Get(); } + + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const final; + void InternalSwap(UninterpretedOption* other); + + private: + friend class ::PROTOBUF_NAMESPACE_ID::internal::AnyMetadata; + static ::PROTOBUF_NAMESPACE_ID::StringPiece FullMessageName() { + return "google.protobuf.UninterpretedOption"; + } + protected: + explicit UninterpretedOption(::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 ---------------------------------------------------- + + typedef UninterpretedOption_NamePart NamePart; + + // accessors ------------------------------------------------------- + + enum : int { + kNameFieldNumber = 2, + kIdentifierValueFieldNumber = 3, + kStringValueFieldNumber = 7, + kAggregateValueFieldNumber = 8, + kPositiveIntValueFieldNumber = 4, + kNegativeIntValueFieldNumber = 5, + kDoubleValueFieldNumber = 6, + }; + // repeated .google.protobuf.UninterpretedOption.NamePart name = 2; + int name_size() const; + private: + int _internal_name_size() const; + public: + void clear_name(); + ::PROTOBUF_NAMESPACE_ID::UninterpretedOption_NamePart* mutable_name(int index); + ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::UninterpretedOption_NamePart >* + mutable_name(); + private: + const ::PROTOBUF_NAMESPACE_ID::UninterpretedOption_NamePart& _internal_name(int index) const; + ::PROTOBUF_NAMESPACE_ID::UninterpretedOption_NamePart* _internal_add_name(); + public: + const ::PROTOBUF_NAMESPACE_ID::UninterpretedOption_NamePart& name(int index) const; + ::PROTOBUF_NAMESPACE_ID::UninterpretedOption_NamePart* add_name(); + const ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::UninterpretedOption_NamePart >& + name() const; + + // optional string identifier_value = 3; + bool has_identifier_value() const; + private: + bool _internal_has_identifier_value() const; + public: + void clear_identifier_value(); + const TProtoStringType& identifier_value() const; + template <typename ArgT0 = const TProtoStringType&, typename... ArgT> + void set_identifier_value(ArgT0&& arg0, ArgT... args); + TProtoStringType* mutable_identifier_value(); + PROTOBUF_NODISCARD TProtoStringType* release_identifier_value(); + void set_allocated_identifier_value(TProtoStringType* identifier_value); + private: + const TProtoStringType& _internal_identifier_value() const; + inline PROTOBUF_ALWAYS_INLINE void _internal_set_identifier_value(const TProtoStringType& value); + TProtoStringType* _internal_mutable_identifier_value(); + public: + + // optional bytes string_value = 7; + bool has_string_value() const; + private: + bool _internal_has_string_value() const; + public: + void clear_string_value(); + const TProtoStringType& string_value() const; + template <typename ArgT0 = const TProtoStringType&, typename... ArgT> + void set_string_value(ArgT0&& arg0, ArgT... args); + TProtoStringType* mutable_string_value(); + PROTOBUF_NODISCARD TProtoStringType* release_string_value(); + void set_allocated_string_value(TProtoStringType* string_value); + private: + const TProtoStringType& _internal_string_value() const; + inline PROTOBUF_ALWAYS_INLINE void _internal_set_string_value(const TProtoStringType& value); + TProtoStringType* _internal_mutable_string_value(); + public: + + // optional string aggregate_value = 8; + bool has_aggregate_value() const; + private: + bool _internal_has_aggregate_value() const; + public: + void clear_aggregate_value(); + const TProtoStringType& aggregate_value() const; + template <typename ArgT0 = const TProtoStringType&, typename... ArgT> + void set_aggregate_value(ArgT0&& arg0, ArgT... args); + TProtoStringType* mutable_aggregate_value(); + PROTOBUF_NODISCARD TProtoStringType* release_aggregate_value(); + void set_allocated_aggregate_value(TProtoStringType* aggregate_value); + private: + const TProtoStringType& _internal_aggregate_value() const; + inline PROTOBUF_ALWAYS_INLINE void _internal_set_aggregate_value(const TProtoStringType& value); + TProtoStringType* _internal_mutable_aggregate_value(); + public: + + // optional uint64 positive_int_value = 4; + bool has_positive_int_value() const; + private: + bool _internal_has_positive_int_value() const; + public: + void clear_positive_int_value(); + arc_ui64 positive_int_value() const; + void set_positive_int_value(arc_ui64 value); + private: + arc_ui64 _internal_positive_int_value() const; + void _internal_set_positive_int_value(arc_ui64 value); + public: + + // optional int64 negative_int_value = 5; + bool has_negative_int_value() const; + private: + bool _internal_has_negative_int_value() const; + public: + void clear_negative_int_value(); + arc_i64 negative_int_value() const; + void set_negative_int_value(arc_i64 value); + private: + arc_i64 _internal_negative_int_value() const; + void _internal_set_negative_int_value(arc_i64 value); + public: + + // optional double double_value = 6; + bool has_double_value() const; + private: + bool _internal_has_double_value() const; + public: + void clear_double_value(); + double double_value() const; + void set_double_value(double value); + private: + double _internal_double_value() const; + void _internal_set_double_value(double value); + public: + + // @@protoc_insertion_point(class_scope:google.protobuf.UninterpretedOption) + private: + class _Internal; + + template <typename T> friend class ::PROTOBUF_NAMESPACE_ID::Arena::InternalHelper; + typedef void InternalArenaConstructable_; + typedef void DestructorSkippable_; + ::PROTOBUF_NAMESPACE_ID::internal::HasBits<1> _has_bits_; + mutable ::PROTOBUF_NAMESPACE_ID::internal::CachedSize _cached_size_; + ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::UninterpretedOption_NamePart > name_; + ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr identifier_value_; + ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr string_value_; + ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr aggregate_value_; + arc_ui64 positive_int_value_; + arc_i64 negative_int_value_; + double double_value_; + friend struct ::TableStruct_google_2fprotobuf_2fdescriptor_2eproto; +}; +// ------------------------------------------------------------------- + +class PROTOBUF_EXPORT SourceCodeInfo_Location final : + public ::PROTOBUF_NAMESPACE_ID::Message /* @@protoc_insertion_point(class_definition:google.protobuf.SourceCodeInfo.Location) */ { + public: + inline SourceCodeInfo_Location() : SourceCodeInfo_Location(nullptr) {} + ~SourceCodeInfo_Location() override; + explicit constexpr SourceCodeInfo_Location(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized); + + SourceCodeInfo_Location(const SourceCodeInfo_Location& from); + SourceCodeInfo_Location(SourceCodeInfo_Location&& from) noexcept + : SourceCodeInfo_Location() { + *this = ::std::move(from); + } + + inline SourceCodeInfo_Location& operator=(const SourceCodeInfo_Location& from) { + CopyFrom(from); + return *this; + } + inline SourceCodeInfo_Location& operator=(SourceCodeInfo_Location&& from) noexcept { + if (this == &from) return *this; + if (GetOwningArena() == from.GetOwningArena() + #ifdef PROTOBUF_FORCE_COPY_IN_MOVE + && GetOwningArena() != nullptr + #endif // !PROTOBUF_FORCE_COPY_IN_MOVE + ) { + InternalSwap(&from); + } else { + CopyFrom(from); + } + return *this; + } + + inline const ::PROTOBUF_NAMESPACE_ID::UnknownFieldSet& unknown_fields() const { + return _internal_metadata_.unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(::PROTOBUF_NAMESPACE_ID::UnknownFieldSet::default_instance); + } + inline ::PROTOBUF_NAMESPACE_ID::UnknownFieldSet* mutable_unknown_fields() { + return _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(); + } + + static const ::PROTOBUF_NAMESPACE_ID::Descriptor* descriptor() { + return GetDescriptor(); + } + static const ::PROTOBUF_NAMESPACE_ID::Descriptor* GetDescriptor() { + return default_instance().GetMetadata().descriptor; + } + static const ::PROTOBUF_NAMESPACE_ID::Reflection* GetReflection() { + return default_instance().GetMetadata().reflection; + } + static const SourceCodeInfo_Location& default_instance() { + return *internal_default_instance(); + } + static inline const SourceCodeInfo_Location* internal_default_instance() { + return reinterpret_cast<const SourceCodeInfo_Location*>( + &_SourceCodeInfo_Location_default_instance_); + } + static constexpr int kIndexInFileMessages = + 23; + + friend void swap(SourceCodeInfo_Location& a, SourceCodeInfo_Location& b) { + a.Swap(&b); + } + inline void Swap(SourceCodeInfo_Location* other) { + if (other == this) return; + #ifdef PROTOBUF_FORCE_COPY_IN_SWAP + if (GetOwningArena() != nullptr && + GetOwningArena() == other->GetOwningArena()) { + #else // PROTOBUF_FORCE_COPY_IN_SWAP + if (GetOwningArena() == other->GetOwningArena()) { + #endif // !PROTOBUF_FORCE_COPY_IN_SWAP + InternalSwap(other); + } else { + ::PROTOBUF_NAMESPACE_ID::internal::GenericSwap(this, other); + } + } + void UnsafeArenaSwap(SourceCodeInfo_Location* other) { + if (other == this) return; + GOOGLE_DCHECK(GetOwningArena() == other->GetOwningArena()); + InternalSwap(other); + } + + // implements Message ---------------------------------------------- + + SourceCodeInfo_Location* New(::PROTOBUF_NAMESPACE_ID::Arena* arena = nullptr) const final { + return CreateMaybeMessage<SourceCodeInfo_Location>(arena); + } + using ::PROTOBUF_NAMESPACE_ID::Message::CopyFrom; + void CopyFrom(const SourceCodeInfo_Location& from); + using ::PROTOBUF_NAMESPACE_ID::Message::MergeFrom; + void MergeFrom(const SourceCodeInfo_Location& 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; + + size_t ByteSizeLong() const final; + const char* _InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) final; + uint8_t* _InternalSerialize( + uint8_t* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const final; + int GetCachedSize() const final { return _cached_size_.Get(); } + + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const final; + void InternalSwap(SourceCodeInfo_Location* other); + + private: + friend class ::PROTOBUF_NAMESPACE_ID::internal::AnyMetadata; + static ::PROTOBUF_NAMESPACE_ID::StringPiece FullMessageName() { + return "google.protobuf.SourceCodeInfo.Location"; + } + protected: + explicit SourceCodeInfo_Location(::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 ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + enum : int { + kPathFieldNumber = 1, + kSpanFieldNumber = 2, + kLeadingDetachedCommentsFieldNumber = 6, + kLeadingCommentsFieldNumber = 3, + kTrailingCommentsFieldNumber = 4, + }; + // repeated int32 path = 1 [packed = true]; + int path_size() const; + private: + int _internal_path_size() const; + public: + void clear_path(); + private: + arc_i32 _internal_path(int index) const; + const ::PROTOBUF_NAMESPACE_ID::RepeatedField< arc_i32 >& + _internal_path() const; + void _internal_add_path(arc_i32 value); + ::PROTOBUF_NAMESPACE_ID::RepeatedField< arc_i32 >* + _internal_mutable_path(); + public: + arc_i32 path(int index) const; + void set_path(int index, arc_i32 value); + void add_path(arc_i32 value); + const ::PROTOBUF_NAMESPACE_ID::RepeatedField< arc_i32 >& + path() const; + ::PROTOBUF_NAMESPACE_ID::RepeatedField< arc_i32 >* + mutable_path(); + + // repeated int32 span = 2 [packed = true]; + int span_size() const; + private: + int _internal_span_size() const; + public: + void clear_span(); + private: + arc_i32 _internal_span(int index) const; + const ::PROTOBUF_NAMESPACE_ID::RepeatedField< arc_i32 >& + _internal_span() const; + void _internal_add_span(arc_i32 value); + ::PROTOBUF_NAMESPACE_ID::RepeatedField< arc_i32 >* + _internal_mutable_span(); + public: + arc_i32 span(int index) const; + void set_span(int index, arc_i32 value); + void add_span(arc_i32 value); + const ::PROTOBUF_NAMESPACE_ID::RepeatedField< arc_i32 >& + span() const; + ::PROTOBUF_NAMESPACE_ID::RepeatedField< arc_i32 >* + mutable_span(); + + // repeated string leading_detached_comments = 6; + int leading_detached_comments_size() const; + private: + int _internal_leading_detached_comments_size() const; + public: + void clear_leading_detached_comments(); + const TProtoStringType& leading_detached_comments(int index) const; + TProtoStringType* mutable_leading_detached_comments(int index); + void set_leading_detached_comments(int index, const TProtoStringType& value); + void set_leading_detached_comments(int index, TProtoStringType&& value); + void set_leading_detached_comments(int index, const char* value); + void set_leading_detached_comments(int index, const char* value, size_t size); + TProtoStringType* add_leading_detached_comments(); + void add_leading_detached_comments(const TProtoStringType& value); + void add_leading_detached_comments(TProtoStringType&& value); + void add_leading_detached_comments(const char* value); + void add_leading_detached_comments(const char* value, size_t size); + const ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField<TProtoStringType>& leading_detached_comments() const; + ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField<TProtoStringType>* mutable_leading_detached_comments(); + private: + const TProtoStringType& _internal_leading_detached_comments(int index) const; + TProtoStringType* _internal_add_leading_detached_comments(); + public: + + // optional string leading_comments = 3; + bool has_leading_comments() const; + private: + bool _internal_has_leading_comments() const; + public: + void clear_leading_comments(); + const TProtoStringType& leading_comments() const; + template <typename ArgT0 = const TProtoStringType&, typename... ArgT> + void set_leading_comments(ArgT0&& arg0, ArgT... args); + TProtoStringType* mutable_leading_comments(); + PROTOBUF_NODISCARD TProtoStringType* release_leading_comments(); + void set_allocated_leading_comments(TProtoStringType* leading_comments); + private: + const TProtoStringType& _internal_leading_comments() const; + inline PROTOBUF_ALWAYS_INLINE void _internal_set_leading_comments(const TProtoStringType& value); + TProtoStringType* _internal_mutable_leading_comments(); + public: + + // optional string trailing_comments = 4; + bool has_trailing_comments() const; + private: + bool _internal_has_trailing_comments() const; + public: + void clear_trailing_comments(); + const TProtoStringType& trailing_comments() const; + template <typename ArgT0 = const TProtoStringType&, typename... ArgT> + void set_trailing_comments(ArgT0&& arg0, ArgT... args); + TProtoStringType* mutable_trailing_comments(); + PROTOBUF_NODISCARD TProtoStringType* release_trailing_comments(); + void set_allocated_trailing_comments(TProtoStringType* trailing_comments); + private: + const TProtoStringType& _internal_trailing_comments() const; + inline PROTOBUF_ALWAYS_INLINE void _internal_set_trailing_comments(const TProtoStringType& value); + TProtoStringType* _internal_mutable_trailing_comments(); + public: + + // @@protoc_insertion_point(class_scope:google.protobuf.SourceCodeInfo.Location) + private: + class _Internal; + + template <typename T> friend class ::PROTOBUF_NAMESPACE_ID::Arena::InternalHelper; + typedef void InternalArenaConstructable_; + typedef void DestructorSkippable_; + ::PROTOBUF_NAMESPACE_ID::internal::HasBits<1> _has_bits_; + mutable ::PROTOBUF_NAMESPACE_ID::internal::CachedSize _cached_size_; + ::PROTOBUF_NAMESPACE_ID::RepeatedField< arc_i32 > path_; + mutable std::atomic<int> _path_cached_byte_size_; + ::PROTOBUF_NAMESPACE_ID::RepeatedField< arc_i32 > span_; + mutable std::atomic<int> _span_cached_byte_size_; + ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField<TProtoStringType> leading_detached_comments_; + ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr leading_comments_; + ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr trailing_comments_; + friend struct ::TableStruct_google_2fprotobuf_2fdescriptor_2eproto; +}; +// ------------------------------------------------------------------- + +class PROTOBUF_EXPORT SourceCodeInfo final : + public ::PROTOBUF_NAMESPACE_ID::Message /* @@protoc_insertion_point(class_definition:google.protobuf.SourceCodeInfo) */ { + public: + inline SourceCodeInfo() : SourceCodeInfo(nullptr) {} + ~SourceCodeInfo() override; + explicit constexpr SourceCodeInfo(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized); + + SourceCodeInfo(const SourceCodeInfo& from); + SourceCodeInfo(SourceCodeInfo&& from) noexcept + : SourceCodeInfo() { + *this = ::std::move(from); + } + + inline SourceCodeInfo& operator=(const SourceCodeInfo& from) { + CopyFrom(from); + return *this; + } + inline SourceCodeInfo& operator=(SourceCodeInfo&& from) noexcept { + if (this == &from) return *this; + if (GetOwningArena() == from.GetOwningArena() + #ifdef PROTOBUF_FORCE_COPY_IN_MOVE + && GetOwningArena() != nullptr + #endif // !PROTOBUF_FORCE_COPY_IN_MOVE + ) { + InternalSwap(&from); + } else { + CopyFrom(from); + } + return *this; + } + + inline const ::PROTOBUF_NAMESPACE_ID::UnknownFieldSet& unknown_fields() const { + return _internal_metadata_.unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(::PROTOBUF_NAMESPACE_ID::UnknownFieldSet::default_instance); + } + inline ::PROTOBUF_NAMESPACE_ID::UnknownFieldSet* mutable_unknown_fields() { + return _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(); + } + + static const ::PROTOBUF_NAMESPACE_ID::Descriptor* descriptor() { + return GetDescriptor(); + } + static const ::PROTOBUF_NAMESPACE_ID::Descriptor* GetDescriptor() { + return default_instance().GetMetadata().descriptor; + } + static const ::PROTOBUF_NAMESPACE_ID::Reflection* GetReflection() { + return default_instance().GetMetadata().reflection; + } + static const SourceCodeInfo& default_instance() { + return *internal_default_instance(); + } + static inline const SourceCodeInfo* internal_default_instance() { + return reinterpret_cast<const SourceCodeInfo*>( + &_SourceCodeInfo_default_instance_); + } + static constexpr int kIndexInFileMessages = + 24; + + friend void swap(SourceCodeInfo& a, SourceCodeInfo& b) { + a.Swap(&b); + } + inline void Swap(SourceCodeInfo* other) { + if (other == this) return; + #ifdef PROTOBUF_FORCE_COPY_IN_SWAP + if (GetOwningArena() != nullptr && + GetOwningArena() == other->GetOwningArena()) { + #else // PROTOBUF_FORCE_COPY_IN_SWAP + if (GetOwningArena() == other->GetOwningArena()) { + #endif // !PROTOBUF_FORCE_COPY_IN_SWAP + InternalSwap(other); + } else { + ::PROTOBUF_NAMESPACE_ID::internal::GenericSwap(this, other); + } + } + void UnsafeArenaSwap(SourceCodeInfo* other) { + if (other == this) return; + GOOGLE_DCHECK(GetOwningArena() == other->GetOwningArena()); + InternalSwap(other); + } + + // implements Message ---------------------------------------------- + + SourceCodeInfo* New(::PROTOBUF_NAMESPACE_ID::Arena* arena = nullptr) const final { + return CreateMaybeMessage<SourceCodeInfo>(arena); + } + using ::PROTOBUF_NAMESPACE_ID::Message::CopyFrom; + void CopyFrom(const SourceCodeInfo& from); + using ::PROTOBUF_NAMESPACE_ID::Message::MergeFrom; + void MergeFrom(const SourceCodeInfo& 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; + + size_t ByteSizeLong() const final; + const char* _InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) final; + uint8_t* _InternalSerialize( + uint8_t* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const final; + int GetCachedSize() const final { return _cached_size_.Get(); } + + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const final; + void InternalSwap(SourceCodeInfo* other); + + private: + friend class ::PROTOBUF_NAMESPACE_ID::internal::AnyMetadata; + static ::PROTOBUF_NAMESPACE_ID::StringPiece FullMessageName() { + return "google.protobuf.SourceCodeInfo"; + } + protected: + explicit SourceCodeInfo(::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 ---------------------------------------------------- + + typedef SourceCodeInfo_Location Location; + + // accessors ------------------------------------------------------- + + enum : int { + kLocationFieldNumber = 1, + }; + // repeated .google.protobuf.SourceCodeInfo.Location location = 1; + int location_size() const; + private: + int _internal_location_size() const; + public: + void clear_location(); + ::PROTOBUF_NAMESPACE_ID::SourceCodeInfo_Location* mutable_location(int index); + ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::SourceCodeInfo_Location >* + mutable_location(); + private: + const ::PROTOBUF_NAMESPACE_ID::SourceCodeInfo_Location& _internal_location(int index) const; + ::PROTOBUF_NAMESPACE_ID::SourceCodeInfo_Location* _internal_add_location(); + public: + const ::PROTOBUF_NAMESPACE_ID::SourceCodeInfo_Location& location(int index) const; + ::PROTOBUF_NAMESPACE_ID::SourceCodeInfo_Location* add_location(); + const ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::SourceCodeInfo_Location >& + location() const; + + // @@protoc_insertion_point(class_scope:google.protobuf.SourceCodeInfo) + private: + class _Internal; + + template <typename T> friend class ::PROTOBUF_NAMESPACE_ID::Arena::InternalHelper; + typedef void InternalArenaConstructable_; + typedef void DestructorSkippable_; + ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::SourceCodeInfo_Location > location_; + mutable ::PROTOBUF_NAMESPACE_ID::internal::CachedSize _cached_size_; + friend struct ::TableStruct_google_2fprotobuf_2fdescriptor_2eproto; +}; +// ------------------------------------------------------------------- + +class PROTOBUF_EXPORT GeneratedCodeInfo_Annotation final : + public ::PROTOBUF_NAMESPACE_ID::Message /* @@protoc_insertion_point(class_definition:google.protobuf.GeneratedCodeInfo.Annotation) */ { + public: + inline GeneratedCodeInfo_Annotation() : GeneratedCodeInfo_Annotation(nullptr) {} + ~GeneratedCodeInfo_Annotation() override; + explicit constexpr GeneratedCodeInfo_Annotation(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized); + + GeneratedCodeInfo_Annotation(const GeneratedCodeInfo_Annotation& from); + GeneratedCodeInfo_Annotation(GeneratedCodeInfo_Annotation&& from) noexcept + : GeneratedCodeInfo_Annotation() { + *this = ::std::move(from); + } + + inline GeneratedCodeInfo_Annotation& operator=(const GeneratedCodeInfo_Annotation& from) { + CopyFrom(from); + return *this; + } + inline GeneratedCodeInfo_Annotation& operator=(GeneratedCodeInfo_Annotation&& from) noexcept { + if (this == &from) return *this; + if (GetOwningArena() == from.GetOwningArena() + #ifdef PROTOBUF_FORCE_COPY_IN_MOVE + && GetOwningArena() != nullptr + #endif // !PROTOBUF_FORCE_COPY_IN_MOVE + ) { + InternalSwap(&from); + } else { + CopyFrom(from); + } + return *this; + } + + inline const ::PROTOBUF_NAMESPACE_ID::UnknownFieldSet& unknown_fields() const { + return _internal_metadata_.unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(::PROTOBUF_NAMESPACE_ID::UnknownFieldSet::default_instance); + } + inline ::PROTOBUF_NAMESPACE_ID::UnknownFieldSet* mutable_unknown_fields() { + return _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(); + } + + static const ::PROTOBUF_NAMESPACE_ID::Descriptor* descriptor() { + return GetDescriptor(); + } + static const ::PROTOBUF_NAMESPACE_ID::Descriptor* GetDescriptor() { + return default_instance().GetMetadata().descriptor; + } + static const ::PROTOBUF_NAMESPACE_ID::Reflection* GetReflection() { + return default_instance().GetMetadata().reflection; + } + static const GeneratedCodeInfo_Annotation& default_instance() { + return *internal_default_instance(); + } + static inline const GeneratedCodeInfo_Annotation* internal_default_instance() { + return reinterpret_cast<const GeneratedCodeInfo_Annotation*>( + &_GeneratedCodeInfo_Annotation_default_instance_); + } + static constexpr int kIndexInFileMessages = + 25; + + friend void swap(GeneratedCodeInfo_Annotation& a, GeneratedCodeInfo_Annotation& b) { + a.Swap(&b); + } + inline void Swap(GeneratedCodeInfo_Annotation* other) { + if (other == this) return; + #ifdef PROTOBUF_FORCE_COPY_IN_SWAP + if (GetOwningArena() != nullptr && + GetOwningArena() == other->GetOwningArena()) { + #else // PROTOBUF_FORCE_COPY_IN_SWAP + if (GetOwningArena() == other->GetOwningArena()) { + #endif // !PROTOBUF_FORCE_COPY_IN_SWAP + InternalSwap(other); + } else { + ::PROTOBUF_NAMESPACE_ID::internal::GenericSwap(this, other); + } + } + void UnsafeArenaSwap(GeneratedCodeInfo_Annotation* other) { + if (other == this) return; + GOOGLE_DCHECK(GetOwningArena() == other->GetOwningArena()); + InternalSwap(other); + } + + // implements Message ---------------------------------------------- + + GeneratedCodeInfo_Annotation* New(::PROTOBUF_NAMESPACE_ID::Arena* arena = nullptr) const final { + return CreateMaybeMessage<GeneratedCodeInfo_Annotation>(arena); + } + using ::PROTOBUF_NAMESPACE_ID::Message::CopyFrom; + void CopyFrom(const GeneratedCodeInfo_Annotation& from); + using ::PROTOBUF_NAMESPACE_ID::Message::MergeFrom; + void MergeFrom(const GeneratedCodeInfo_Annotation& 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; + + size_t ByteSizeLong() const final; + const char* _InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) final; + uint8_t* _InternalSerialize( + uint8_t* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const final; + int GetCachedSize() const final { return _cached_size_.Get(); } + + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const final; + void InternalSwap(GeneratedCodeInfo_Annotation* other); + + private: + friend class ::PROTOBUF_NAMESPACE_ID::internal::AnyMetadata; + static ::PROTOBUF_NAMESPACE_ID::StringPiece FullMessageName() { + return "google.protobuf.GeneratedCodeInfo.Annotation"; + } + protected: + explicit GeneratedCodeInfo_Annotation(::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 ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + enum : int { + kPathFieldNumber = 1, + kSourceFileFieldNumber = 2, + kBeginFieldNumber = 3, + kEndFieldNumber = 4, + }; + // repeated int32 path = 1 [packed = true]; + int path_size() const; + private: + int _internal_path_size() const; + public: + void clear_path(); + private: + arc_i32 _internal_path(int index) const; + const ::PROTOBUF_NAMESPACE_ID::RepeatedField< arc_i32 >& + _internal_path() const; + void _internal_add_path(arc_i32 value); + ::PROTOBUF_NAMESPACE_ID::RepeatedField< arc_i32 >* + _internal_mutable_path(); + public: + arc_i32 path(int index) const; + void set_path(int index, arc_i32 value); + void add_path(arc_i32 value); + const ::PROTOBUF_NAMESPACE_ID::RepeatedField< arc_i32 >& + path() const; + ::PROTOBUF_NAMESPACE_ID::RepeatedField< arc_i32 >* + mutable_path(); + + // optional string source_file = 2; + bool has_source_file() const; + private: + bool _internal_has_source_file() const; + public: + void clear_source_file(); + const TProtoStringType& source_file() const; + template <typename ArgT0 = const TProtoStringType&, typename... ArgT> + void set_source_file(ArgT0&& arg0, ArgT... args); + TProtoStringType* mutable_source_file(); + PROTOBUF_NODISCARD TProtoStringType* release_source_file(); + void set_allocated_source_file(TProtoStringType* source_file); + private: + const TProtoStringType& _internal_source_file() const; + inline PROTOBUF_ALWAYS_INLINE void _internal_set_source_file(const TProtoStringType& value); + TProtoStringType* _internal_mutable_source_file(); + public: + + // optional int32 begin = 3; + bool has_begin() const; + private: + bool _internal_has_begin() const; + public: + void clear_begin(); + arc_i32 begin() const; + void set_begin(arc_i32 value); + private: + arc_i32 _internal_begin() const; + void _internal_set_begin(arc_i32 value); + public: + + // optional int32 end = 4; + bool has_end() const; + private: + bool _internal_has_end() const; + public: + void clear_end(); + arc_i32 end() const; + void set_end(arc_i32 value); + private: + arc_i32 _internal_end() const; + void _internal_set_end(arc_i32 value); + public: + + // @@protoc_insertion_point(class_scope:google.protobuf.GeneratedCodeInfo.Annotation) + private: + class _Internal; + + template <typename T> friend class ::PROTOBUF_NAMESPACE_ID::Arena::InternalHelper; + typedef void InternalArenaConstructable_; + typedef void DestructorSkippable_; + ::PROTOBUF_NAMESPACE_ID::internal::HasBits<1> _has_bits_; + mutable ::PROTOBUF_NAMESPACE_ID::internal::CachedSize _cached_size_; + ::PROTOBUF_NAMESPACE_ID::RepeatedField< arc_i32 > path_; + mutable std::atomic<int> _path_cached_byte_size_; + ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr source_file_; + arc_i32 begin_; + arc_i32 end_; + friend struct ::TableStruct_google_2fprotobuf_2fdescriptor_2eproto; +}; +// ------------------------------------------------------------------- + +class PROTOBUF_EXPORT GeneratedCodeInfo final : + public ::PROTOBUF_NAMESPACE_ID::Message /* @@protoc_insertion_point(class_definition:google.protobuf.GeneratedCodeInfo) */ { + public: + inline GeneratedCodeInfo() : GeneratedCodeInfo(nullptr) {} + ~GeneratedCodeInfo() override; + explicit constexpr GeneratedCodeInfo(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized); + + GeneratedCodeInfo(const GeneratedCodeInfo& from); + GeneratedCodeInfo(GeneratedCodeInfo&& from) noexcept + : GeneratedCodeInfo() { + *this = ::std::move(from); + } + + inline GeneratedCodeInfo& operator=(const GeneratedCodeInfo& from) { + CopyFrom(from); + return *this; + } + inline GeneratedCodeInfo& operator=(GeneratedCodeInfo&& from) noexcept { + if (this == &from) return *this; + if (GetOwningArena() == from.GetOwningArena() + #ifdef PROTOBUF_FORCE_COPY_IN_MOVE + && GetOwningArena() != nullptr + #endif // !PROTOBUF_FORCE_COPY_IN_MOVE + ) { + InternalSwap(&from); + } else { + CopyFrom(from); + } + return *this; + } + + inline const ::PROTOBUF_NAMESPACE_ID::UnknownFieldSet& unknown_fields() const { + return _internal_metadata_.unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(::PROTOBUF_NAMESPACE_ID::UnknownFieldSet::default_instance); + } + inline ::PROTOBUF_NAMESPACE_ID::UnknownFieldSet* mutable_unknown_fields() { + return _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(); + } + + static const ::PROTOBUF_NAMESPACE_ID::Descriptor* descriptor() { + return GetDescriptor(); + } + static const ::PROTOBUF_NAMESPACE_ID::Descriptor* GetDescriptor() { + return default_instance().GetMetadata().descriptor; + } + static const ::PROTOBUF_NAMESPACE_ID::Reflection* GetReflection() { + return default_instance().GetMetadata().reflection; + } + static const GeneratedCodeInfo& default_instance() { + return *internal_default_instance(); + } + static inline const GeneratedCodeInfo* internal_default_instance() { + return reinterpret_cast<const GeneratedCodeInfo*>( + &_GeneratedCodeInfo_default_instance_); + } + static constexpr int kIndexInFileMessages = + 26; + + friend void swap(GeneratedCodeInfo& a, GeneratedCodeInfo& b) { + a.Swap(&b); + } + inline void Swap(GeneratedCodeInfo* other) { + if (other == this) return; + #ifdef PROTOBUF_FORCE_COPY_IN_SWAP + if (GetOwningArena() != nullptr && + GetOwningArena() == other->GetOwningArena()) { + #else // PROTOBUF_FORCE_COPY_IN_SWAP + if (GetOwningArena() == other->GetOwningArena()) { + #endif // !PROTOBUF_FORCE_COPY_IN_SWAP + InternalSwap(other); + } else { + ::PROTOBUF_NAMESPACE_ID::internal::GenericSwap(this, other); + } + } + void UnsafeArenaSwap(GeneratedCodeInfo* other) { + if (other == this) return; + GOOGLE_DCHECK(GetOwningArena() == other->GetOwningArena()); + InternalSwap(other); + } + + // implements Message ---------------------------------------------- + + GeneratedCodeInfo* New(::PROTOBUF_NAMESPACE_ID::Arena* arena = nullptr) const final { + return CreateMaybeMessage<GeneratedCodeInfo>(arena); + } + using ::PROTOBUF_NAMESPACE_ID::Message::CopyFrom; + void CopyFrom(const GeneratedCodeInfo& from); + using ::PROTOBUF_NAMESPACE_ID::Message::MergeFrom; + void MergeFrom(const GeneratedCodeInfo& 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; + + size_t ByteSizeLong() const final; + const char* _InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) final; + uint8_t* _InternalSerialize( + uint8_t* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const final; + int GetCachedSize() const final { return _cached_size_.Get(); } + + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const final; + void InternalSwap(GeneratedCodeInfo* other); + + private: + friend class ::PROTOBUF_NAMESPACE_ID::internal::AnyMetadata; + static ::PROTOBUF_NAMESPACE_ID::StringPiece FullMessageName() { + return "google.protobuf.GeneratedCodeInfo"; + } + protected: + explicit GeneratedCodeInfo(::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 ---------------------------------------------------- + + typedef GeneratedCodeInfo_Annotation Annotation; + + // accessors ------------------------------------------------------- + + enum : int { + kAnnotationFieldNumber = 1, + }; + // repeated .google.protobuf.GeneratedCodeInfo.Annotation annotation = 1; + int annotation_size() const; + private: + int _internal_annotation_size() const; + public: + void clear_annotation(); + ::PROTOBUF_NAMESPACE_ID::GeneratedCodeInfo_Annotation* mutable_annotation(int index); + ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::GeneratedCodeInfo_Annotation >* + mutable_annotation(); + private: + const ::PROTOBUF_NAMESPACE_ID::GeneratedCodeInfo_Annotation& _internal_annotation(int index) const; + ::PROTOBUF_NAMESPACE_ID::GeneratedCodeInfo_Annotation* _internal_add_annotation(); + public: + const ::PROTOBUF_NAMESPACE_ID::GeneratedCodeInfo_Annotation& annotation(int index) const; + ::PROTOBUF_NAMESPACE_ID::GeneratedCodeInfo_Annotation* add_annotation(); + const ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::GeneratedCodeInfo_Annotation >& + annotation() const; + + // @@protoc_insertion_point(class_scope:google.protobuf.GeneratedCodeInfo) + private: + class _Internal; + + template <typename T> friend class ::PROTOBUF_NAMESPACE_ID::Arena::InternalHelper; + typedef void InternalArenaConstructable_; + typedef void DestructorSkippable_; + ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::GeneratedCodeInfo_Annotation > annotation_; + mutable ::PROTOBUF_NAMESPACE_ID::internal::CachedSize _cached_size_; + friend struct ::TableStruct_google_2fprotobuf_2fdescriptor_2eproto; +}; +// =================================================================== + + +// =================================================================== + +#ifdef __GNUC__ + #pragma GCC diagnostic push + #pragma GCC diagnostic ignored "-Wstrict-aliasing" +#endif // __GNUC__ +// FileDescriptorSet + +// repeated .google.protobuf.FileDescriptorProto file = 1; +inline int FileDescriptorSet::_internal_file_size() const { + return file_.size(); +} +inline int FileDescriptorSet::file_size() const { + return _internal_file_size(); +} +inline void FileDescriptorSet::clear_file() { + file_.Clear(); +} +inline ::PROTOBUF_NAMESPACE_ID::FileDescriptorProto* FileDescriptorSet::mutable_file(int index) { + // @@protoc_insertion_point(field_mutable:google.protobuf.FileDescriptorSet.file) + return file_.Mutable(index); +} +inline ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::FileDescriptorProto >* +FileDescriptorSet::mutable_file() { + // @@protoc_insertion_point(field_mutable_list:google.protobuf.FileDescriptorSet.file) + return &file_; +} +inline const ::PROTOBUF_NAMESPACE_ID::FileDescriptorProto& FileDescriptorSet::_internal_file(int index) const { + return file_.Get(index); +} +inline const ::PROTOBUF_NAMESPACE_ID::FileDescriptorProto& FileDescriptorSet::file(int index) const { + // @@protoc_insertion_point(field_get:google.protobuf.FileDescriptorSet.file) + return _internal_file(index); +} +inline ::PROTOBUF_NAMESPACE_ID::FileDescriptorProto* FileDescriptorSet::_internal_add_file() { + return file_.Add(); +} +inline ::PROTOBUF_NAMESPACE_ID::FileDescriptorProto* FileDescriptorSet::add_file() { + ::PROTOBUF_NAMESPACE_ID::FileDescriptorProto* _add = _internal_add_file(); + // @@protoc_insertion_point(field_add:google.protobuf.FileDescriptorSet.file) + return _add; +} +inline const ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::FileDescriptorProto >& +FileDescriptorSet::file() const { + // @@protoc_insertion_point(field_list:google.protobuf.FileDescriptorSet.file) + return file_; +} + +// ------------------------------------------------------------------- + +// FileDescriptorProto + +// optional string name = 1; +inline bool FileDescriptorProto::_internal_has_name() const { + bool value = (_has_bits_[0] & 0x00000001u) != 0; + return value; +} +inline bool FileDescriptorProto::has_name() const { + return _internal_has_name(); +} +inline void FileDescriptorProto::clear_name() { + name_.ClearToEmpty(); + _has_bits_[0] &= ~0x00000001u; +} +inline const TProtoStringType& FileDescriptorProto::name() const { + // @@protoc_insertion_point(field_get:google.protobuf.FileDescriptorProto.name) + return _internal_name(); +} +template <typename ArgT0, typename... ArgT> +inline PROTOBUF_ALWAYS_INLINE +void FileDescriptorProto::set_name(ArgT0&& arg0, ArgT... args) { + _has_bits_[0] |= 0x00000001u; + name_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, static_cast<ArgT0 &&>(arg0), args..., GetArenaForAllocation()); + // @@protoc_insertion_point(field_set:google.protobuf.FileDescriptorProto.name) +} +inline TProtoStringType* FileDescriptorProto::mutable_name() { + TProtoStringType* _s = _internal_mutable_name(); + // @@protoc_insertion_point(field_mutable:google.protobuf.FileDescriptorProto.name) + return _s; +} +inline const TProtoStringType& FileDescriptorProto::_internal_name() const { + return name_.Get(); +} +inline void FileDescriptorProto::_internal_set_name(const TProtoStringType& value) { + _has_bits_[0] |= 0x00000001u; + name_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, value, GetArenaForAllocation()); +} +inline TProtoStringType* FileDescriptorProto::_internal_mutable_name() { + _has_bits_[0] |= 0x00000001u; + return name_.Mutable(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, GetArenaForAllocation()); +} +inline TProtoStringType* FileDescriptorProto::release_name() { + // @@protoc_insertion_point(field_release:google.protobuf.FileDescriptorProto.name) + if (!_internal_has_name()) { + return nullptr; + } + _has_bits_[0] &= ~0x00000001u; + auto* p = name_.ReleaseNonDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArenaForAllocation()); +#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING + if (name_.IsDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited())) { + name_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation()); + } +#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING + return p; +} +inline void FileDescriptorProto::set_allocated_name(TProtoStringType* name) { + if (name != nullptr) { + _has_bits_[0] |= 0x00000001u; + } else { + _has_bits_[0] &= ~0x00000001u; + } + name_.SetAllocated(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), name, + GetArenaForAllocation()); +#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING + if (name_.IsDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited())) { + name_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation()); + } +#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING + // @@protoc_insertion_point(field_set_allocated:google.protobuf.FileDescriptorProto.name) +} + +// optional string package = 2; +inline bool FileDescriptorProto::_internal_has_package() const { + bool value = (_has_bits_[0] & 0x00000002u) != 0; + return value; +} +inline bool FileDescriptorProto::has_package() const { + return _internal_has_package(); +} +inline void FileDescriptorProto::clear_package() { + package_.ClearToEmpty(); + _has_bits_[0] &= ~0x00000002u; +} +inline const TProtoStringType& FileDescriptorProto::package() const { + // @@protoc_insertion_point(field_get:google.protobuf.FileDescriptorProto.package) + return _internal_package(); +} +template <typename ArgT0, typename... ArgT> +inline PROTOBUF_ALWAYS_INLINE +void FileDescriptorProto::set_package(ArgT0&& arg0, ArgT... args) { + _has_bits_[0] |= 0x00000002u; + package_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, static_cast<ArgT0 &&>(arg0), args..., GetArenaForAllocation()); + // @@protoc_insertion_point(field_set:google.protobuf.FileDescriptorProto.package) +} +inline TProtoStringType* FileDescriptorProto::mutable_package() { + TProtoStringType* _s = _internal_mutable_package(); + // @@protoc_insertion_point(field_mutable:google.protobuf.FileDescriptorProto.package) + return _s; +} +inline const TProtoStringType& FileDescriptorProto::_internal_package() const { + return package_.Get(); +} +inline void FileDescriptorProto::_internal_set_package(const TProtoStringType& value) { + _has_bits_[0] |= 0x00000002u; + package_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, value, GetArenaForAllocation()); +} +inline TProtoStringType* FileDescriptorProto::_internal_mutable_package() { + _has_bits_[0] |= 0x00000002u; + return package_.Mutable(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, GetArenaForAllocation()); +} +inline TProtoStringType* FileDescriptorProto::release_package() { + // @@protoc_insertion_point(field_release:google.protobuf.FileDescriptorProto.package) + if (!_internal_has_package()) { + return nullptr; + } + _has_bits_[0] &= ~0x00000002u; + auto* p = package_.ReleaseNonDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArenaForAllocation()); +#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING + if (package_.IsDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited())) { + package_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation()); + } +#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING + return p; +} +inline void FileDescriptorProto::set_allocated_package(TProtoStringType* package) { + if (package != nullptr) { + _has_bits_[0] |= 0x00000002u; + } else { + _has_bits_[0] &= ~0x00000002u; + } + package_.SetAllocated(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), package, + GetArenaForAllocation()); +#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING + if (package_.IsDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited())) { + package_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation()); + } +#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING + // @@protoc_insertion_point(field_set_allocated:google.protobuf.FileDescriptorProto.package) +} + +// repeated string dependency = 3; +inline int FileDescriptorProto::_internal_dependency_size() const { + return dependency_.size(); +} +inline int FileDescriptorProto::dependency_size() const { + return _internal_dependency_size(); +} +inline void FileDescriptorProto::clear_dependency() { + dependency_.Clear(); +} +inline TProtoStringType* FileDescriptorProto::add_dependency() { + TProtoStringType* _s = _internal_add_dependency(); + // @@protoc_insertion_point(field_add_mutable:google.protobuf.FileDescriptorProto.dependency) + return _s; +} +inline const TProtoStringType& FileDescriptorProto::_internal_dependency(int index) const { + return dependency_.Get(index); +} +inline const TProtoStringType& FileDescriptorProto::dependency(int index) const { + // @@protoc_insertion_point(field_get:google.protobuf.FileDescriptorProto.dependency) + return _internal_dependency(index); +} +inline TProtoStringType* FileDescriptorProto::mutable_dependency(int index) { + // @@protoc_insertion_point(field_mutable:google.protobuf.FileDescriptorProto.dependency) + return dependency_.Mutable(index); +} +inline void FileDescriptorProto::set_dependency(int index, const TProtoStringType& value) { + dependency_.Mutable(index)->assign(value); + // @@protoc_insertion_point(field_set:google.protobuf.FileDescriptorProto.dependency) +} +inline void FileDescriptorProto::set_dependency(int index, TProtoStringType&& value) { + dependency_.Mutable(index)->assign(std::move(value)); + // @@protoc_insertion_point(field_set:google.protobuf.FileDescriptorProto.dependency) +} +inline void FileDescriptorProto::set_dependency(int index, const char* value) { + GOOGLE_DCHECK(value != nullptr); + dependency_.Mutable(index)->assign(value); + // @@protoc_insertion_point(field_set_char:google.protobuf.FileDescriptorProto.dependency) +} +inline void FileDescriptorProto::set_dependency(int index, const char* value, size_t size) { + dependency_.Mutable(index)->assign( + reinterpret_cast<const char*>(value), size); + // @@protoc_insertion_point(field_set_pointer:google.protobuf.FileDescriptorProto.dependency) +} +inline TProtoStringType* FileDescriptorProto::_internal_add_dependency() { + return dependency_.Add(); +} +inline void FileDescriptorProto::add_dependency(const TProtoStringType& value) { + dependency_.Add()->assign(value); + // @@protoc_insertion_point(field_add:google.protobuf.FileDescriptorProto.dependency) +} +inline void FileDescriptorProto::add_dependency(TProtoStringType&& value) { + dependency_.Add(std::move(value)); + // @@protoc_insertion_point(field_add:google.protobuf.FileDescriptorProto.dependency) +} +inline void FileDescriptorProto::add_dependency(const char* value) { + GOOGLE_DCHECK(value != nullptr); + dependency_.Add()->assign(value); + // @@protoc_insertion_point(field_add_char:google.protobuf.FileDescriptorProto.dependency) +} +inline void FileDescriptorProto::add_dependency(const char* value, size_t size) { + dependency_.Add()->assign(reinterpret_cast<const char*>(value), size); + // @@protoc_insertion_point(field_add_pointer:google.protobuf.FileDescriptorProto.dependency) +} +inline const ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField<TProtoStringType>& +FileDescriptorProto::dependency() const { + // @@protoc_insertion_point(field_list:google.protobuf.FileDescriptorProto.dependency) + return dependency_; +} +inline ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField<TProtoStringType>* +FileDescriptorProto::mutable_dependency() { + // @@protoc_insertion_point(field_mutable_list:google.protobuf.FileDescriptorProto.dependency) + return &dependency_; +} + +// repeated int32 public_dependency = 10; +inline int FileDescriptorProto::_internal_public_dependency_size() const { + return public_dependency_.size(); +} +inline int FileDescriptorProto::public_dependency_size() const { + return _internal_public_dependency_size(); +} +inline void FileDescriptorProto::clear_public_dependency() { + public_dependency_.Clear(); +} +inline arc_i32 FileDescriptorProto::_internal_public_dependency(int index) const { + return public_dependency_.Get(index); +} +inline arc_i32 FileDescriptorProto::public_dependency(int index) const { + // @@protoc_insertion_point(field_get:google.protobuf.FileDescriptorProto.public_dependency) + return _internal_public_dependency(index); +} +inline void FileDescriptorProto::set_public_dependency(int index, arc_i32 value) { + public_dependency_.Set(index, value); + // @@protoc_insertion_point(field_set:google.protobuf.FileDescriptorProto.public_dependency) +} +inline void FileDescriptorProto::_internal_add_public_dependency(arc_i32 value) { + public_dependency_.Add(value); +} +inline void FileDescriptorProto::add_public_dependency(arc_i32 value) { + _internal_add_public_dependency(value); + // @@protoc_insertion_point(field_add:google.protobuf.FileDescriptorProto.public_dependency) +} +inline const ::PROTOBUF_NAMESPACE_ID::RepeatedField< arc_i32 >& +FileDescriptorProto::_internal_public_dependency() const { + return public_dependency_; +} +inline const ::PROTOBUF_NAMESPACE_ID::RepeatedField< arc_i32 >& +FileDescriptorProto::public_dependency() const { + // @@protoc_insertion_point(field_list:google.protobuf.FileDescriptorProto.public_dependency) + return _internal_public_dependency(); +} +inline ::PROTOBUF_NAMESPACE_ID::RepeatedField< arc_i32 >* +FileDescriptorProto::_internal_mutable_public_dependency() { + return &public_dependency_; +} +inline ::PROTOBUF_NAMESPACE_ID::RepeatedField< arc_i32 >* +FileDescriptorProto::mutable_public_dependency() { + // @@protoc_insertion_point(field_mutable_list:google.protobuf.FileDescriptorProto.public_dependency) + return _internal_mutable_public_dependency(); +} + +// repeated int32 weak_dependency = 11; +inline int FileDescriptorProto::_internal_weak_dependency_size() const { + return weak_dependency_.size(); +} +inline int FileDescriptorProto::weak_dependency_size() const { + return _internal_weak_dependency_size(); +} +inline void FileDescriptorProto::clear_weak_dependency() { + weak_dependency_.Clear(); +} +inline arc_i32 FileDescriptorProto::_internal_weak_dependency(int index) const { + return weak_dependency_.Get(index); +} +inline arc_i32 FileDescriptorProto::weak_dependency(int index) const { + // @@protoc_insertion_point(field_get:google.protobuf.FileDescriptorProto.weak_dependency) + return _internal_weak_dependency(index); +} +inline void FileDescriptorProto::set_weak_dependency(int index, arc_i32 value) { + weak_dependency_.Set(index, value); + // @@protoc_insertion_point(field_set:google.protobuf.FileDescriptorProto.weak_dependency) +} +inline void FileDescriptorProto::_internal_add_weak_dependency(arc_i32 value) { + weak_dependency_.Add(value); +} +inline void FileDescriptorProto::add_weak_dependency(arc_i32 value) { + _internal_add_weak_dependency(value); + // @@protoc_insertion_point(field_add:google.protobuf.FileDescriptorProto.weak_dependency) +} +inline const ::PROTOBUF_NAMESPACE_ID::RepeatedField< arc_i32 >& +FileDescriptorProto::_internal_weak_dependency() const { + return weak_dependency_; +} +inline const ::PROTOBUF_NAMESPACE_ID::RepeatedField< arc_i32 >& +FileDescriptorProto::weak_dependency() const { + // @@protoc_insertion_point(field_list:google.protobuf.FileDescriptorProto.weak_dependency) + return _internal_weak_dependency(); +} +inline ::PROTOBUF_NAMESPACE_ID::RepeatedField< arc_i32 >* +FileDescriptorProto::_internal_mutable_weak_dependency() { + return &weak_dependency_; +} +inline ::PROTOBUF_NAMESPACE_ID::RepeatedField< arc_i32 >* +FileDescriptorProto::mutable_weak_dependency() { + // @@protoc_insertion_point(field_mutable_list:google.protobuf.FileDescriptorProto.weak_dependency) + return _internal_mutable_weak_dependency(); +} + +// repeated .google.protobuf.DescriptorProto message_type = 4; +inline int FileDescriptorProto::_internal_message_type_size() const { + return message_type_.size(); +} +inline int FileDescriptorProto::message_type_size() const { + return _internal_message_type_size(); +} +inline void FileDescriptorProto::clear_message_type() { + message_type_.Clear(); +} +inline ::PROTOBUF_NAMESPACE_ID::DescriptorProto* FileDescriptorProto::mutable_message_type(int index) { + // @@protoc_insertion_point(field_mutable:google.protobuf.FileDescriptorProto.message_type) + return message_type_.Mutable(index); +} +inline ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::DescriptorProto >* +FileDescriptorProto::mutable_message_type() { + // @@protoc_insertion_point(field_mutable_list:google.protobuf.FileDescriptorProto.message_type) + return &message_type_; +} +inline const ::PROTOBUF_NAMESPACE_ID::DescriptorProto& FileDescriptorProto::_internal_message_type(int index) const { + return message_type_.Get(index); +} +inline const ::PROTOBUF_NAMESPACE_ID::DescriptorProto& FileDescriptorProto::message_type(int index) const { + // @@protoc_insertion_point(field_get:google.protobuf.FileDescriptorProto.message_type) + return _internal_message_type(index); +} +inline ::PROTOBUF_NAMESPACE_ID::DescriptorProto* FileDescriptorProto::_internal_add_message_type() { + return message_type_.Add(); +} +inline ::PROTOBUF_NAMESPACE_ID::DescriptorProto* FileDescriptorProto::add_message_type() { + ::PROTOBUF_NAMESPACE_ID::DescriptorProto* _add = _internal_add_message_type(); + // @@protoc_insertion_point(field_add:google.protobuf.FileDescriptorProto.message_type) + return _add; +} +inline const ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::DescriptorProto >& +FileDescriptorProto::message_type() const { + // @@protoc_insertion_point(field_list:google.protobuf.FileDescriptorProto.message_type) + return message_type_; +} + +// repeated .google.protobuf.EnumDescriptorProto enum_type = 5; +inline int FileDescriptorProto::_internal_enum_type_size() const { + return enum_type_.size(); +} +inline int FileDescriptorProto::enum_type_size() const { + return _internal_enum_type_size(); +} +inline void FileDescriptorProto::clear_enum_type() { + enum_type_.Clear(); +} +inline ::PROTOBUF_NAMESPACE_ID::EnumDescriptorProto* FileDescriptorProto::mutable_enum_type(int index) { + // @@protoc_insertion_point(field_mutable:google.protobuf.FileDescriptorProto.enum_type) + return enum_type_.Mutable(index); +} +inline ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::EnumDescriptorProto >* +FileDescriptorProto::mutable_enum_type() { + // @@protoc_insertion_point(field_mutable_list:google.protobuf.FileDescriptorProto.enum_type) + return &enum_type_; +} +inline const ::PROTOBUF_NAMESPACE_ID::EnumDescriptorProto& FileDescriptorProto::_internal_enum_type(int index) const { + return enum_type_.Get(index); +} +inline const ::PROTOBUF_NAMESPACE_ID::EnumDescriptorProto& FileDescriptorProto::enum_type(int index) const { + // @@protoc_insertion_point(field_get:google.protobuf.FileDescriptorProto.enum_type) + return _internal_enum_type(index); +} +inline ::PROTOBUF_NAMESPACE_ID::EnumDescriptorProto* FileDescriptorProto::_internal_add_enum_type() { + return enum_type_.Add(); +} +inline ::PROTOBUF_NAMESPACE_ID::EnumDescriptorProto* FileDescriptorProto::add_enum_type() { + ::PROTOBUF_NAMESPACE_ID::EnumDescriptorProto* _add = _internal_add_enum_type(); + // @@protoc_insertion_point(field_add:google.protobuf.FileDescriptorProto.enum_type) + return _add; +} +inline const ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::EnumDescriptorProto >& +FileDescriptorProto::enum_type() const { + // @@protoc_insertion_point(field_list:google.protobuf.FileDescriptorProto.enum_type) + return enum_type_; +} + +// repeated .google.protobuf.ServiceDescriptorProto service = 6; +inline int FileDescriptorProto::_internal_service_size() const { + return service_.size(); +} +inline int FileDescriptorProto::service_size() const { + return _internal_service_size(); +} +inline void FileDescriptorProto::clear_service() { + service_.Clear(); +} +inline ::PROTOBUF_NAMESPACE_ID::ServiceDescriptorProto* FileDescriptorProto::mutable_service(int index) { + // @@protoc_insertion_point(field_mutable:google.protobuf.FileDescriptorProto.service) + return service_.Mutable(index); +} +inline ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::ServiceDescriptorProto >* +FileDescriptorProto::mutable_service() { + // @@protoc_insertion_point(field_mutable_list:google.protobuf.FileDescriptorProto.service) + return &service_; +} +inline const ::PROTOBUF_NAMESPACE_ID::ServiceDescriptorProto& FileDescriptorProto::_internal_service(int index) const { + return service_.Get(index); +} +inline const ::PROTOBUF_NAMESPACE_ID::ServiceDescriptorProto& FileDescriptorProto::service(int index) const { + // @@protoc_insertion_point(field_get:google.protobuf.FileDescriptorProto.service) + return _internal_service(index); +} +inline ::PROTOBUF_NAMESPACE_ID::ServiceDescriptorProto* FileDescriptorProto::_internal_add_service() { + return service_.Add(); +} +inline ::PROTOBUF_NAMESPACE_ID::ServiceDescriptorProto* FileDescriptorProto::add_service() { + ::PROTOBUF_NAMESPACE_ID::ServiceDescriptorProto* _add = _internal_add_service(); + // @@protoc_insertion_point(field_add:google.protobuf.FileDescriptorProto.service) + return _add; +} +inline const ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::ServiceDescriptorProto >& +FileDescriptorProto::service() const { + // @@protoc_insertion_point(field_list:google.protobuf.FileDescriptorProto.service) + return service_; +} + +// repeated .google.protobuf.FieldDescriptorProto extension = 7; +inline int FileDescriptorProto::_internal_extension_size() const { + return extension_.size(); +} +inline int FileDescriptorProto::extension_size() const { + return _internal_extension_size(); +} +inline void FileDescriptorProto::clear_extension() { + extension_.Clear(); +} +inline ::PROTOBUF_NAMESPACE_ID::FieldDescriptorProto* FileDescriptorProto::mutable_extension(int index) { + // @@protoc_insertion_point(field_mutable:google.protobuf.FileDescriptorProto.extension) + return extension_.Mutable(index); +} +inline ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::FieldDescriptorProto >* +FileDescriptorProto::mutable_extension() { + // @@protoc_insertion_point(field_mutable_list:google.protobuf.FileDescriptorProto.extension) + return &extension_; +} +inline const ::PROTOBUF_NAMESPACE_ID::FieldDescriptorProto& FileDescriptorProto::_internal_extension(int index) const { + return extension_.Get(index); +} +inline const ::PROTOBUF_NAMESPACE_ID::FieldDescriptorProto& FileDescriptorProto::extension(int index) const { + // @@protoc_insertion_point(field_get:google.protobuf.FileDescriptorProto.extension) + return _internal_extension(index); +} +inline ::PROTOBUF_NAMESPACE_ID::FieldDescriptorProto* FileDescriptorProto::_internal_add_extension() { + return extension_.Add(); +} +inline ::PROTOBUF_NAMESPACE_ID::FieldDescriptorProto* FileDescriptorProto::add_extension() { + ::PROTOBUF_NAMESPACE_ID::FieldDescriptorProto* _add = _internal_add_extension(); + // @@protoc_insertion_point(field_add:google.protobuf.FileDescriptorProto.extension) + return _add; +} +inline const ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::FieldDescriptorProto >& +FileDescriptorProto::extension() const { + // @@protoc_insertion_point(field_list:google.protobuf.FileDescriptorProto.extension) + return extension_; +} + +// optional .google.protobuf.FileOptions options = 8; +inline bool FileDescriptorProto::_internal_has_options() const { + bool value = (_has_bits_[0] & 0x00000008u) != 0; + PROTOBUF_ASSUME(!value || options_ != nullptr); + return value; +} +inline bool FileDescriptorProto::has_options() const { + return _internal_has_options(); +} +inline void FileDescriptorProto::clear_options() { + if (options_ != nullptr) options_->Clear(); + _has_bits_[0] &= ~0x00000008u; +} +inline const ::PROTOBUF_NAMESPACE_ID::FileOptions& FileDescriptorProto::_internal_options() const { + const ::PROTOBUF_NAMESPACE_ID::FileOptions* p = options_; + return p != nullptr ? *p : reinterpret_cast<const ::PROTOBUF_NAMESPACE_ID::FileOptions&>( + ::PROTOBUF_NAMESPACE_ID::_FileOptions_default_instance_); +} +inline const ::PROTOBUF_NAMESPACE_ID::FileOptions& FileDescriptorProto::options() const { + // @@protoc_insertion_point(field_get:google.protobuf.FileDescriptorProto.options) + return _internal_options(); +} +inline void FileDescriptorProto::unsafe_arena_set_allocated_options( + ::PROTOBUF_NAMESPACE_ID::FileOptions* options) { + if (GetArenaForAllocation() == nullptr) { + delete reinterpret_cast<::PROTOBUF_NAMESPACE_ID::MessageLite*>(options_); + } + options_ = options; + if (options) { + _has_bits_[0] |= 0x00000008u; + } else { + _has_bits_[0] &= ~0x00000008u; + } + // @@protoc_insertion_point(field_unsafe_arena_set_allocated:google.protobuf.FileDescriptorProto.options) +} +inline ::PROTOBUF_NAMESPACE_ID::FileOptions* FileDescriptorProto::release_options() { + _has_bits_[0] &= ~0x00000008u; + ::PROTOBUF_NAMESPACE_ID::FileOptions* temp = options_; + options_ = nullptr; +#ifdef PROTOBUF_FORCE_COPY_IN_RELEASE + auto* old = reinterpret_cast<::PROTOBUF_NAMESPACE_ID::MessageLite*>(temp); + temp = ::PROTOBUF_NAMESPACE_ID::internal::DuplicateIfNonNull(temp); + if (GetArenaForAllocation() == nullptr) { delete old; } +#else // PROTOBUF_FORCE_COPY_IN_RELEASE + if (GetArenaForAllocation() != nullptr) { + temp = ::PROTOBUF_NAMESPACE_ID::internal::DuplicateIfNonNull(temp); + } +#endif // !PROTOBUF_FORCE_COPY_IN_RELEASE + return temp; +} +inline ::PROTOBUF_NAMESPACE_ID::FileOptions* FileDescriptorProto::unsafe_arena_release_options() { + // @@protoc_insertion_point(field_release:google.protobuf.FileDescriptorProto.options) + _has_bits_[0] &= ~0x00000008u; + ::PROTOBUF_NAMESPACE_ID::FileOptions* temp = options_; + options_ = nullptr; + return temp; +} +inline ::PROTOBUF_NAMESPACE_ID::FileOptions* FileDescriptorProto::_internal_mutable_options() { + _has_bits_[0] |= 0x00000008u; + if (options_ == nullptr) { + auto* p = CreateMaybeMessage<::PROTOBUF_NAMESPACE_ID::FileOptions>(GetArenaForAllocation()); + options_ = p; + } + return options_; +} +inline ::PROTOBUF_NAMESPACE_ID::FileOptions* FileDescriptorProto::mutable_options() { + ::PROTOBUF_NAMESPACE_ID::FileOptions* _msg = _internal_mutable_options(); + // @@protoc_insertion_point(field_mutable:google.protobuf.FileDescriptorProto.options) + return _msg; +} +inline void FileDescriptorProto::set_allocated_options(::PROTOBUF_NAMESPACE_ID::FileOptions* options) { + ::PROTOBUF_NAMESPACE_ID::Arena* message_arena = GetArenaForAllocation(); + if (message_arena == nullptr) { + delete options_; + } + if (options) { + ::PROTOBUF_NAMESPACE_ID::Arena* submessage_arena = + ::PROTOBUF_NAMESPACE_ID::Arena::InternalHelper<::PROTOBUF_NAMESPACE_ID::FileOptions>::GetOwningArena(options); + if (message_arena != submessage_arena) { + options = ::PROTOBUF_NAMESPACE_ID::internal::GetOwnedMessage( + message_arena, options, submessage_arena); + } + _has_bits_[0] |= 0x00000008u; + } else { + _has_bits_[0] &= ~0x00000008u; + } + options_ = options; + // @@protoc_insertion_point(field_set_allocated:google.protobuf.FileDescriptorProto.options) +} + +// optional .google.protobuf.SourceCodeInfo source_code_info = 9; +inline bool FileDescriptorProto::_internal_has_source_code_info() const { + bool value = (_has_bits_[0] & 0x00000010u) != 0; + PROTOBUF_ASSUME(!value || source_code_info_ != nullptr); + return value; +} +inline bool FileDescriptorProto::has_source_code_info() const { + return _internal_has_source_code_info(); +} +inline void FileDescriptorProto::clear_source_code_info() { + if (source_code_info_ != nullptr) source_code_info_->Clear(); + _has_bits_[0] &= ~0x00000010u; +} +inline const ::PROTOBUF_NAMESPACE_ID::SourceCodeInfo& FileDescriptorProto::_internal_source_code_info() const { + const ::PROTOBUF_NAMESPACE_ID::SourceCodeInfo* p = source_code_info_; + return p != nullptr ? *p : reinterpret_cast<const ::PROTOBUF_NAMESPACE_ID::SourceCodeInfo&>( + ::PROTOBUF_NAMESPACE_ID::_SourceCodeInfo_default_instance_); +} +inline const ::PROTOBUF_NAMESPACE_ID::SourceCodeInfo& FileDescriptorProto::source_code_info() const { + // @@protoc_insertion_point(field_get:google.protobuf.FileDescriptorProto.source_code_info) + return _internal_source_code_info(); +} +inline void FileDescriptorProto::unsafe_arena_set_allocated_source_code_info( + ::PROTOBUF_NAMESPACE_ID::SourceCodeInfo* source_code_info) { + if (GetArenaForAllocation() == nullptr) { + delete reinterpret_cast<::PROTOBUF_NAMESPACE_ID::MessageLite*>(source_code_info_); + } + source_code_info_ = source_code_info; + if (source_code_info) { + _has_bits_[0] |= 0x00000010u; + } else { + _has_bits_[0] &= ~0x00000010u; + } + // @@protoc_insertion_point(field_unsafe_arena_set_allocated:google.protobuf.FileDescriptorProto.source_code_info) +} +inline ::PROTOBUF_NAMESPACE_ID::SourceCodeInfo* FileDescriptorProto::release_source_code_info() { + _has_bits_[0] &= ~0x00000010u; + ::PROTOBUF_NAMESPACE_ID::SourceCodeInfo* temp = source_code_info_; + source_code_info_ = nullptr; +#ifdef PROTOBUF_FORCE_COPY_IN_RELEASE + auto* old = reinterpret_cast<::PROTOBUF_NAMESPACE_ID::MessageLite*>(temp); + temp = ::PROTOBUF_NAMESPACE_ID::internal::DuplicateIfNonNull(temp); + if (GetArenaForAllocation() == nullptr) { delete old; } +#else // PROTOBUF_FORCE_COPY_IN_RELEASE + if (GetArenaForAllocation() != nullptr) { + temp = ::PROTOBUF_NAMESPACE_ID::internal::DuplicateIfNonNull(temp); + } +#endif // !PROTOBUF_FORCE_COPY_IN_RELEASE + return temp; +} +inline ::PROTOBUF_NAMESPACE_ID::SourceCodeInfo* FileDescriptorProto::unsafe_arena_release_source_code_info() { + // @@protoc_insertion_point(field_release:google.protobuf.FileDescriptorProto.source_code_info) + _has_bits_[0] &= ~0x00000010u; + ::PROTOBUF_NAMESPACE_ID::SourceCodeInfo* temp = source_code_info_; + source_code_info_ = nullptr; + return temp; +} +inline ::PROTOBUF_NAMESPACE_ID::SourceCodeInfo* FileDescriptorProto::_internal_mutable_source_code_info() { + _has_bits_[0] |= 0x00000010u; + if (source_code_info_ == nullptr) { + auto* p = CreateMaybeMessage<::PROTOBUF_NAMESPACE_ID::SourceCodeInfo>(GetArenaForAllocation()); + source_code_info_ = p; + } + return source_code_info_; +} +inline ::PROTOBUF_NAMESPACE_ID::SourceCodeInfo* FileDescriptorProto::mutable_source_code_info() { + ::PROTOBUF_NAMESPACE_ID::SourceCodeInfo* _msg = _internal_mutable_source_code_info(); + // @@protoc_insertion_point(field_mutable:google.protobuf.FileDescriptorProto.source_code_info) + return _msg; +} +inline void FileDescriptorProto::set_allocated_source_code_info(::PROTOBUF_NAMESPACE_ID::SourceCodeInfo* source_code_info) { + ::PROTOBUF_NAMESPACE_ID::Arena* message_arena = GetArenaForAllocation(); + if (message_arena == nullptr) { + delete source_code_info_; + } + if (source_code_info) { + ::PROTOBUF_NAMESPACE_ID::Arena* submessage_arena = + ::PROTOBUF_NAMESPACE_ID::Arena::InternalHelper<::PROTOBUF_NAMESPACE_ID::SourceCodeInfo>::GetOwningArena(source_code_info); + if (message_arena != submessage_arena) { + source_code_info = ::PROTOBUF_NAMESPACE_ID::internal::GetOwnedMessage( + message_arena, source_code_info, submessage_arena); + } + _has_bits_[0] |= 0x00000010u; + } else { + _has_bits_[0] &= ~0x00000010u; + } + source_code_info_ = source_code_info; + // @@protoc_insertion_point(field_set_allocated:google.protobuf.FileDescriptorProto.source_code_info) +} + +// optional string syntax = 12; +inline bool FileDescriptorProto::_internal_has_syntax() const { + bool value = (_has_bits_[0] & 0x00000004u) != 0; + return value; +} +inline bool FileDescriptorProto::has_syntax() const { + return _internal_has_syntax(); +} +inline void FileDescriptorProto::clear_syntax() { + syntax_.ClearToEmpty(); + _has_bits_[0] &= ~0x00000004u; +} +inline const TProtoStringType& FileDescriptorProto::syntax() const { + // @@protoc_insertion_point(field_get:google.protobuf.FileDescriptorProto.syntax) + return _internal_syntax(); +} +template <typename ArgT0, typename... ArgT> +inline PROTOBUF_ALWAYS_INLINE +void FileDescriptorProto::set_syntax(ArgT0&& arg0, ArgT... args) { + _has_bits_[0] |= 0x00000004u; + syntax_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, static_cast<ArgT0 &&>(arg0), args..., GetArenaForAllocation()); + // @@protoc_insertion_point(field_set:google.protobuf.FileDescriptorProto.syntax) +} +inline TProtoStringType* FileDescriptorProto::mutable_syntax() { + TProtoStringType* _s = _internal_mutable_syntax(); + // @@protoc_insertion_point(field_mutable:google.protobuf.FileDescriptorProto.syntax) + return _s; +} +inline const TProtoStringType& FileDescriptorProto::_internal_syntax() const { + return syntax_.Get(); +} +inline void FileDescriptorProto::_internal_set_syntax(const TProtoStringType& value) { + _has_bits_[0] |= 0x00000004u; + syntax_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, value, GetArenaForAllocation()); +} +inline TProtoStringType* FileDescriptorProto::_internal_mutable_syntax() { + _has_bits_[0] |= 0x00000004u; + return syntax_.Mutable(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, GetArenaForAllocation()); +} +inline TProtoStringType* FileDescriptorProto::release_syntax() { + // @@protoc_insertion_point(field_release:google.protobuf.FileDescriptorProto.syntax) + if (!_internal_has_syntax()) { + return nullptr; + } + _has_bits_[0] &= ~0x00000004u; + auto* p = syntax_.ReleaseNonDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArenaForAllocation()); +#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING + if (syntax_.IsDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited())) { + syntax_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation()); + } +#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING + return p; +} +inline void FileDescriptorProto::set_allocated_syntax(TProtoStringType* syntax) { + if (syntax != nullptr) { + _has_bits_[0] |= 0x00000004u; + } else { + _has_bits_[0] &= ~0x00000004u; + } + syntax_.SetAllocated(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), syntax, + GetArenaForAllocation()); +#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING + if (syntax_.IsDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited())) { + syntax_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation()); + } +#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING + // @@protoc_insertion_point(field_set_allocated:google.protobuf.FileDescriptorProto.syntax) +} + +// ------------------------------------------------------------------- + +// DescriptorProto_ExtensionRange + +// optional int32 start = 1; +inline bool DescriptorProto_ExtensionRange::_internal_has_start() const { + bool value = (_has_bits_[0] & 0x00000002u) != 0; + return value; +} +inline bool DescriptorProto_ExtensionRange::has_start() const { + return _internal_has_start(); +} +inline void DescriptorProto_ExtensionRange::clear_start() { + start_ = 0; + _has_bits_[0] &= ~0x00000002u; +} +inline arc_i32 DescriptorProto_ExtensionRange::_internal_start() const { + return start_; +} +inline arc_i32 DescriptorProto_ExtensionRange::start() const { + // @@protoc_insertion_point(field_get:google.protobuf.DescriptorProto.ExtensionRange.start) + return _internal_start(); +} +inline void DescriptorProto_ExtensionRange::_internal_set_start(arc_i32 value) { + _has_bits_[0] |= 0x00000002u; + start_ = value; +} +inline void DescriptorProto_ExtensionRange::set_start(arc_i32 value) { + _internal_set_start(value); + // @@protoc_insertion_point(field_set:google.protobuf.DescriptorProto.ExtensionRange.start) +} + +// optional int32 end = 2; +inline bool DescriptorProto_ExtensionRange::_internal_has_end() const { + bool value = (_has_bits_[0] & 0x00000004u) != 0; + return value; +} +inline bool DescriptorProto_ExtensionRange::has_end() const { + return _internal_has_end(); +} +inline void DescriptorProto_ExtensionRange::clear_end() { + end_ = 0; + _has_bits_[0] &= ~0x00000004u; +} +inline arc_i32 DescriptorProto_ExtensionRange::_internal_end() const { + return end_; +} +inline arc_i32 DescriptorProto_ExtensionRange::end() const { + // @@protoc_insertion_point(field_get:google.protobuf.DescriptorProto.ExtensionRange.end) + return _internal_end(); +} +inline void DescriptorProto_ExtensionRange::_internal_set_end(arc_i32 value) { + _has_bits_[0] |= 0x00000004u; + end_ = value; +} +inline void DescriptorProto_ExtensionRange::set_end(arc_i32 value) { + _internal_set_end(value); + // @@protoc_insertion_point(field_set:google.protobuf.DescriptorProto.ExtensionRange.end) +} + +// optional .google.protobuf.ExtensionRangeOptions options = 3; +inline bool DescriptorProto_ExtensionRange::_internal_has_options() const { + bool value = (_has_bits_[0] & 0x00000001u) != 0; + PROTOBUF_ASSUME(!value || options_ != nullptr); + return value; +} +inline bool DescriptorProto_ExtensionRange::has_options() const { + return _internal_has_options(); +} +inline void DescriptorProto_ExtensionRange::clear_options() { + if (options_ != nullptr) options_->Clear(); + _has_bits_[0] &= ~0x00000001u; +} +inline const ::PROTOBUF_NAMESPACE_ID::ExtensionRangeOptions& DescriptorProto_ExtensionRange::_internal_options() const { + const ::PROTOBUF_NAMESPACE_ID::ExtensionRangeOptions* p = options_; + return p != nullptr ? *p : reinterpret_cast<const ::PROTOBUF_NAMESPACE_ID::ExtensionRangeOptions&>( + ::PROTOBUF_NAMESPACE_ID::_ExtensionRangeOptions_default_instance_); +} +inline const ::PROTOBUF_NAMESPACE_ID::ExtensionRangeOptions& DescriptorProto_ExtensionRange::options() const { + // @@protoc_insertion_point(field_get:google.protobuf.DescriptorProto.ExtensionRange.options) + return _internal_options(); +} +inline void DescriptorProto_ExtensionRange::unsafe_arena_set_allocated_options( + ::PROTOBUF_NAMESPACE_ID::ExtensionRangeOptions* options) { + if (GetArenaForAllocation() == nullptr) { + delete reinterpret_cast<::PROTOBUF_NAMESPACE_ID::MessageLite*>(options_); + } + options_ = options; + if (options) { + _has_bits_[0] |= 0x00000001u; + } else { + _has_bits_[0] &= ~0x00000001u; + } + // @@protoc_insertion_point(field_unsafe_arena_set_allocated:google.protobuf.DescriptorProto.ExtensionRange.options) +} +inline ::PROTOBUF_NAMESPACE_ID::ExtensionRangeOptions* DescriptorProto_ExtensionRange::release_options() { + _has_bits_[0] &= ~0x00000001u; + ::PROTOBUF_NAMESPACE_ID::ExtensionRangeOptions* temp = options_; + options_ = nullptr; +#ifdef PROTOBUF_FORCE_COPY_IN_RELEASE + auto* old = reinterpret_cast<::PROTOBUF_NAMESPACE_ID::MessageLite*>(temp); + temp = ::PROTOBUF_NAMESPACE_ID::internal::DuplicateIfNonNull(temp); + if (GetArenaForAllocation() == nullptr) { delete old; } +#else // PROTOBUF_FORCE_COPY_IN_RELEASE + if (GetArenaForAllocation() != nullptr) { + temp = ::PROTOBUF_NAMESPACE_ID::internal::DuplicateIfNonNull(temp); + } +#endif // !PROTOBUF_FORCE_COPY_IN_RELEASE + return temp; +} +inline ::PROTOBUF_NAMESPACE_ID::ExtensionRangeOptions* DescriptorProto_ExtensionRange::unsafe_arena_release_options() { + // @@protoc_insertion_point(field_release:google.protobuf.DescriptorProto.ExtensionRange.options) + _has_bits_[0] &= ~0x00000001u; + ::PROTOBUF_NAMESPACE_ID::ExtensionRangeOptions* temp = options_; + options_ = nullptr; + return temp; +} +inline ::PROTOBUF_NAMESPACE_ID::ExtensionRangeOptions* DescriptorProto_ExtensionRange::_internal_mutable_options() { + _has_bits_[0] |= 0x00000001u; + if (options_ == nullptr) { + auto* p = CreateMaybeMessage<::PROTOBUF_NAMESPACE_ID::ExtensionRangeOptions>(GetArenaForAllocation()); + options_ = p; + } + return options_; +} +inline ::PROTOBUF_NAMESPACE_ID::ExtensionRangeOptions* DescriptorProto_ExtensionRange::mutable_options() { + ::PROTOBUF_NAMESPACE_ID::ExtensionRangeOptions* _msg = _internal_mutable_options(); + // @@protoc_insertion_point(field_mutable:google.protobuf.DescriptorProto.ExtensionRange.options) + return _msg; +} +inline void DescriptorProto_ExtensionRange::set_allocated_options(::PROTOBUF_NAMESPACE_ID::ExtensionRangeOptions* options) { + ::PROTOBUF_NAMESPACE_ID::Arena* message_arena = GetArenaForAllocation(); + if (message_arena == nullptr) { + delete options_; + } + if (options) { + ::PROTOBUF_NAMESPACE_ID::Arena* submessage_arena = + ::PROTOBUF_NAMESPACE_ID::Arena::InternalHelper<::PROTOBUF_NAMESPACE_ID::ExtensionRangeOptions>::GetOwningArena(options); + if (message_arena != submessage_arena) { + options = ::PROTOBUF_NAMESPACE_ID::internal::GetOwnedMessage( + message_arena, options, submessage_arena); + } + _has_bits_[0] |= 0x00000001u; + } else { + _has_bits_[0] &= ~0x00000001u; + } + options_ = options; + // @@protoc_insertion_point(field_set_allocated:google.protobuf.DescriptorProto.ExtensionRange.options) +} + +// ------------------------------------------------------------------- + +// DescriptorProto_ReservedRange + +// optional int32 start = 1; +inline bool DescriptorProto_ReservedRange::_internal_has_start() const { + bool value = (_has_bits_[0] & 0x00000001u) != 0; + return value; +} +inline bool DescriptorProto_ReservedRange::has_start() const { + return _internal_has_start(); +} +inline void DescriptorProto_ReservedRange::clear_start() { + start_ = 0; + _has_bits_[0] &= ~0x00000001u; +} +inline arc_i32 DescriptorProto_ReservedRange::_internal_start() const { + return start_; +} +inline arc_i32 DescriptorProto_ReservedRange::start() const { + // @@protoc_insertion_point(field_get:google.protobuf.DescriptorProto.ReservedRange.start) + return _internal_start(); +} +inline void DescriptorProto_ReservedRange::_internal_set_start(arc_i32 value) { + _has_bits_[0] |= 0x00000001u; + start_ = value; +} +inline void DescriptorProto_ReservedRange::set_start(arc_i32 value) { + _internal_set_start(value); + // @@protoc_insertion_point(field_set:google.protobuf.DescriptorProto.ReservedRange.start) +} + +// optional int32 end = 2; +inline bool DescriptorProto_ReservedRange::_internal_has_end() const { + bool value = (_has_bits_[0] & 0x00000002u) != 0; + return value; +} +inline bool DescriptorProto_ReservedRange::has_end() const { + return _internal_has_end(); +} +inline void DescriptorProto_ReservedRange::clear_end() { + end_ = 0; + _has_bits_[0] &= ~0x00000002u; +} +inline arc_i32 DescriptorProto_ReservedRange::_internal_end() const { + return end_; +} +inline arc_i32 DescriptorProto_ReservedRange::end() const { + // @@protoc_insertion_point(field_get:google.protobuf.DescriptorProto.ReservedRange.end) + return _internal_end(); +} +inline void DescriptorProto_ReservedRange::_internal_set_end(arc_i32 value) { + _has_bits_[0] |= 0x00000002u; + end_ = value; +} +inline void DescriptorProto_ReservedRange::set_end(arc_i32 value) { + _internal_set_end(value); + // @@protoc_insertion_point(field_set:google.protobuf.DescriptorProto.ReservedRange.end) +} + +// ------------------------------------------------------------------- + +// DescriptorProto + +// optional string name = 1; +inline bool DescriptorProto::_internal_has_name() const { + bool value = (_has_bits_[0] & 0x00000001u) != 0; + return value; +} +inline bool DescriptorProto::has_name() const { + return _internal_has_name(); +} +inline void DescriptorProto::clear_name() { + name_.ClearToEmpty(); + _has_bits_[0] &= ~0x00000001u; +} +inline const TProtoStringType& DescriptorProto::name() const { + // @@protoc_insertion_point(field_get:google.protobuf.DescriptorProto.name) + return _internal_name(); +} +template <typename ArgT0, typename... ArgT> +inline PROTOBUF_ALWAYS_INLINE +void DescriptorProto::set_name(ArgT0&& arg0, ArgT... args) { + _has_bits_[0] |= 0x00000001u; + name_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, static_cast<ArgT0 &&>(arg0), args..., GetArenaForAllocation()); + // @@protoc_insertion_point(field_set:google.protobuf.DescriptorProto.name) +} +inline TProtoStringType* DescriptorProto::mutable_name() { + TProtoStringType* _s = _internal_mutable_name(); + // @@protoc_insertion_point(field_mutable:google.protobuf.DescriptorProto.name) + return _s; +} +inline const TProtoStringType& DescriptorProto::_internal_name() const { + return name_.Get(); +} +inline void DescriptorProto::_internal_set_name(const TProtoStringType& value) { + _has_bits_[0] |= 0x00000001u; + name_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, value, GetArenaForAllocation()); +} +inline TProtoStringType* DescriptorProto::_internal_mutable_name() { + _has_bits_[0] |= 0x00000001u; + return name_.Mutable(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, GetArenaForAllocation()); +} +inline TProtoStringType* DescriptorProto::release_name() { + // @@protoc_insertion_point(field_release:google.protobuf.DescriptorProto.name) + if (!_internal_has_name()) { + return nullptr; + } + _has_bits_[0] &= ~0x00000001u; + auto* p = name_.ReleaseNonDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArenaForAllocation()); +#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING + if (name_.IsDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited())) { + name_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation()); + } +#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING + return p; +} +inline void DescriptorProto::set_allocated_name(TProtoStringType* name) { + if (name != nullptr) { + _has_bits_[0] |= 0x00000001u; + } else { + _has_bits_[0] &= ~0x00000001u; + } + name_.SetAllocated(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), name, + GetArenaForAllocation()); +#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING + if (name_.IsDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited())) { + name_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation()); + } +#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING + // @@protoc_insertion_point(field_set_allocated:google.protobuf.DescriptorProto.name) +} + +// repeated .google.protobuf.FieldDescriptorProto field = 2; +inline int DescriptorProto::_internal_field_size() const { + return field_.size(); +} +inline int DescriptorProto::field_size() const { + return _internal_field_size(); +} +inline void DescriptorProto::clear_field() { + field_.Clear(); +} +inline ::PROTOBUF_NAMESPACE_ID::FieldDescriptorProto* DescriptorProto::mutable_field(int index) { + // @@protoc_insertion_point(field_mutable:google.protobuf.DescriptorProto.field) + return field_.Mutable(index); +} +inline ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::FieldDescriptorProto >* +DescriptorProto::mutable_field() { + // @@protoc_insertion_point(field_mutable_list:google.protobuf.DescriptorProto.field) + return &field_; +} +inline const ::PROTOBUF_NAMESPACE_ID::FieldDescriptorProto& DescriptorProto::_internal_field(int index) const { + return field_.Get(index); +} +inline const ::PROTOBUF_NAMESPACE_ID::FieldDescriptorProto& DescriptorProto::field(int index) const { + // @@protoc_insertion_point(field_get:google.protobuf.DescriptorProto.field) + return _internal_field(index); +} +inline ::PROTOBUF_NAMESPACE_ID::FieldDescriptorProto* DescriptorProto::_internal_add_field() { + return field_.Add(); +} +inline ::PROTOBUF_NAMESPACE_ID::FieldDescriptorProto* DescriptorProto::add_field() { + ::PROTOBUF_NAMESPACE_ID::FieldDescriptorProto* _add = _internal_add_field(); + // @@protoc_insertion_point(field_add:google.protobuf.DescriptorProto.field) + return _add; +} +inline const ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::FieldDescriptorProto >& +DescriptorProto::field() const { + // @@protoc_insertion_point(field_list:google.protobuf.DescriptorProto.field) + return field_; +} + +// repeated .google.protobuf.FieldDescriptorProto extension = 6; +inline int DescriptorProto::_internal_extension_size() const { + return extension_.size(); +} +inline int DescriptorProto::extension_size() const { + return _internal_extension_size(); +} +inline void DescriptorProto::clear_extension() { + extension_.Clear(); +} +inline ::PROTOBUF_NAMESPACE_ID::FieldDescriptorProto* DescriptorProto::mutable_extension(int index) { + // @@protoc_insertion_point(field_mutable:google.protobuf.DescriptorProto.extension) + return extension_.Mutable(index); +} +inline ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::FieldDescriptorProto >* +DescriptorProto::mutable_extension() { + // @@protoc_insertion_point(field_mutable_list:google.protobuf.DescriptorProto.extension) + return &extension_; +} +inline const ::PROTOBUF_NAMESPACE_ID::FieldDescriptorProto& DescriptorProto::_internal_extension(int index) const { + return extension_.Get(index); +} +inline const ::PROTOBUF_NAMESPACE_ID::FieldDescriptorProto& DescriptorProto::extension(int index) const { + // @@protoc_insertion_point(field_get:google.protobuf.DescriptorProto.extension) + return _internal_extension(index); +} +inline ::PROTOBUF_NAMESPACE_ID::FieldDescriptorProto* DescriptorProto::_internal_add_extension() { + return extension_.Add(); +} +inline ::PROTOBUF_NAMESPACE_ID::FieldDescriptorProto* DescriptorProto::add_extension() { + ::PROTOBUF_NAMESPACE_ID::FieldDescriptorProto* _add = _internal_add_extension(); + // @@protoc_insertion_point(field_add:google.protobuf.DescriptorProto.extension) + return _add; +} +inline const ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::FieldDescriptorProto >& +DescriptorProto::extension() const { + // @@protoc_insertion_point(field_list:google.protobuf.DescriptorProto.extension) + return extension_; +} + +// repeated .google.protobuf.DescriptorProto nested_type = 3; +inline int DescriptorProto::_internal_nested_type_size() const { + return nested_type_.size(); +} +inline int DescriptorProto::nested_type_size() const { + return _internal_nested_type_size(); +} +inline void DescriptorProto::clear_nested_type() { + nested_type_.Clear(); +} +inline ::PROTOBUF_NAMESPACE_ID::DescriptorProto* DescriptorProto::mutable_nested_type(int index) { + // @@protoc_insertion_point(field_mutable:google.protobuf.DescriptorProto.nested_type) + return nested_type_.Mutable(index); +} +inline ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::DescriptorProto >* +DescriptorProto::mutable_nested_type() { + // @@protoc_insertion_point(field_mutable_list:google.protobuf.DescriptorProto.nested_type) + return &nested_type_; +} +inline const ::PROTOBUF_NAMESPACE_ID::DescriptorProto& DescriptorProto::_internal_nested_type(int index) const { + return nested_type_.Get(index); +} +inline const ::PROTOBUF_NAMESPACE_ID::DescriptorProto& DescriptorProto::nested_type(int index) const { + // @@protoc_insertion_point(field_get:google.protobuf.DescriptorProto.nested_type) + return _internal_nested_type(index); +} +inline ::PROTOBUF_NAMESPACE_ID::DescriptorProto* DescriptorProto::_internal_add_nested_type() { + return nested_type_.Add(); +} +inline ::PROTOBUF_NAMESPACE_ID::DescriptorProto* DescriptorProto::add_nested_type() { + ::PROTOBUF_NAMESPACE_ID::DescriptorProto* _add = _internal_add_nested_type(); + // @@protoc_insertion_point(field_add:google.protobuf.DescriptorProto.nested_type) + return _add; +} +inline const ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::DescriptorProto >& +DescriptorProto::nested_type() const { + // @@protoc_insertion_point(field_list:google.protobuf.DescriptorProto.nested_type) + return nested_type_; +} + +// repeated .google.protobuf.EnumDescriptorProto enum_type = 4; +inline int DescriptorProto::_internal_enum_type_size() const { + return enum_type_.size(); +} +inline int DescriptorProto::enum_type_size() const { + return _internal_enum_type_size(); +} +inline void DescriptorProto::clear_enum_type() { + enum_type_.Clear(); +} +inline ::PROTOBUF_NAMESPACE_ID::EnumDescriptorProto* DescriptorProto::mutable_enum_type(int index) { + // @@protoc_insertion_point(field_mutable:google.protobuf.DescriptorProto.enum_type) + return enum_type_.Mutable(index); +} +inline ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::EnumDescriptorProto >* +DescriptorProto::mutable_enum_type() { + // @@protoc_insertion_point(field_mutable_list:google.protobuf.DescriptorProto.enum_type) + return &enum_type_; +} +inline const ::PROTOBUF_NAMESPACE_ID::EnumDescriptorProto& DescriptorProto::_internal_enum_type(int index) const { + return enum_type_.Get(index); +} +inline const ::PROTOBUF_NAMESPACE_ID::EnumDescriptorProto& DescriptorProto::enum_type(int index) const { + // @@protoc_insertion_point(field_get:google.protobuf.DescriptorProto.enum_type) + return _internal_enum_type(index); +} +inline ::PROTOBUF_NAMESPACE_ID::EnumDescriptorProto* DescriptorProto::_internal_add_enum_type() { + return enum_type_.Add(); +} +inline ::PROTOBUF_NAMESPACE_ID::EnumDescriptorProto* DescriptorProto::add_enum_type() { + ::PROTOBUF_NAMESPACE_ID::EnumDescriptorProto* _add = _internal_add_enum_type(); + // @@protoc_insertion_point(field_add:google.protobuf.DescriptorProto.enum_type) + return _add; +} +inline const ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::EnumDescriptorProto >& +DescriptorProto::enum_type() const { + // @@protoc_insertion_point(field_list:google.protobuf.DescriptorProto.enum_type) + return enum_type_; +} + +// repeated .google.protobuf.DescriptorProto.ExtensionRange extension_range = 5; +inline int DescriptorProto::_internal_extension_range_size() const { + return extension_range_.size(); +} +inline int DescriptorProto::extension_range_size() const { + return _internal_extension_range_size(); +} +inline void DescriptorProto::clear_extension_range() { + extension_range_.Clear(); +} +inline ::PROTOBUF_NAMESPACE_ID::DescriptorProto_ExtensionRange* DescriptorProto::mutable_extension_range(int index) { + // @@protoc_insertion_point(field_mutable:google.protobuf.DescriptorProto.extension_range) + return extension_range_.Mutable(index); +} +inline ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::DescriptorProto_ExtensionRange >* +DescriptorProto::mutable_extension_range() { + // @@protoc_insertion_point(field_mutable_list:google.protobuf.DescriptorProto.extension_range) + return &extension_range_; +} +inline const ::PROTOBUF_NAMESPACE_ID::DescriptorProto_ExtensionRange& DescriptorProto::_internal_extension_range(int index) const { + return extension_range_.Get(index); +} +inline const ::PROTOBUF_NAMESPACE_ID::DescriptorProto_ExtensionRange& DescriptorProto::extension_range(int index) const { + // @@protoc_insertion_point(field_get:google.protobuf.DescriptorProto.extension_range) + return _internal_extension_range(index); +} +inline ::PROTOBUF_NAMESPACE_ID::DescriptorProto_ExtensionRange* DescriptorProto::_internal_add_extension_range() { + return extension_range_.Add(); +} +inline ::PROTOBUF_NAMESPACE_ID::DescriptorProto_ExtensionRange* DescriptorProto::add_extension_range() { + ::PROTOBUF_NAMESPACE_ID::DescriptorProto_ExtensionRange* _add = _internal_add_extension_range(); + // @@protoc_insertion_point(field_add:google.protobuf.DescriptorProto.extension_range) + return _add; +} +inline const ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::DescriptorProto_ExtensionRange >& +DescriptorProto::extension_range() const { + // @@protoc_insertion_point(field_list:google.protobuf.DescriptorProto.extension_range) + return extension_range_; +} + +// repeated .google.protobuf.OneofDescriptorProto oneof_decl = 8; +inline int DescriptorProto::_internal_oneof_decl_size() const { + return oneof_decl_.size(); +} +inline int DescriptorProto::oneof_decl_size() const { + return _internal_oneof_decl_size(); +} +inline void DescriptorProto::clear_oneof_decl() { + oneof_decl_.Clear(); +} +inline ::PROTOBUF_NAMESPACE_ID::OneofDescriptorProto* DescriptorProto::mutable_oneof_decl(int index) { + // @@protoc_insertion_point(field_mutable:google.protobuf.DescriptorProto.oneof_decl) + return oneof_decl_.Mutable(index); +} +inline ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::OneofDescriptorProto >* +DescriptorProto::mutable_oneof_decl() { + // @@protoc_insertion_point(field_mutable_list:google.protobuf.DescriptorProto.oneof_decl) + return &oneof_decl_; +} +inline const ::PROTOBUF_NAMESPACE_ID::OneofDescriptorProto& DescriptorProto::_internal_oneof_decl(int index) const { + return oneof_decl_.Get(index); +} +inline const ::PROTOBUF_NAMESPACE_ID::OneofDescriptorProto& DescriptorProto::oneof_decl(int index) const { + // @@protoc_insertion_point(field_get:google.protobuf.DescriptorProto.oneof_decl) + return _internal_oneof_decl(index); +} +inline ::PROTOBUF_NAMESPACE_ID::OneofDescriptorProto* DescriptorProto::_internal_add_oneof_decl() { + return oneof_decl_.Add(); +} +inline ::PROTOBUF_NAMESPACE_ID::OneofDescriptorProto* DescriptorProto::add_oneof_decl() { + ::PROTOBUF_NAMESPACE_ID::OneofDescriptorProto* _add = _internal_add_oneof_decl(); + // @@protoc_insertion_point(field_add:google.protobuf.DescriptorProto.oneof_decl) + return _add; +} +inline const ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::OneofDescriptorProto >& +DescriptorProto::oneof_decl() const { + // @@protoc_insertion_point(field_list:google.protobuf.DescriptorProto.oneof_decl) + return oneof_decl_; +} + +// optional .google.protobuf.MessageOptions options = 7; +inline bool DescriptorProto::_internal_has_options() const { + bool value = (_has_bits_[0] & 0x00000002u) != 0; + PROTOBUF_ASSUME(!value || options_ != nullptr); + return value; +} +inline bool DescriptorProto::has_options() const { + return _internal_has_options(); +} +inline void DescriptorProto::clear_options() { + if (options_ != nullptr) options_->Clear(); + _has_bits_[0] &= ~0x00000002u; +} +inline const ::PROTOBUF_NAMESPACE_ID::MessageOptions& DescriptorProto::_internal_options() const { + const ::PROTOBUF_NAMESPACE_ID::MessageOptions* p = options_; + return p != nullptr ? *p : reinterpret_cast<const ::PROTOBUF_NAMESPACE_ID::MessageOptions&>( + ::PROTOBUF_NAMESPACE_ID::_MessageOptions_default_instance_); +} +inline const ::PROTOBUF_NAMESPACE_ID::MessageOptions& DescriptorProto::options() const { + // @@protoc_insertion_point(field_get:google.protobuf.DescriptorProto.options) + return _internal_options(); +} +inline void DescriptorProto::unsafe_arena_set_allocated_options( + ::PROTOBUF_NAMESPACE_ID::MessageOptions* options) { + if (GetArenaForAllocation() == nullptr) { + delete reinterpret_cast<::PROTOBUF_NAMESPACE_ID::MessageLite*>(options_); + } + options_ = options; + if (options) { + _has_bits_[0] |= 0x00000002u; + } else { + _has_bits_[0] &= ~0x00000002u; + } + // @@protoc_insertion_point(field_unsafe_arena_set_allocated:google.protobuf.DescriptorProto.options) +} +inline ::PROTOBUF_NAMESPACE_ID::MessageOptions* DescriptorProto::release_options() { + _has_bits_[0] &= ~0x00000002u; + ::PROTOBUF_NAMESPACE_ID::MessageOptions* temp = options_; + options_ = nullptr; +#ifdef PROTOBUF_FORCE_COPY_IN_RELEASE + auto* old = reinterpret_cast<::PROTOBUF_NAMESPACE_ID::MessageLite*>(temp); + temp = ::PROTOBUF_NAMESPACE_ID::internal::DuplicateIfNonNull(temp); + if (GetArenaForAllocation() == nullptr) { delete old; } +#else // PROTOBUF_FORCE_COPY_IN_RELEASE + if (GetArenaForAllocation() != nullptr) { + temp = ::PROTOBUF_NAMESPACE_ID::internal::DuplicateIfNonNull(temp); + } +#endif // !PROTOBUF_FORCE_COPY_IN_RELEASE + return temp; +} +inline ::PROTOBUF_NAMESPACE_ID::MessageOptions* DescriptorProto::unsafe_arena_release_options() { + // @@protoc_insertion_point(field_release:google.protobuf.DescriptorProto.options) + _has_bits_[0] &= ~0x00000002u; + ::PROTOBUF_NAMESPACE_ID::MessageOptions* temp = options_; + options_ = nullptr; + return temp; +} +inline ::PROTOBUF_NAMESPACE_ID::MessageOptions* DescriptorProto::_internal_mutable_options() { + _has_bits_[0] |= 0x00000002u; + if (options_ == nullptr) { + auto* p = CreateMaybeMessage<::PROTOBUF_NAMESPACE_ID::MessageOptions>(GetArenaForAllocation()); + options_ = p; + } + return options_; +} +inline ::PROTOBUF_NAMESPACE_ID::MessageOptions* DescriptorProto::mutable_options() { + ::PROTOBUF_NAMESPACE_ID::MessageOptions* _msg = _internal_mutable_options(); + // @@protoc_insertion_point(field_mutable:google.protobuf.DescriptorProto.options) + return _msg; +} +inline void DescriptorProto::set_allocated_options(::PROTOBUF_NAMESPACE_ID::MessageOptions* options) { + ::PROTOBUF_NAMESPACE_ID::Arena* message_arena = GetArenaForAllocation(); + if (message_arena == nullptr) { + delete options_; + } + if (options) { + ::PROTOBUF_NAMESPACE_ID::Arena* submessage_arena = + ::PROTOBUF_NAMESPACE_ID::Arena::InternalHelper<::PROTOBUF_NAMESPACE_ID::MessageOptions>::GetOwningArena(options); + if (message_arena != submessage_arena) { + options = ::PROTOBUF_NAMESPACE_ID::internal::GetOwnedMessage( + message_arena, options, submessage_arena); + } + _has_bits_[0] |= 0x00000002u; + } else { + _has_bits_[0] &= ~0x00000002u; + } + options_ = options; + // @@protoc_insertion_point(field_set_allocated:google.protobuf.DescriptorProto.options) +} + +// repeated .google.protobuf.DescriptorProto.ReservedRange reserved_range = 9; +inline int DescriptorProto::_internal_reserved_range_size() const { + return reserved_range_.size(); +} +inline int DescriptorProto::reserved_range_size() const { + return _internal_reserved_range_size(); +} +inline void DescriptorProto::clear_reserved_range() { + reserved_range_.Clear(); +} +inline ::PROTOBUF_NAMESPACE_ID::DescriptorProto_ReservedRange* DescriptorProto::mutable_reserved_range(int index) { + // @@protoc_insertion_point(field_mutable:google.protobuf.DescriptorProto.reserved_range) + return reserved_range_.Mutable(index); +} +inline ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::DescriptorProto_ReservedRange >* +DescriptorProto::mutable_reserved_range() { + // @@protoc_insertion_point(field_mutable_list:google.protobuf.DescriptorProto.reserved_range) + return &reserved_range_; +} +inline const ::PROTOBUF_NAMESPACE_ID::DescriptorProto_ReservedRange& DescriptorProto::_internal_reserved_range(int index) const { + return reserved_range_.Get(index); +} +inline const ::PROTOBUF_NAMESPACE_ID::DescriptorProto_ReservedRange& DescriptorProto::reserved_range(int index) const { + // @@protoc_insertion_point(field_get:google.protobuf.DescriptorProto.reserved_range) + return _internal_reserved_range(index); +} +inline ::PROTOBUF_NAMESPACE_ID::DescriptorProto_ReservedRange* DescriptorProto::_internal_add_reserved_range() { + return reserved_range_.Add(); +} +inline ::PROTOBUF_NAMESPACE_ID::DescriptorProto_ReservedRange* DescriptorProto::add_reserved_range() { + ::PROTOBUF_NAMESPACE_ID::DescriptorProto_ReservedRange* _add = _internal_add_reserved_range(); + // @@protoc_insertion_point(field_add:google.protobuf.DescriptorProto.reserved_range) + return _add; +} +inline const ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::DescriptorProto_ReservedRange >& +DescriptorProto::reserved_range() const { + // @@protoc_insertion_point(field_list:google.protobuf.DescriptorProto.reserved_range) + return reserved_range_; +} + +// repeated string reserved_name = 10; +inline int DescriptorProto::_internal_reserved_name_size() const { + return reserved_name_.size(); +} +inline int DescriptorProto::reserved_name_size() const { + return _internal_reserved_name_size(); +} +inline void DescriptorProto::clear_reserved_name() { + reserved_name_.Clear(); +} +inline TProtoStringType* DescriptorProto::add_reserved_name() { + TProtoStringType* _s = _internal_add_reserved_name(); + // @@protoc_insertion_point(field_add_mutable:google.protobuf.DescriptorProto.reserved_name) + return _s; +} +inline const TProtoStringType& DescriptorProto::_internal_reserved_name(int index) const { + return reserved_name_.Get(index); +} +inline const TProtoStringType& DescriptorProto::reserved_name(int index) const { + // @@protoc_insertion_point(field_get:google.protobuf.DescriptorProto.reserved_name) + return _internal_reserved_name(index); +} +inline TProtoStringType* DescriptorProto::mutable_reserved_name(int index) { + // @@protoc_insertion_point(field_mutable:google.protobuf.DescriptorProto.reserved_name) + return reserved_name_.Mutable(index); +} +inline void DescriptorProto::set_reserved_name(int index, const TProtoStringType& value) { + reserved_name_.Mutable(index)->assign(value); + // @@protoc_insertion_point(field_set:google.protobuf.DescriptorProto.reserved_name) +} +inline void DescriptorProto::set_reserved_name(int index, TProtoStringType&& value) { + reserved_name_.Mutable(index)->assign(std::move(value)); + // @@protoc_insertion_point(field_set:google.protobuf.DescriptorProto.reserved_name) +} +inline void DescriptorProto::set_reserved_name(int index, const char* value) { + GOOGLE_DCHECK(value != nullptr); + reserved_name_.Mutable(index)->assign(value); + // @@protoc_insertion_point(field_set_char:google.protobuf.DescriptorProto.reserved_name) +} +inline void DescriptorProto::set_reserved_name(int index, const char* value, size_t size) { + reserved_name_.Mutable(index)->assign( + reinterpret_cast<const char*>(value), size); + // @@protoc_insertion_point(field_set_pointer:google.protobuf.DescriptorProto.reserved_name) +} +inline TProtoStringType* DescriptorProto::_internal_add_reserved_name() { + return reserved_name_.Add(); +} +inline void DescriptorProto::add_reserved_name(const TProtoStringType& value) { + reserved_name_.Add()->assign(value); + // @@protoc_insertion_point(field_add:google.protobuf.DescriptorProto.reserved_name) +} +inline void DescriptorProto::add_reserved_name(TProtoStringType&& value) { + reserved_name_.Add(std::move(value)); + // @@protoc_insertion_point(field_add:google.protobuf.DescriptorProto.reserved_name) +} +inline void DescriptorProto::add_reserved_name(const char* value) { + GOOGLE_DCHECK(value != nullptr); + reserved_name_.Add()->assign(value); + // @@protoc_insertion_point(field_add_char:google.protobuf.DescriptorProto.reserved_name) +} +inline void DescriptorProto::add_reserved_name(const char* value, size_t size) { + reserved_name_.Add()->assign(reinterpret_cast<const char*>(value), size); + // @@protoc_insertion_point(field_add_pointer:google.protobuf.DescriptorProto.reserved_name) +} +inline const ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField<TProtoStringType>& +DescriptorProto::reserved_name() const { + // @@protoc_insertion_point(field_list:google.protobuf.DescriptorProto.reserved_name) + return reserved_name_; +} +inline ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField<TProtoStringType>* +DescriptorProto::mutable_reserved_name() { + // @@protoc_insertion_point(field_mutable_list:google.protobuf.DescriptorProto.reserved_name) + return &reserved_name_; +} + +// ------------------------------------------------------------------- + +// ExtensionRangeOptions + +// repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999; +inline int ExtensionRangeOptions::_internal_uninterpreted_option_size() const { + return uninterpreted_option_.size(); +} +inline int ExtensionRangeOptions::uninterpreted_option_size() const { + return _internal_uninterpreted_option_size(); +} +inline void ExtensionRangeOptions::clear_uninterpreted_option() { + uninterpreted_option_.Clear(); +} +inline ::PROTOBUF_NAMESPACE_ID::UninterpretedOption* ExtensionRangeOptions::mutable_uninterpreted_option(int index) { + // @@protoc_insertion_point(field_mutable:google.protobuf.ExtensionRangeOptions.uninterpreted_option) + return uninterpreted_option_.Mutable(index); +} +inline ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::UninterpretedOption >* +ExtensionRangeOptions::mutable_uninterpreted_option() { + // @@protoc_insertion_point(field_mutable_list:google.protobuf.ExtensionRangeOptions.uninterpreted_option) + return &uninterpreted_option_; +} +inline const ::PROTOBUF_NAMESPACE_ID::UninterpretedOption& ExtensionRangeOptions::_internal_uninterpreted_option(int index) const { + return uninterpreted_option_.Get(index); +} +inline const ::PROTOBUF_NAMESPACE_ID::UninterpretedOption& ExtensionRangeOptions::uninterpreted_option(int index) const { + // @@protoc_insertion_point(field_get:google.protobuf.ExtensionRangeOptions.uninterpreted_option) + return _internal_uninterpreted_option(index); +} +inline ::PROTOBUF_NAMESPACE_ID::UninterpretedOption* ExtensionRangeOptions::_internal_add_uninterpreted_option() { + return uninterpreted_option_.Add(); +} +inline ::PROTOBUF_NAMESPACE_ID::UninterpretedOption* ExtensionRangeOptions::add_uninterpreted_option() { + ::PROTOBUF_NAMESPACE_ID::UninterpretedOption* _add = _internal_add_uninterpreted_option(); + // @@protoc_insertion_point(field_add:google.protobuf.ExtensionRangeOptions.uninterpreted_option) + return _add; +} +inline const ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::UninterpretedOption >& +ExtensionRangeOptions::uninterpreted_option() const { + // @@protoc_insertion_point(field_list:google.protobuf.ExtensionRangeOptions.uninterpreted_option) + return uninterpreted_option_; +} + +// ------------------------------------------------------------------- + +// FieldDescriptorProto + +// optional string name = 1; +inline bool FieldDescriptorProto::_internal_has_name() const { + bool value = (_has_bits_[0] & 0x00000001u) != 0; + return value; +} +inline bool FieldDescriptorProto::has_name() const { + return _internal_has_name(); +} +inline void FieldDescriptorProto::clear_name() { + name_.ClearToEmpty(); + _has_bits_[0] &= ~0x00000001u; +} +inline const TProtoStringType& FieldDescriptorProto::name() const { + // @@protoc_insertion_point(field_get:google.protobuf.FieldDescriptorProto.name) + return _internal_name(); +} +template <typename ArgT0, typename... ArgT> +inline PROTOBUF_ALWAYS_INLINE +void FieldDescriptorProto::set_name(ArgT0&& arg0, ArgT... args) { + _has_bits_[0] |= 0x00000001u; + name_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, static_cast<ArgT0 &&>(arg0), args..., GetArenaForAllocation()); + // @@protoc_insertion_point(field_set:google.protobuf.FieldDescriptorProto.name) +} +inline TProtoStringType* FieldDescriptorProto::mutable_name() { + TProtoStringType* _s = _internal_mutable_name(); + // @@protoc_insertion_point(field_mutable:google.protobuf.FieldDescriptorProto.name) + return _s; +} +inline const TProtoStringType& FieldDescriptorProto::_internal_name() const { + return name_.Get(); +} +inline void FieldDescriptorProto::_internal_set_name(const TProtoStringType& value) { + _has_bits_[0] |= 0x00000001u; + name_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, value, GetArenaForAllocation()); +} +inline TProtoStringType* FieldDescriptorProto::_internal_mutable_name() { + _has_bits_[0] |= 0x00000001u; + return name_.Mutable(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, GetArenaForAllocation()); +} +inline TProtoStringType* FieldDescriptorProto::release_name() { + // @@protoc_insertion_point(field_release:google.protobuf.FieldDescriptorProto.name) + if (!_internal_has_name()) { + return nullptr; + } + _has_bits_[0] &= ~0x00000001u; + auto* p = name_.ReleaseNonDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArenaForAllocation()); +#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING + if (name_.IsDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited())) { + name_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation()); + } +#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING + return p; +} +inline void FieldDescriptorProto::set_allocated_name(TProtoStringType* name) { + if (name != nullptr) { + _has_bits_[0] |= 0x00000001u; + } else { + _has_bits_[0] &= ~0x00000001u; + } + name_.SetAllocated(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), name, + GetArenaForAllocation()); +#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING + if (name_.IsDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited())) { + name_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation()); + } +#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING + // @@protoc_insertion_point(field_set_allocated:google.protobuf.FieldDescriptorProto.name) +} + +// optional int32 number = 3; +inline bool FieldDescriptorProto::_internal_has_number() const { + bool value = (_has_bits_[0] & 0x00000040u) != 0; + return value; +} +inline bool FieldDescriptorProto::has_number() const { + return _internal_has_number(); +} +inline void FieldDescriptorProto::clear_number() { + number_ = 0; + _has_bits_[0] &= ~0x00000040u; +} +inline arc_i32 FieldDescriptorProto::_internal_number() const { + return number_; +} +inline arc_i32 FieldDescriptorProto::number() const { + // @@protoc_insertion_point(field_get:google.protobuf.FieldDescriptorProto.number) + return _internal_number(); +} +inline void FieldDescriptorProto::_internal_set_number(arc_i32 value) { + _has_bits_[0] |= 0x00000040u; + number_ = value; +} +inline void FieldDescriptorProto::set_number(arc_i32 value) { + _internal_set_number(value); + // @@protoc_insertion_point(field_set:google.protobuf.FieldDescriptorProto.number) +} + +// optional .google.protobuf.FieldDescriptorProto.Label label = 4; +inline bool FieldDescriptorProto::_internal_has_label() const { + bool value = (_has_bits_[0] & 0x00000200u) != 0; + return value; +} +inline bool FieldDescriptorProto::has_label() const { + return _internal_has_label(); +} +inline void FieldDescriptorProto::clear_label() { + label_ = 1; + _has_bits_[0] &= ~0x00000200u; +} +inline ::PROTOBUF_NAMESPACE_ID::FieldDescriptorProto_Label FieldDescriptorProto::_internal_label() const { + return static_cast< ::PROTOBUF_NAMESPACE_ID::FieldDescriptorProto_Label >(label_); +} +inline ::PROTOBUF_NAMESPACE_ID::FieldDescriptorProto_Label FieldDescriptorProto::label() const { + // @@protoc_insertion_point(field_get:google.protobuf.FieldDescriptorProto.label) + return _internal_label(); +} +inline void FieldDescriptorProto::_internal_set_label(::PROTOBUF_NAMESPACE_ID::FieldDescriptorProto_Label value) { + assert(::PROTOBUF_NAMESPACE_ID::FieldDescriptorProto_Label_IsValid(value)); + _has_bits_[0] |= 0x00000200u; + label_ = value; +} +inline void FieldDescriptorProto::set_label(::PROTOBUF_NAMESPACE_ID::FieldDescriptorProto_Label value) { + _internal_set_label(value); + // @@protoc_insertion_point(field_set:google.protobuf.FieldDescriptorProto.label) +} + +// optional .google.protobuf.FieldDescriptorProto.Type type = 5; +inline bool FieldDescriptorProto::_internal_has_type() const { + bool value = (_has_bits_[0] & 0x00000400u) != 0; + return value; +} +inline bool FieldDescriptorProto::has_type() const { + return _internal_has_type(); +} +inline void FieldDescriptorProto::clear_type() { + type_ = 1; + _has_bits_[0] &= ~0x00000400u; +} +inline ::PROTOBUF_NAMESPACE_ID::FieldDescriptorProto_Type FieldDescriptorProto::_internal_type() const { + return static_cast< ::PROTOBUF_NAMESPACE_ID::FieldDescriptorProto_Type >(type_); +} +inline ::PROTOBUF_NAMESPACE_ID::FieldDescriptorProto_Type FieldDescriptorProto::type() const { + // @@protoc_insertion_point(field_get:google.protobuf.FieldDescriptorProto.type) + return _internal_type(); +} +inline void FieldDescriptorProto::_internal_set_type(::PROTOBUF_NAMESPACE_ID::FieldDescriptorProto_Type value) { + assert(::PROTOBUF_NAMESPACE_ID::FieldDescriptorProto_Type_IsValid(value)); + _has_bits_[0] |= 0x00000400u; + type_ = value; +} +inline void FieldDescriptorProto::set_type(::PROTOBUF_NAMESPACE_ID::FieldDescriptorProto_Type value) { + _internal_set_type(value); + // @@protoc_insertion_point(field_set:google.protobuf.FieldDescriptorProto.type) +} + +// optional string type_name = 6; +inline bool FieldDescriptorProto::_internal_has_type_name() const { + bool value = (_has_bits_[0] & 0x00000004u) != 0; + return value; +} +inline bool FieldDescriptorProto::has_type_name() const { + return _internal_has_type_name(); +} +inline void FieldDescriptorProto::clear_type_name() { + type_name_.ClearToEmpty(); + _has_bits_[0] &= ~0x00000004u; +} +inline const TProtoStringType& FieldDescriptorProto::type_name() const { + // @@protoc_insertion_point(field_get:google.protobuf.FieldDescriptorProto.type_name) + return _internal_type_name(); +} +template <typename ArgT0, typename... ArgT> +inline PROTOBUF_ALWAYS_INLINE +void FieldDescriptorProto::set_type_name(ArgT0&& arg0, ArgT... args) { + _has_bits_[0] |= 0x00000004u; + type_name_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, static_cast<ArgT0 &&>(arg0), args..., GetArenaForAllocation()); + // @@protoc_insertion_point(field_set:google.protobuf.FieldDescriptorProto.type_name) +} +inline TProtoStringType* FieldDescriptorProto::mutable_type_name() { + TProtoStringType* _s = _internal_mutable_type_name(); + // @@protoc_insertion_point(field_mutable:google.protobuf.FieldDescriptorProto.type_name) + return _s; +} +inline const TProtoStringType& FieldDescriptorProto::_internal_type_name() const { + return type_name_.Get(); +} +inline void FieldDescriptorProto::_internal_set_type_name(const TProtoStringType& value) { + _has_bits_[0] |= 0x00000004u; + type_name_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, value, GetArenaForAllocation()); +} +inline TProtoStringType* FieldDescriptorProto::_internal_mutable_type_name() { + _has_bits_[0] |= 0x00000004u; + return type_name_.Mutable(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, GetArenaForAllocation()); +} +inline TProtoStringType* FieldDescriptorProto::release_type_name() { + // @@protoc_insertion_point(field_release:google.protobuf.FieldDescriptorProto.type_name) + if (!_internal_has_type_name()) { + return nullptr; + } + _has_bits_[0] &= ~0x00000004u; + auto* p = type_name_.ReleaseNonDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArenaForAllocation()); +#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING + if (type_name_.IsDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited())) { + type_name_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation()); + } +#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING + return p; +} +inline void FieldDescriptorProto::set_allocated_type_name(TProtoStringType* type_name) { + if (type_name != nullptr) { + _has_bits_[0] |= 0x00000004u; + } else { + _has_bits_[0] &= ~0x00000004u; + } + type_name_.SetAllocated(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), type_name, + GetArenaForAllocation()); +#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING + if (type_name_.IsDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited())) { + type_name_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation()); + } +#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING + // @@protoc_insertion_point(field_set_allocated:google.protobuf.FieldDescriptorProto.type_name) +} + +// optional string extendee = 2; +inline bool FieldDescriptorProto::_internal_has_extendee() const { + bool value = (_has_bits_[0] & 0x00000002u) != 0; + return value; +} +inline bool FieldDescriptorProto::has_extendee() const { + return _internal_has_extendee(); +} +inline void FieldDescriptorProto::clear_extendee() { + extendee_.ClearToEmpty(); + _has_bits_[0] &= ~0x00000002u; +} +inline const TProtoStringType& FieldDescriptorProto::extendee() const { + // @@protoc_insertion_point(field_get:google.protobuf.FieldDescriptorProto.extendee) + return _internal_extendee(); +} +template <typename ArgT0, typename... ArgT> +inline PROTOBUF_ALWAYS_INLINE +void FieldDescriptorProto::set_extendee(ArgT0&& arg0, ArgT... args) { + _has_bits_[0] |= 0x00000002u; + extendee_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, static_cast<ArgT0 &&>(arg0), args..., GetArenaForAllocation()); + // @@protoc_insertion_point(field_set:google.protobuf.FieldDescriptorProto.extendee) +} +inline TProtoStringType* FieldDescriptorProto::mutable_extendee() { + TProtoStringType* _s = _internal_mutable_extendee(); + // @@protoc_insertion_point(field_mutable:google.protobuf.FieldDescriptorProto.extendee) + return _s; +} +inline const TProtoStringType& FieldDescriptorProto::_internal_extendee() const { + return extendee_.Get(); +} +inline void FieldDescriptorProto::_internal_set_extendee(const TProtoStringType& value) { + _has_bits_[0] |= 0x00000002u; + extendee_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, value, GetArenaForAllocation()); +} +inline TProtoStringType* FieldDescriptorProto::_internal_mutable_extendee() { + _has_bits_[0] |= 0x00000002u; + return extendee_.Mutable(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, GetArenaForAllocation()); +} +inline TProtoStringType* FieldDescriptorProto::release_extendee() { + // @@protoc_insertion_point(field_release:google.protobuf.FieldDescriptorProto.extendee) + if (!_internal_has_extendee()) { + return nullptr; + } + _has_bits_[0] &= ~0x00000002u; + auto* p = extendee_.ReleaseNonDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArenaForAllocation()); +#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING + if (extendee_.IsDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited())) { + extendee_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation()); + } +#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING + return p; +} +inline void FieldDescriptorProto::set_allocated_extendee(TProtoStringType* extendee) { + if (extendee != nullptr) { + _has_bits_[0] |= 0x00000002u; + } else { + _has_bits_[0] &= ~0x00000002u; + } + extendee_.SetAllocated(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), extendee, + GetArenaForAllocation()); +#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING + if (extendee_.IsDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited())) { + extendee_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation()); + } +#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING + // @@protoc_insertion_point(field_set_allocated:google.protobuf.FieldDescriptorProto.extendee) +} + +// optional string default_value = 7; +inline bool FieldDescriptorProto::_internal_has_default_value() const { + bool value = (_has_bits_[0] & 0x00000008u) != 0; + return value; +} +inline bool FieldDescriptorProto::has_default_value() const { + return _internal_has_default_value(); +} +inline void FieldDescriptorProto::clear_default_value() { + default_value_.ClearToEmpty(); + _has_bits_[0] &= ~0x00000008u; +} +inline const TProtoStringType& FieldDescriptorProto::default_value() const { + // @@protoc_insertion_point(field_get:google.protobuf.FieldDescriptorProto.default_value) + return _internal_default_value(); +} +template <typename ArgT0, typename... ArgT> +inline PROTOBUF_ALWAYS_INLINE +void FieldDescriptorProto::set_default_value(ArgT0&& arg0, ArgT... args) { + _has_bits_[0] |= 0x00000008u; + default_value_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, static_cast<ArgT0 &&>(arg0), args..., GetArenaForAllocation()); + // @@protoc_insertion_point(field_set:google.protobuf.FieldDescriptorProto.default_value) +} +inline TProtoStringType* FieldDescriptorProto::mutable_default_value() { + TProtoStringType* _s = _internal_mutable_default_value(); + // @@protoc_insertion_point(field_mutable:google.protobuf.FieldDescriptorProto.default_value) + return _s; +} +inline const TProtoStringType& FieldDescriptorProto::_internal_default_value() const { + return default_value_.Get(); +} +inline void FieldDescriptorProto::_internal_set_default_value(const TProtoStringType& value) { + _has_bits_[0] |= 0x00000008u; + default_value_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, value, GetArenaForAllocation()); +} +inline TProtoStringType* FieldDescriptorProto::_internal_mutable_default_value() { + _has_bits_[0] |= 0x00000008u; + return default_value_.Mutable(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, GetArenaForAllocation()); +} +inline TProtoStringType* FieldDescriptorProto::release_default_value() { + // @@protoc_insertion_point(field_release:google.protobuf.FieldDescriptorProto.default_value) + if (!_internal_has_default_value()) { + return nullptr; + } + _has_bits_[0] &= ~0x00000008u; + auto* p = default_value_.ReleaseNonDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArenaForAllocation()); +#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING + if (default_value_.IsDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited())) { + default_value_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation()); + } +#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING + return p; +} +inline void FieldDescriptorProto::set_allocated_default_value(TProtoStringType* default_value) { + if (default_value != nullptr) { + _has_bits_[0] |= 0x00000008u; + } else { + _has_bits_[0] &= ~0x00000008u; + } + default_value_.SetAllocated(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), default_value, + GetArenaForAllocation()); +#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING + if (default_value_.IsDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited())) { + default_value_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation()); + } +#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING + // @@protoc_insertion_point(field_set_allocated:google.protobuf.FieldDescriptorProto.default_value) +} + +// optional int32 oneof_index = 9; +inline bool FieldDescriptorProto::_internal_has_oneof_index() const { + bool value = (_has_bits_[0] & 0x00000080u) != 0; + return value; +} +inline bool FieldDescriptorProto::has_oneof_index() const { + return _internal_has_oneof_index(); +} +inline void FieldDescriptorProto::clear_oneof_index() { + oneof_index_ = 0; + _has_bits_[0] &= ~0x00000080u; +} +inline arc_i32 FieldDescriptorProto::_internal_oneof_index() const { + return oneof_index_; +} +inline arc_i32 FieldDescriptorProto::oneof_index() const { + // @@protoc_insertion_point(field_get:google.protobuf.FieldDescriptorProto.oneof_index) + return _internal_oneof_index(); +} +inline void FieldDescriptorProto::_internal_set_oneof_index(arc_i32 value) { + _has_bits_[0] |= 0x00000080u; + oneof_index_ = value; +} +inline void FieldDescriptorProto::set_oneof_index(arc_i32 value) { + _internal_set_oneof_index(value); + // @@protoc_insertion_point(field_set:google.protobuf.FieldDescriptorProto.oneof_index) +} + +// optional string json_name = 10; +inline bool FieldDescriptorProto::_internal_has_json_name() const { + bool value = (_has_bits_[0] & 0x00000010u) != 0; + return value; +} +inline bool FieldDescriptorProto::has_json_name() const { + return _internal_has_json_name(); +} +inline void FieldDescriptorProto::clear_json_name() { + json_name_.ClearToEmpty(); + _has_bits_[0] &= ~0x00000010u; +} +inline const TProtoStringType& FieldDescriptorProto::json_name() const { + // @@protoc_insertion_point(field_get:google.protobuf.FieldDescriptorProto.json_name) + return _internal_json_name(); +} +template <typename ArgT0, typename... ArgT> +inline PROTOBUF_ALWAYS_INLINE +void FieldDescriptorProto::set_json_name(ArgT0&& arg0, ArgT... args) { + _has_bits_[0] |= 0x00000010u; + json_name_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, static_cast<ArgT0 &&>(arg0), args..., GetArenaForAllocation()); + // @@protoc_insertion_point(field_set:google.protobuf.FieldDescriptorProto.json_name) +} +inline TProtoStringType* FieldDescriptorProto::mutable_json_name() { + TProtoStringType* _s = _internal_mutable_json_name(); + // @@protoc_insertion_point(field_mutable:google.protobuf.FieldDescriptorProto.json_name) + return _s; +} +inline const TProtoStringType& FieldDescriptorProto::_internal_json_name() const { + return json_name_.Get(); +} +inline void FieldDescriptorProto::_internal_set_json_name(const TProtoStringType& value) { + _has_bits_[0] |= 0x00000010u; + json_name_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, value, GetArenaForAllocation()); +} +inline TProtoStringType* FieldDescriptorProto::_internal_mutable_json_name() { + _has_bits_[0] |= 0x00000010u; + return json_name_.Mutable(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, GetArenaForAllocation()); +} +inline TProtoStringType* FieldDescriptorProto::release_json_name() { + // @@protoc_insertion_point(field_release:google.protobuf.FieldDescriptorProto.json_name) + if (!_internal_has_json_name()) { + return nullptr; + } + _has_bits_[0] &= ~0x00000010u; + auto* p = json_name_.ReleaseNonDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArenaForAllocation()); +#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING + if (json_name_.IsDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited())) { + json_name_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation()); + } +#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING + return p; +} +inline void FieldDescriptorProto::set_allocated_json_name(TProtoStringType* json_name) { + if (json_name != nullptr) { + _has_bits_[0] |= 0x00000010u; + } else { + _has_bits_[0] &= ~0x00000010u; + } + json_name_.SetAllocated(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), json_name, + GetArenaForAllocation()); +#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING + if (json_name_.IsDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited())) { + json_name_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation()); + } +#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING + // @@protoc_insertion_point(field_set_allocated:google.protobuf.FieldDescriptorProto.json_name) +} + +// optional .google.protobuf.FieldOptions options = 8; +inline bool FieldDescriptorProto::_internal_has_options() const { + bool value = (_has_bits_[0] & 0x00000020u) != 0; + PROTOBUF_ASSUME(!value || options_ != nullptr); + return value; +} +inline bool FieldDescriptorProto::has_options() const { + return _internal_has_options(); +} +inline void FieldDescriptorProto::clear_options() { + if (options_ != nullptr) options_->Clear(); + _has_bits_[0] &= ~0x00000020u; +} +inline const ::PROTOBUF_NAMESPACE_ID::FieldOptions& FieldDescriptorProto::_internal_options() const { + const ::PROTOBUF_NAMESPACE_ID::FieldOptions* p = options_; + return p != nullptr ? *p : reinterpret_cast<const ::PROTOBUF_NAMESPACE_ID::FieldOptions&>( + ::PROTOBUF_NAMESPACE_ID::_FieldOptions_default_instance_); +} +inline const ::PROTOBUF_NAMESPACE_ID::FieldOptions& FieldDescriptorProto::options() const { + // @@protoc_insertion_point(field_get:google.protobuf.FieldDescriptorProto.options) + return _internal_options(); +} +inline void FieldDescriptorProto::unsafe_arena_set_allocated_options( + ::PROTOBUF_NAMESPACE_ID::FieldOptions* options) { + if (GetArenaForAllocation() == nullptr) { + delete reinterpret_cast<::PROTOBUF_NAMESPACE_ID::MessageLite*>(options_); + } + options_ = options; + if (options) { + _has_bits_[0] |= 0x00000020u; + } else { + _has_bits_[0] &= ~0x00000020u; + } + // @@protoc_insertion_point(field_unsafe_arena_set_allocated:google.protobuf.FieldDescriptorProto.options) +} +inline ::PROTOBUF_NAMESPACE_ID::FieldOptions* FieldDescriptorProto::release_options() { + _has_bits_[0] &= ~0x00000020u; + ::PROTOBUF_NAMESPACE_ID::FieldOptions* temp = options_; + options_ = nullptr; +#ifdef PROTOBUF_FORCE_COPY_IN_RELEASE + auto* old = reinterpret_cast<::PROTOBUF_NAMESPACE_ID::MessageLite*>(temp); + temp = ::PROTOBUF_NAMESPACE_ID::internal::DuplicateIfNonNull(temp); + if (GetArenaForAllocation() == nullptr) { delete old; } +#else // PROTOBUF_FORCE_COPY_IN_RELEASE + if (GetArenaForAllocation() != nullptr) { + temp = ::PROTOBUF_NAMESPACE_ID::internal::DuplicateIfNonNull(temp); + } +#endif // !PROTOBUF_FORCE_COPY_IN_RELEASE + return temp; +} +inline ::PROTOBUF_NAMESPACE_ID::FieldOptions* FieldDescriptorProto::unsafe_arena_release_options() { + // @@protoc_insertion_point(field_release:google.protobuf.FieldDescriptorProto.options) + _has_bits_[0] &= ~0x00000020u; + ::PROTOBUF_NAMESPACE_ID::FieldOptions* temp = options_; + options_ = nullptr; + return temp; +} +inline ::PROTOBUF_NAMESPACE_ID::FieldOptions* FieldDescriptorProto::_internal_mutable_options() { + _has_bits_[0] |= 0x00000020u; + if (options_ == nullptr) { + auto* p = CreateMaybeMessage<::PROTOBUF_NAMESPACE_ID::FieldOptions>(GetArenaForAllocation()); + options_ = p; + } + return options_; +} +inline ::PROTOBUF_NAMESPACE_ID::FieldOptions* FieldDescriptorProto::mutable_options() { + ::PROTOBUF_NAMESPACE_ID::FieldOptions* _msg = _internal_mutable_options(); + // @@protoc_insertion_point(field_mutable:google.protobuf.FieldDescriptorProto.options) + return _msg; +} +inline void FieldDescriptorProto::set_allocated_options(::PROTOBUF_NAMESPACE_ID::FieldOptions* options) { + ::PROTOBUF_NAMESPACE_ID::Arena* message_arena = GetArenaForAllocation(); + if (message_arena == nullptr) { + delete options_; + } + if (options) { + ::PROTOBUF_NAMESPACE_ID::Arena* submessage_arena = + ::PROTOBUF_NAMESPACE_ID::Arena::InternalHelper<::PROTOBUF_NAMESPACE_ID::FieldOptions>::GetOwningArena(options); + if (message_arena != submessage_arena) { + options = ::PROTOBUF_NAMESPACE_ID::internal::GetOwnedMessage( + message_arena, options, submessage_arena); + } + _has_bits_[0] |= 0x00000020u; + } else { + _has_bits_[0] &= ~0x00000020u; + } + options_ = options; + // @@protoc_insertion_point(field_set_allocated:google.protobuf.FieldDescriptorProto.options) +} + +// optional bool proto3_optional = 17; +inline bool FieldDescriptorProto::_internal_has_proto3_optional() const { + bool value = (_has_bits_[0] & 0x00000100u) != 0; + return value; +} +inline bool FieldDescriptorProto::has_proto3_optional() const { + return _internal_has_proto3_optional(); +} +inline void FieldDescriptorProto::clear_proto3_optional() { + proto3_optional_ = false; + _has_bits_[0] &= ~0x00000100u; +} +inline bool FieldDescriptorProto::_internal_proto3_optional() const { + return proto3_optional_; +} +inline bool FieldDescriptorProto::proto3_optional() const { + // @@protoc_insertion_point(field_get:google.protobuf.FieldDescriptorProto.proto3_optional) + return _internal_proto3_optional(); +} +inline void FieldDescriptorProto::_internal_set_proto3_optional(bool value) { + _has_bits_[0] |= 0x00000100u; + proto3_optional_ = value; +} +inline void FieldDescriptorProto::set_proto3_optional(bool value) { + _internal_set_proto3_optional(value); + // @@protoc_insertion_point(field_set:google.protobuf.FieldDescriptorProto.proto3_optional) +} + +// ------------------------------------------------------------------- + +// OneofDescriptorProto + +// optional string name = 1; +inline bool OneofDescriptorProto::_internal_has_name() const { + bool value = (_has_bits_[0] & 0x00000001u) != 0; + return value; +} +inline bool OneofDescriptorProto::has_name() const { + return _internal_has_name(); +} +inline void OneofDescriptorProto::clear_name() { + name_.ClearToEmpty(); + _has_bits_[0] &= ~0x00000001u; +} +inline const TProtoStringType& OneofDescriptorProto::name() const { + // @@protoc_insertion_point(field_get:google.protobuf.OneofDescriptorProto.name) + return _internal_name(); +} +template <typename ArgT0, typename... ArgT> +inline PROTOBUF_ALWAYS_INLINE +void OneofDescriptorProto::set_name(ArgT0&& arg0, ArgT... args) { + _has_bits_[0] |= 0x00000001u; + name_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, static_cast<ArgT0 &&>(arg0), args..., GetArenaForAllocation()); + // @@protoc_insertion_point(field_set:google.protobuf.OneofDescriptorProto.name) +} +inline TProtoStringType* OneofDescriptorProto::mutable_name() { + TProtoStringType* _s = _internal_mutable_name(); + // @@protoc_insertion_point(field_mutable:google.protobuf.OneofDescriptorProto.name) + return _s; +} +inline const TProtoStringType& OneofDescriptorProto::_internal_name() const { + return name_.Get(); +} +inline void OneofDescriptorProto::_internal_set_name(const TProtoStringType& value) { + _has_bits_[0] |= 0x00000001u; + name_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, value, GetArenaForAllocation()); +} +inline TProtoStringType* OneofDescriptorProto::_internal_mutable_name() { + _has_bits_[0] |= 0x00000001u; + return name_.Mutable(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, GetArenaForAllocation()); +} +inline TProtoStringType* OneofDescriptorProto::release_name() { + // @@protoc_insertion_point(field_release:google.protobuf.OneofDescriptorProto.name) + if (!_internal_has_name()) { + return nullptr; + } + _has_bits_[0] &= ~0x00000001u; + auto* p = name_.ReleaseNonDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArenaForAllocation()); +#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING + if (name_.IsDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited())) { + name_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation()); + } +#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING + return p; +} +inline void OneofDescriptorProto::set_allocated_name(TProtoStringType* name) { + if (name != nullptr) { + _has_bits_[0] |= 0x00000001u; + } else { + _has_bits_[0] &= ~0x00000001u; + } + name_.SetAllocated(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), name, + GetArenaForAllocation()); +#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING + if (name_.IsDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited())) { + name_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation()); + } +#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING + // @@protoc_insertion_point(field_set_allocated:google.protobuf.OneofDescriptorProto.name) +} + +// optional .google.protobuf.OneofOptions options = 2; +inline bool OneofDescriptorProto::_internal_has_options() const { + bool value = (_has_bits_[0] & 0x00000002u) != 0; + PROTOBUF_ASSUME(!value || options_ != nullptr); + return value; +} +inline bool OneofDescriptorProto::has_options() const { + return _internal_has_options(); +} +inline void OneofDescriptorProto::clear_options() { + if (options_ != nullptr) options_->Clear(); + _has_bits_[0] &= ~0x00000002u; +} +inline const ::PROTOBUF_NAMESPACE_ID::OneofOptions& OneofDescriptorProto::_internal_options() const { + const ::PROTOBUF_NAMESPACE_ID::OneofOptions* p = options_; + return p != nullptr ? *p : reinterpret_cast<const ::PROTOBUF_NAMESPACE_ID::OneofOptions&>( + ::PROTOBUF_NAMESPACE_ID::_OneofOptions_default_instance_); +} +inline const ::PROTOBUF_NAMESPACE_ID::OneofOptions& OneofDescriptorProto::options() const { + // @@protoc_insertion_point(field_get:google.protobuf.OneofDescriptorProto.options) + return _internal_options(); +} +inline void OneofDescriptorProto::unsafe_arena_set_allocated_options( + ::PROTOBUF_NAMESPACE_ID::OneofOptions* options) { + if (GetArenaForAllocation() == nullptr) { + delete reinterpret_cast<::PROTOBUF_NAMESPACE_ID::MessageLite*>(options_); + } + options_ = options; + if (options) { + _has_bits_[0] |= 0x00000002u; + } else { + _has_bits_[0] &= ~0x00000002u; + } + // @@protoc_insertion_point(field_unsafe_arena_set_allocated:google.protobuf.OneofDescriptorProto.options) +} +inline ::PROTOBUF_NAMESPACE_ID::OneofOptions* OneofDescriptorProto::release_options() { + _has_bits_[0] &= ~0x00000002u; + ::PROTOBUF_NAMESPACE_ID::OneofOptions* temp = options_; + options_ = nullptr; +#ifdef PROTOBUF_FORCE_COPY_IN_RELEASE + auto* old = reinterpret_cast<::PROTOBUF_NAMESPACE_ID::MessageLite*>(temp); + temp = ::PROTOBUF_NAMESPACE_ID::internal::DuplicateIfNonNull(temp); + if (GetArenaForAllocation() == nullptr) { delete old; } +#else // PROTOBUF_FORCE_COPY_IN_RELEASE + if (GetArenaForAllocation() != nullptr) { + temp = ::PROTOBUF_NAMESPACE_ID::internal::DuplicateIfNonNull(temp); + } +#endif // !PROTOBUF_FORCE_COPY_IN_RELEASE + return temp; +} +inline ::PROTOBUF_NAMESPACE_ID::OneofOptions* OneofDescriptorProto::unsafe_arena_release_options() { + // @@protoc_insertion_point(field_release:google.protobuf.OneofDescriptorProto.options) + _has_bits_[0] &= ~0x00000002u; + ::PROTOBUF_NAMESPACE_ID::OneofOptions* temp = options_; + options_ = nullptr; + return temp; +} +inline ::PROTOBUF_NAMESPACE_ID::OneofOptions* OneofDescriptorProto::_internal_mutable_options() { + _has_bits_[0] |= 0x00000002u; + if (options_ == nullptr) { + auto* p = CreateMaybeMessage<::PROTOBUF_NAMESPACE_ID::OneofOptions>(GetArenaForAllocation()); + options_ = p; + } + return options_; +} +inline ::PROTOBUF_NAMESPACE_ID::OneofOptions* OneofDescriptorProto::mutable_options() { + ::PROTOBUF_NAMESPACE_ID::OneofOptions* _msg = _internal_mutable_options(); + // @@protoc_insertion_point(field_mutable:google.protobuf.OneofDescriptorProto.options) + return _msg; +} +inline void OneofDescriptorProto::set_allocated_options(::PROTOBUF_NAMESPACE_ID::OneofOptions* options) { + ::PROTOBUF_NAMESPACE_ID::Arena* message_arena = GetArenaForAllocation(); + if (message_arena == nullptr) { + delete options_; + } + if (options) { + ::PROTOBUF_NAMESPACE_ID::Arena* submessage_arena = + ::PROTOBUF_NAMESPACE_ID::Arena::InternalHelper<::PROTOBUF_NAMESPACE_ID::OneofOptions>::GetOwningArena(options); + if (message_arena != submessage_arena) { + options = ::PROTOBUF_NAMESPACE_ID::internal::GetOwnedMessage( + message_arena, options, submessage_arena); + } + _has_bits_[0] |= 0x00000002u; + } else { + _has_bits_[0] &= ~0x00000002u; + } + options_ = options; + // @@protoc_insertion_point(field_set_allocated:google.protobuf.OneofDescriptorProto.options) +} + +// ------------------------------------------------------------------- + +// EnumDescriptorProto_EnumReservedRange + +// optional int32 start = 1; +inline bool EnumDescriptorProto_EnumReservedRange::_internal_has_start() const { + bool value = (_has_bits_[0] & 0x00000001u) != 0; + return value; +} +inline bool EnumDescriptorProto_EnumReservedRange::has_start() const { + return _internal_has_start(); +} +inline void EnumDescriptorProto_EnumReservedRange::clear_start() { + start_ = 0; + _has_bits_[0] &= ~0x00000001u; +} +inline arc_i32 EnumDescriptorProto_EnumReservedRange::_internal_start() const { + return start_; +} +inline arc_i32 EnumDescriptorProto_EnumReservedRange::start() const { + // @@protoc_insertion_point(field_get:google.protobuf.EnumDescriptorProto.EnumReservedRange.start) + return _internal_start(); +} +inline void EnumDescriptorProto_EnumReservedRange::_internal_set_start(arc_i32 value) { + _has_bits_[0] |= 0x00000001u; + start_ = value; +} +inline void EnumDescriptorProto_EnumReservedRange::set_start(arc_i32 value) { + _internal_set_start(value); + // @@protoc_insertion_point(field_set:google.protobuf.EnumDescriptorProto.EnumReservedRange.start) +} + +// optional int32 end = 2; +inline bool EnumDescriptorProto_EnumReservedRange::_internal_has_end() const { + bool value = (_has_bits_[0] & 0x00000002u) != 0; + return value; +} +inline bool EnumDescriptorProto_EnumReservedRange::has_end() const { + return _internal_has_end(); +} +inline void EnumDescriptorProto_EnumReservedRange::clear_end() { + end_ = 0; + _has_bits_[0] &= ~0x00000002u; +} +inline arc_i32 EnumDescriptorProto_EnumReservedRange::_internal_end() const { + return end_; +} +inline arc_i32 EnumDescriptorProto_EnumReservedRange::end() const { + // @@protoc_insertion_point(field_get:google.protobuf.EnumDescriptorProto.EnumReservedRange.end) + return _internal_end(); +} +inline void EnumDescriptorProto_EnumReservedRange::_internal_set_end(arc_i32 value) { + _has_bits_[0] |= 0x00000002u; + end_ = value; +} +inline void EnumDescriptorProto_EnumReservedRange::set_end(arc_i32 value) { + _internal_set_end(value); + // @@protoc_insertion_point(field_set:google.protobuf.EnumDescriptorProto.EnumReservedRange.end) +} + +// ------------------------------------------------------------------- + +// EnumDescriptorProto + +// optional string name = 1; +inline bool EnumDescriptorProto::_internal_has_name() const { + bool value = (_has_bits_[0] & 0x00000001u) != 0; + return value; +} +inline bool EnumDescriptorProto::has_name() const { + return _internal_has_name(); +} +inline void EnumDescriptorProto::clear_name() { + name_.ClearToEmpty(); + _has_bits_[0] &= ~0x00000001u; +} +inline const TProtoStringType& EnumDescriptorProto::name() const { + // @@protoc_insertion_point(field_get:google.protobuf.EnumDescriptorProto.name) + return _internal_name(); +} +template <typename ArgT0, typename... ArgT> +inline PROTOBUF_ALWAYS_INLINE +void EnumDescriptorProto::set_name(ArgT0&& arg0, ArgT... args) { + _has_bits_[0] |= 0x00000001u; + name_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, static_cast<ArgT0 &&>(arg0), args..., GetArenaForAllocation()); + // @@protoc_insertion_point(field_set:google.protobuf.EnumDescriptorProto.name) +} +inline TProtoStringType* EnumDescriptorProto::mutable_name() { + TProtoStringType* _s = _internal_mutable_name(); + // @@protoc_insertion_point(field_mutable:google.protobuf.EnumDescriptorProto.name) + return _s; +} +inline const TProtoStringType& EnumDescriptorProto::_internal_name() const { + return name_.Get(); +} +inline void EnumDescriptorProto::_internal_set_name(const TProtoStringType& value) { + _has_bits_[0] |= 0x00000001u; + name_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, value, GetArenaForAllocation()); +} +inline TProtoStringType* EnumDescriptorProto::_internal_mutable_name() { + _has_bits_[0] |= 0x00000001u; + return name_.Mutable(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, GetArenaForAllocation()); +} +inline TProtoStringType* EnumDescriptorProto::release_name() { + // @@protoc_insertion_point(field_release:google.protobuf.EnumDescriptorProto.name) + if (!_internal_has_name()) { + return nullptr; + } + _has_bits_[0] &= ~0x00000001u; + auto* p = name_.ReleaseNonDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArenaForAllocation()); +#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING + if (name_.IsDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited())) { + name_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation()); + } +#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING + return p; +} +inline void EnumDescriptorProto::set_allocated_name(TProtoStringType* name) { + if (name != nullptr) { + _has_bits_[0] |= 0x00000001u; + } else { + _has_bits_[0] &= ~0x00000001u; + } + name_.SetAllocated(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), name, + GetArenaForAllocation()); +#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING + if (name_.IsDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited())) { + name_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation()); + } +#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING + // @@protoc_insertion_point(field_set_allocated:google.protobuf.EnumDescriptorProto.name) +} + +// repeated .google.protobuf.EnumValueDescriptorProto value = 2; +inline int EnumDescriptorProto::_internal_value_size() const { + return value_.size(); +} +inline int EnumDescriptorProto::value_size() const { + return _internal_value_size(); +} +inline void EnumDescriptorProto::clear_value() { + value_.Clear(); +} +inline ::PROTOBUF_NAMESPACE_ID::EnumValueDescriptorProto* EnumDescriptorProto::mutable_value(int index) { + // @@protoc_insertion_point(field_mutable:google.protobuf.EnumDescriptorProto.value) + return value_.Mutable(index); +} +inline ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::EnumValueDescriptorProto >* +EnumDescriptorProto::mutable_value() { + // @@protoc_insertion_point(field_mutable_list:google.protobuf.EnumDescriptorProto.value) + return &value_; +} +inline const ::PROTOBUF_NAMESPACE_ID::EnumValueDescriptorProto& EnumDescriptorProto::_internal_value(int index) const { + return value_.Get(index); +} +inline const ::PROTOBUF_NAMESPACE_ID::EnumValueDescriptorProto& EnumDescriptorProto::value(int index) const { + // @@protoc_insertion_point(field_get:google.protobuf.EnumDescriptorProto.value) + return _internal_value(index); +} +inline ::PROTOBUF_NAMESPACE_ID::EnumValueDescriptorProto* EnumDescriptorProto::_internal_add_value() { + return value_.Add(); +} +inline ::PROTOBUF_NAMESPACE_ID::EnumValueDescriptorProto* EnumDescriptorProto::add_value() { + ::PROTOBUF_NAMESPACE_ID::EnumValueDescriptorProto* _add = _internal_add_value(); + // @@protoc_insertion_point(field_add:google.protobuf.EnumDescriptorProto.value) + return _add; +} +inline const ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::EnumValueDescriptorProto >& +EnumDescriptorProto::value() const { + // @@protoc_insertion_point(field_list:google.protobuf.EnumDescriptorProto.value) + return value_; +} + +// optional .google.protobuf.EnumOptions options = 3; +inline bool EnumDescriptorProto::_internal_has_options() const { + bool value = (_has_bits_[0] & 0x00000002u) != 0; + PROTOBUF_ASSUME(!value || options_ != nullptr); + return value; +} +inline bool EnumDescriptorProto::has_options() const { + return _internal_has_options(); +} +inline void EnumDescriptorProto::clear_options() { + if (options_ != nullptr) options_->Clear(); + _has_bits_[0] &= ~0x00000002u; +} +inline const ::PROTOBUF_NAMESPACE_ID::EnumOptions& EnumDescriptorProto::_internal_options() const { + const ::PROTOBUF_NAMESPACE_ID::EnumOptions* p = options_; + return p != nullptr ? *p : reinterpret_cast<const ::PROTOBUF_NAMESPACE_ID::EnumOptions&>( + ::PROTOBUF_NAMESPACE_ID::_EnumOptions_default_instance_); +} +inline const ::PROTOBUF_NAMESPACE_ID::EnumOptions& EnumDescriptorProto::options() const { + // @@protoc_insertion_point(field_get:google.protobuf.EnumDescriptorProto.options) + return _internal_options(); +} +inline void EnumDescriptorProto::unsafe_arena_set_allocated_options( + ::PROTOBUF_NAMESPACE_ID::EnumOptions* options) { + if (GetArenaForAllocation() == nullptr) { + delete reinterpret_cast<::PROTOBUF_NAMESPACE_ID::MessageLite*>(options_); + } + options_ = options; + if (options) { + _has_bits_[0] |= 0x00000002u; + } else { + _has_bits_[0] &= ~0x00000002u; + } + // @@protoc_insertion_point(field_unsafe_arena_set_allocated:google.protobuf.EnumDescriptorProto.options) +} +inline ::PROTOBUF_NAMESPACE_ID::EnumOptions* EnumDescriptorProto::release_options() { + _has_bits_[0] &= ~0x00000002u; + ::PROTOBUF_NAMESPACE_ID::EnumOptions* temp = options_; + options_ = nullptr; +#ifdef PROTOBUF_FORCE_COPY_IN_RELEASE + auto* old = reinterpret_cast<::PROTOBUF_NAMESPACE_ID::MessageLite*>(temp); + temp = ::PROTOBUF_NAMESPACE_ID::internal::DuplicateIfNonNull(temp); + if (GetArenaForAllocation() == nullptr) { delete old; } +#else // PROTOBUF_FORCE_COPY_IN_RELEASE + if (GetArenaForAllocation() != nullptr) { + temp = ::PROTOBUF_NAMESPACE_ID::internal::DuplicateIfNonNull(temp); + } +#endif // !PROTOBUF_FORCE_COPY_IN_RELEASE + return temp; +} +inline ::PROTOBUF_NAMESPACE_ID::EnumOptions* EnumDescriptorProto::unsafe_arena_release_options() { + // @@protoc_insertion_point(field_release:google.protobuf.EnumDescriptorProto.options) + _has_bits_[0] &= ~0x00000002u; + ::PROTOBUF_NAMESPACE_ID::EnumOptions* temp = options_; + options_ = nullptr; + return temp; +} +inline ::PROTOBUF_NAMESPACE_ID::EnumOptions* EnumDescriptorProto::_internal_mutable_options() { + _has_bits_[0] |= 0x00000002u; + if (options_ == nullptr) { + auto* p = CreateMaybeMessage<::PROTOBUF_NAMESPACE_ID::EnumOptions>(GetArenaForAllocation()); + options_ = p; + } + return options_; +} +inline ::PROTOBUF_NAMESPACE_ID::EnumOptions* EnumDescriptorProto::mutable_options() { + ::PROTOBUF_NAMESPACE_ID::EnumOptions* _msg = _internal_mutable_options(); + // @@protoc_insertion_point(field_mutable:google.protobuf.EnumDescriptorProto.options) + return _msg; +} +inline void EnumDescriptorProto::set_allocated_options(::PROTOBUF_NAMESPACE_ID::EnumOptions* options) { + ::PROTOBUF_NAMESPACE_ID::Arena* message_arena = GetArenaForAllocation(); + if (message_arena == nullptr) { + delete options_; + } + if (options) { + ::PROTOBUF_NAMESPACE_ID::Arena* submessage_arena = + ::PROTOBUF_NAMESPACE_ID::Arena::InternalHelper<::PROTOBUF_NAMESPACE_ID::EnumOptions>::GetOwningArena(options); + if (message_arena != submessage_arena) { + options = ::PROTOBUF_NAMESPACE_ID::internal::GetOwnedMessage( + message_arena, options, submessage_arena); + } + _has_bits_[0] |= 0x00000002u; + } else { + _has_bits_[0] &= ~0x00000002u; + } + options_ = options; + // @@protoc_insertion_point(field_set_allocated:google.protobuf.EnumDescriptorProto.options) +} + +// repeated .google.protobuf.EnumDescriptorProto.EnumReservedRange reserved_range = 4; +inline int EnumDescriptorProto::_internal_reserved_range_size() const { + return reserved_range_.size(); +} +inline int EnumDescriptorProto::reserved_range_size() const { + return _internal_reserved_range_size(); +} +inline void EnumDescriptorProto::clear_reserved_range() { + reserved_range_.Clear(); +} +inline ::PROTOBUF_NAMESPACE_ID::EnumDescriptorProto_EnumReservedRange* EnumDescriptorProto::mutable_reserved_range(int index) { + // @@protoc_insertion_point(field_mutable:google.protobuf.EnumDescriptorProto.reserved_range) + return reserved_range_.Mutable(index); +} +inline ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::EnumDescriptorProto_EnumReservedRange >* +EnumDescriptorProto::mutable_reserved_range() { + // @@protoc_insertion_point(field_mutable_list:google.protobuf.EnumDescriptorProto.reserved_range) + return &reserved_range_; +} +inline const ::PROTOBUF_NAMESPACE_ID::EnumDescriptorProto_EnumReservedRange& EnumDescriptorProto::_internal_reserved_range(int index) const { + return reserved_range_.Get(index); +} +inline const ::PROTOBUF_NAMESPACE_ID::EnumDescriptorProto_EnumReservedRange& EnumDescriptorProto::reserved_range(int index) const { + // @@protoc_insertion_point(field_get:google.protobuf.EnumDescriptorProto.reserved_range) + return _internal_reserved_range(index); +} +inline ::PROTOBUF_NAMESPACE_ID::EnumDescriptorProto_EnumReservedRange* EnumDescriptorProto::_internal_add_reserved_range() { + return reserved_range_.Add(); +} +inline ::PROTOBUF_NAMESPACE_ID::EnumDescriptorProto_EnumReservedRange* EnumDescriptorProto::add_reserved_range() { + ::PROTOBUF_NAMESPACE_ID::EnumDescriptorProto_EnumReservedRange* _add = _internal_add_reserved_range(); + // @@protoc_insertion_point(field_add:google.protobuf.EnumDescriptorProto.reserved_range) + return _add; +} +inline const ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::EnumDescriptorProto_EnumReservedRange >& +EnumDescriptorProto::reserved_range() const { + // @@protoc_insertion_point(field_list:google.protobuf.EnumDescriptorProto.reserved_range) + return reserved_range_; +} + +// repeated string reserved_name = 5; +inline int EnumDescriptorProto::_internal_reserved_name_size() const { + return reserved_name_.size(); +} +inline int EnumDescriptorProto::reserved_name_size() const { + return _internal_reserved_name_size(); +} +inline void EnumDescriptorProto::clear_reserved_name() { + reserved_name_.Clear(); +} +inline TProtoStringType* EnumDescriptorProto::add_reserved_name() { + TProtoStringType* _s = _internal_add_reserved_name(); + // @@protoc_insertion_point(field_add_mutable:google.protobuf.EnumDescriptorProto.reserved_name) + return _s; +} +inline const TProtoStringType& EnumDescriptorProto::_internal_reserved_name(int index) const { + return reserved_name_.Get(index); +} +inline const TProtoStringType& EnumDescriptorProto::reserved_name(int index) const { + // @@protoc_insertion_point(field_get:google.protobuf.EnumDescriptorProto.reserved_name) + return _internal_reserved_name(index); +} +inline TProtoStringType* EnumDescriptorProto::mutable_reserved_name(int index) { + // @@protoc_insertion_point(field_mutable:google.protobuf.EnumDescriptorProto.reserved_name) + return reserved_name_.Mutable(index); +} +inline void EnumDescriptorProto::set_reserved_name(int index, const TProtoStringType& value) { + reserved_name_.Mutable(index)->assign(value); + // @@protoc_insertion_point(field_set:google.protobuf.EnumDescriptorProto.reserved_name) +} +inline void EnumDescriptorProto::set_reserved_name(int index, TProtoStringType&& value) { + reserved_name_.Mutable(index)->assign(std::move(value)); + // @@protoc_insertion_point(field_set:google.protobuf.EnumDescriptorProto.reserved_name) +} +inline void EnumDescriptorProto::set_reserved_name(int index, const char* value) { + GOOGLE_DCHECK(value != nullptr); + reserved_name_.Mutable(index)->assign(value); + // @@protoc_insertion_point(field_set_char:google.protobuf.EnumDescriptorProto.reserved_name) +} +inline void EnumDescriptorProto::set_reserved_name(int index, const char* value, size_t size) { + reserved_name_.Mutable(index)->assign( + reinterpret_cast<const char*>(value), size); + // @@protoc_insertion_point(field_set_pointer:google.protobuf.EnumDescriptorProto.reserved_name) +} +inline TProtoStringType* EnumDescriptorProto::_internal_add_reserved_name() { + return reserved_name_.Add(); +} +inline void EnumDescriptorProto::add_reserved_name(const TProtoStringType& value) { + reserved_name_.Add()->assign(value); + // @@protoc_insertion_point(field_add:google.protobuf.EnumDescriptorProto.reserved_name) +} +inline void EnumDescriptorProto::add_reserved_name(TProtoStringType&& value) { + reserved_name_.Add(std::move(value)); + // @@protoc_insertion_point(field_add:google.protobuf.EnumDescriptorProto.reserved_name) +} +inline void EnumDescriptorProto::add_reserved_name(const char* value) { + GOOGLE_DCHECK(value != nullptr); + reserved_name_.Add()->assign(value); + // @@protoc_insertion_point(field_add_char:google.protobuf.EnumDescriptorProto.reserved_name) +} +inline void EnumDescriptorProto::add_reserved_name(const char* value, size_t size) { + reserved_name_.Add()->assign(reinterpret_cast<const char*>(value), size); + // @@protoc_insertion_point(field_add_pointer:google.protobuf.EnumDescriptorProto.reserved_name) +} +inline const ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField<TProtoStringType>& +EnumDescriptorProto::reserved_name() const { + // @@protoc_insertion_point(field_list:google.protobuf.EnumDescriptorProto.reserved_name) + return reserved_name_; +} +inline ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField<TProtoStringType>* +EnumDescriptorProto::mutable_reserved_name() { + // @@protoc_insertion_point(field_mutable_list:google.protobuf.EnumDescriptorProto.reserved_name) + return &reserved_name_; +} + +// ------------------------------------------------------------------- + +// EnumValueDescriptorProto + +// optional string name = 1; +inline bool EnumValueDescriptorProto::_internal_has_name() const { + bool value = (_has_bits_[0] & 0x00000001u) != 0; + return value; +} +inline bool EnumValueDescriptorProto::has_name() const { + return _internal_has_name(); +} +inline void EnumValueDescriptorProto::clear_name() { + name_.ClearToEmpty(); + _has_bits_[0] &= ~0x00000001u; +} +inline const TProtoStringType& EnumValueDescriptorProto::name() const { + // @@protoc_insertion_point(field_get:google.protobuf.EnumValueDescriptorProto.name) + return _internal_name(); +} +template <typename ArgT0, typename... ArgT> +inline PROTOBUF_ALWAYS_INLINE +void EnumValueDescriptorProto::set_name(ArgT0&& arg0, ArgT... args) { + _has_bits_[0] |= 0x00000001u; + name_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, static_cast<ArgT0 &&>(arg0), args..., GetArenaForAllocation()); + // @@protoc_insertion_point(field_set:google.protobuf.EnumValueDescriptorProto.name) +} +inline TProtoStringType* EnumValueDescriptorProto::mutable_name() { + TProtoStringType* _s = _internal_mutable_name(); + // @@protoc_insertion_point(field_mutable:google.protobuf.EnumValueDescriptorProto.name) + return _s; +} +inline const TProtoStringType& EnumValueDescriptorProto::_internal_name() const { + return name_.Get(); +} +inline void EnumValueDescriptorProto::_internal_set_name(const TProtoStringType& value) { + _has_bits_[0] |= 0x00000001u; + name_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, value, GetArenaForAllocation()); +} +inline TProtoStringType* EnumValueDescriptorProto::_internal_mutable_name() { + _has_bits_[0] |= 0x00000001u; + return name_.Mutable(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, GetArenaForAllocation()); +} +inline TProtoStringType* EnumValueDescriptorProto::release_name() { + // @@protoc_insertion_point(field_release:google.protobuf.EnumValueDescriptorProto.name) + if (!_internal_has_name()) { + return nullptr; + } + _has_bits_[0] &= ~0x00000001u; + auto* p = name_.ReleaseNonDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArenaForAllocation()); +#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING + if (name_.IsDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited())) { + name_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation()); + } +#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING + return p; +} +inline void EnumValueDescriptorProto::set_allocated_name(TProtoStringType* name) { + if (name != nullptr) { + _has_bits_[0] |= 0x00000001u; + } else { + _has_bits_[0] &= ~0x00000001u; + } + name_.SetAllocated(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), name, + GetArenaForAllocation()); +#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING + if (name_.IsDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited())) { + name_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation()); + } +#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING + // @@protoc_insertion_point(field_set_allocated:google.protobuf.EnumValueDescriptorProto.name) +} + +// optional int32 number = 2; +inline bool EnumValueDescriptorProto::_internal_has_number() const { + bool value = (_has_bits_[0] & 0x00000004u) != 0; + return value; +} +inline bool EnumValueDescriptorProto::has_number() const { + return _internal_has_number(); +} +inline void EnumValueDescriptorProto::clear_number() { + number_ = 0; + _has_bits_[0] &= ~0x00000004u; +} +inline arc_i32 EnumValueDescriptorProto::_internal_number() const { + return number_; +} +inline arc_i32 EnumValueDescriptorProto::number() const { + // @@protoc_insertion_point(field_get:google.protobuf.EnumValueDescriptorProto.number) + return _internal_number(); +} +inline void EnumValueDescriptorProto::_internal_set_number(arc_i32 value) { + _has_bits_[0] |= 0x00000004u; + number_ = value; +} +inline void EnumValueDescriptorProto::set_number(arc_i32 value) { + _internal_set_number(value); + // @@protoc_insertion_point(field_set:google.protobuf.EnumValueDescriptorProto.number) +} + +// optional .google.protobuf.EnumValueOptions options = 3; +inline bool EnumValueDescriptorProto::_internal_has_options() const { + bool value = (_has_bits_[0] & 0x00000002u) != 0; + PROTOBUF_ASSUME(!value || options_ != nullptr); + return value; +} +inline bool EnumValueDescriptorProto::has_options() const { + return _internal_has_options(); +} +inline void EnumValueDescriptorProto::clear_options() { + if (options_ != nullptr) options_->Clear(); + _has_bits_[0] &= ~0x00000002u; +} +inline const ::PROTOBUF_NAMESPACE_ID::EnumValueOptions& EnumValueDescriptorProto::_internal_options() const { + const ::PROTOBUF_NAMESPACE_ID::EnumValueOptions* p = options_; + return p != nullptr ? *p : reinterpret_cast<const ::PROTOBUF_NAMESPACE_ID::EnumValueOptions&>( + ::PROTOBUF_NAMESPACE_ID::_EnumValueOptions_default_instance_); +} +inline const ::PROTOBUF_NAMESPACE_ID::EnumValueOptions& EnumValueDescriptorProto::options() const { + // @@protoc_insertion_point(field_get:google.protobuf.EnumValueDescriptorProto.options) + return _internal_options(); +} +inline void EnumValueDescriptorProto::unsafe_arena_set_allocated_options( + ::PROTOBUF_NAMESPACE_ID::EnumValueOptions* options) { + if (GetArenaForAllocation() == nullptr) { + delete reinterpret_cast<::PROTOBUF_NAMESPACE_ID::MessageLite*>(options_); + } + options_ = options; + if (options) { + _has_bits_[0] |= 0x00000002u; + } else { + _has_bits_[0] &= ~0x00000002u; + } + // @@protoc_insertion_point(field_unsafe_arena_set_allocated:google.protobuf.EnumValueDescriptorProto.options) +} +inline ::PROTOBUF_NAMESPACE_ID::EnumValueOptions* EnumValueDescriptorProto::release_options() { + _has_bits_[0] &= ~0x00000002u; + ::PROTOBUF_NAMESPACE_ID::EnumValueOptions* temp = options_; + options_ = nullptr; +#ifdef PROTOBUF_FORCE_COPY_IN_RELEASE + auto* old = reinterpret_cast<::PROTOBUF_NAMESPACE_ID::MessageLite*>(temp); + temp = ::PROTOBUF_NAMESPACE_ID::internal::DuplicateIfNonNull(temp); + if (GetArenaForAllocation() == nullptr) { delete old; } +#else // PROTOBUF_FORCE_COPY_IN_RELEASE + if (GetArenaForAllocation() != nullptr) { + temp = ::PROTOBUF_NAMESPACE_ID::internal::DuplicateIfNonNull(temp); + } +#endif // !PROTOBUF_FORCE_COPY_IN_RELEASE + return temp; +} +inline ::PROTOBUF_NAMESPACE_ID::EnumValueOptions* EnumValueDescriptorProto::unsafe_arena_release_options() { + // @@protoc_insertion_point(field_release:google.protobuf.EnumValueDescriptorProto.options) + _has_bits_[0] &= ~0x00000002u; + ::PROTOBUF_NAMESPACE_ID::EnumValueOptions* temp = options_; + options_ = nullptr; + return temp; +} +inline ::PROTOBUF_NAMESPACE_ID::EnumValueOptions* EnumValueDescriptorProto::_internal_mutable_options() { + _has_bits_[0] |= 0x00000002u; + if (options_ == nullptr) { + auto* p = CreateMaybeMessage<::PROTOBUF_NAMESPACE_ID::EnumValueOptions>(GetArenaForAllocation()); + options_ = p; + } + return options_; +} +inline ::PROTOBUF_NAMESPACE_ID::EnumValueOptions* EnumValueDescriptorProto::mutable_options() { + ::PROTOBUF_NAMESPACE_ID::EnumValueOptions* _msg = _internal_mutable_options(); + // @@protoc_insertion_point(field_mutable:google.protobuf.EnumValueDescriptorProto.options) + return _msg; +} +inline void EnumValueDescriptorProto::set_allocated_options(::PROTOBUF_NAMESPACE_ID::EnumValueOptions* options) { + ::PROTOBUF_NAMESPACE_ID::Arena* message_arena = GetArenaForAllocation(); + if (message_arena == nullptr) { + delete options_; + } + if (options) { + ::PROTOBUF_NAMESPACE_ID::Arena* submessage_arena = + ::PROTOBUF_NAMESPACE_ID::Arena::InternalHelper<::PROTOBUF_NAMESPACE_ID::EnumValueOptions>::GetOwningArena(options); + if (message_arena != submessage_arena) { + options = ::PROTOBUF_NAMESPACE_ID::internal::GetOwnedMessage( + message_arena, options, submessage_arena); + } + _has_bits_[0] |= 0x00000002u; + } else { + _has_bits_[0] &= ~0x00000002u; + } + options_ = options; + // @@protoc_insertion_point(field_set_allocated:google.protobuf.EnumValueDescriptorProto.options) +} + +// ------------------------------------------------------------------- + +// ServiceDescriptorProto + +// optional string name = 1; +inline bool ServiceDescriptorProto::_internal_has_name() const { + bool value = (_has_bits_[0] & 0x00000001u) != 0; + return value; +} +inline bool ServiceDescriptorProto::has_name() const { + return _internal_has_name(); +} +inline void ServiceDescriptorProto::clear_name() { + name_.ClearToEmpty(); + _has_bits_[0] &= ~0x00000001u; +} +inline const TProtoStringType& ServiceDescriptorProto::name() const { + // @@protoc_insertion_point(field_get:google.protobuf.ServiceDescriptorProto.name) + return _internal_name(); +} +template <typename ArgT0, typename... ArgT> +inline PROTOBUF_ALWAYS_INLINE +void ServiceDescriptorProto::set_name(ArgT0&& arg0, ArgT... args) { + _has_bits_[0] |= 0x00000001u; + name_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, static_cast<ArgT0 &&>(arg0), args..., GetArenaForAllocation()); + // @@protoc_insertion_point(field_set:google.protobuf.ServiceDescriptorProto.name) +} +inline TProtoStringType* ServiceDescriptorProto::mutable_name() { + TProtoStringType* _s = _internal_mutable_name(); + // @@protoc_insertion_point(field_mutable:google.protobuf.ServiceDescriptorProto.name) + return _s; +} +inline const TProtoStringType& ServiceDescriptorProto::_internal_name() const { + return name_.Get(); +} +inline void ServiceDescriptorProto::_internal_set_name(const TProtoStringType& value) { + _has_bits_[0] |= 0x00000001u; + name_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, value, GetArenaForAllocation()); +} +inline TProtoStringType* ServiceDescriptorProto::_internal_mutable_name() { + _has_bits_[0] |= 0x00000001u; + return name_.Mutable(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, GetArenaForAllocation()); +} +inline TProtoStringType* ServiceDescriptorProto::release_name() { + // @@protoc_insertion_point(field_release:google.protobuf.ServiceDescriptorProto.name) + if (!_internal_has_name()) { + return nullptr; + } + _has_bits_[0] &= ~0x00000001u; + auto* p = name_.ReleaseNonDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArenaForAllocation()); +#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING + if (name_.IsDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited())) { + name_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation()); + } +#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING + return p; +} +inline void ServiceDescriptorProto::set_allocated_name(TProtoStringType* name) { + if (name != nullptr) { + _has_bits_[0] |= 0x00000001u; + } else { + _has_bits_[0] &= ~0x00000001u; + } + name_.SetAllocated(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), name, + GetArenaForAllocation()); +#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING + if (name_.IsDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited())) { + name_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation()); + } +#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING + // @@protoc_insertion_point(field_set_allocated:google.protobuf.ServiceDescriptorProto.name) +} + +// repeated .google.protobuf.MethodDescriptorProto method = 2; +inline int ServiceDescriptorProto::_internal_method_size() const { + return method_.size(); +} +inline int ServiceDescriptorProto::method_size() const { + return _internal_method_size(); +} +inline void ServiceDescriptorProto::clear_method() { + method_.Clear(); +} +inline ::PROTOBUF_NAMESPACE_ID::MethodDescriptorProto* ServiceDescriptorProto::mutable_method(int index) { + // @@protoc_insertion_point(field_mutable:google.protobuf.ServiceDescriptorProto.method) + return method_.Mutable(index); +} +inline ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::MethodDescriptorProto >* +ServiceDescriptorProto::mutable_method() { + // @@protoc_insertion_point(field_mutable_list:google.protobuf.ServiceDescriptorProto.method) + return &method_; +} +inline const ::PROTOBUF_NAMESPACE_ID::MethodDescriptorProto& ServiceDescriptorProto::_internal_method(int index) const { + return method_.Get(index); +} +inline const ::PROTOBUF_NAMESPACE_ID::MethodDescriptorProto& ServiceDescriptorProto::method(int index) const { + // @@protoc_insertion_point(field_get:google.protobuf.ServiceDescriptorProto.method) + return _internal_method(index); +} +inline ::PROTOBUF_NAMESPACE_ID::MethodDescriptorProto* ServiceDescriptorProto::_internal_add_method() { + return method_.Add(); +} +inline ::PROTOBUF_NAMESPACE_ID::MethodDescriptorProto* ServiceDescriptorProto::add_method() { + ::PROTOBUF_NAMESPACE_ID::MethodDescriptorProto* _add = _internal_add_method(); + // @@protoc_insertion_point(field_add:google.protobuf.ServiceDescriptorProto.method) + return _add; +} +inline const ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::MethodDescriptorProto >& +ServiceDescriptorProto::method() const { + // @@protoc_insertion_point(field_list:google.protobuf.ServiceDescriptorProto.method) + return method_; +} + +// optional .google.protobuf.ServiceOptions options = 3; +inline bool ServiceDescriptorProto::_internal_has_options() const { + bool value = (_has_bits_[0] & 0x00000002u) != 0; + PROTOBUF_ASSUME(!value || options_ != nullptr); + return value; +} +inline bool ServiceDescriptorProto::has_options() const { + return _internal_has_options(); +} +inline void ServiceDescriptorProto::clear_options() { + if (options_ != nullptr) options_->Clear(); + _has_bits_[0] &= ~0x00000002u; +} +inline const ::PROTOBUF_NAMESPACE_ID::ServiceOptions& ServiceDescriptorProto::_internal_options() const { + const ::PROTOBUF_NAMESPACE_ID::ServiceOptions* p = options_; + return p != nullptr ? *p : reinterpret_cast<const ::PROTOBUF_NAMESPACE_ID::ServiceOptions&>( + ::PROTOBUF_NAMESPACE_ID::_ServiceOptions_default_instance_); +} +inline const ::PROTOBUF_NAMESPACE_ID::ServiceOptions& ServiceDescriptorProto::options() const { + // @@protoc_insertion_point(field_get:google.protobuf.ServiceDescriptorProto.options) + return _internal_options(); +} +inline void ServiceDescriptorProto::unsafe_arena_set_allocated_options( + ::PROTOBUF_NAMESPACE_ID::ServiceOptions* options) { + if (GetArenaForAllocation() == nullptr) { + delete reinterpret_cast<::PROTOBUF_NAMESPACE_ID::MessageLite*>(options_); + } + options_ = options; + if (options) { + _has_bits_[0] |= 0x00000002u; + } else { + _has_bits_[0] &= ~0x00000002u; + } + // @@protoc_insertion_point(field_unsafe_arena_set_allocated:google.protobuf.ServiceDescriptorProto.options) +} +inline ::PROTOBUF_NAMESPACE_ID::ServiceOptions* ServiceDescriptorProto::release_options() { + _has_bits_[0] &= ~0x00000002u; + ::PROTOBUF_NAMESPACE_ID::ServiceOptions* temp = options_; + options_ = nullptr; +#ifdef PROTOBUF_FORCE_COPY_IN_RELEASE + auto* old = reinterpret_cast<::PROTOBUF_NAMESPACE_ID::MessageLite*>(temp); + temp = ::PROTOBUF_NAMESPACE_ID::internal::DuplicateIfNonNull(temp); + if (GetArenaForAllocation() == nullptr) { delete old; } +#else // PROTOBUF_FORCE_COPY_IN_RELEASE + if (GetArenaForAllocation() != nullptr) { + temp = ::PROTOBUF_NAMESPACE_ID::internal::DuplicateIfNonNull(temp); + } +#endif // !PROTOBUF_FORCE_COPY_IN_RELEASE + return temp; +} +inline ::PROTOBUF_NAMESPACE_ID::ServiceOptions* ServiceDescriptorProto::unsafe_arena_release_options() { + // @@protoc_insertion_point(field_release:google.protobuf.ServiceDescriptorProto.options) + _has_bits_[0] &= ~0x00000002u; + ::PROTOBUF_NAMESPACE_ID::ServiceOptions* temp = options_; + options_ = nullptr; + return temp; +} +inline ::PROTOBUF_NAMESPACE_ID::ServiceOptions* ServiceDescriptorProto::_internal_mutable_options() { + _has_bits_[0] |= 0x00000002u; + if (options_ == nullptr) { + auto* p = CreateMaybeMessage<::PROTOBUF_NAMESPACE_ID::ServiceOptions>(GetArenaForAllocation()); + options_ = p; + } + return options_; +} +inline ::PROTOBUF_NAMESPACE_ID::ServiceOptions* ServiceDescriptorProto::mutable_options() { + ::PROTOBUF_NAMESPACE_ID::ServiceOptions* _msg = _internal_mutable_options(); + // @@protoc_insertion_point(field_mutable:google.protobuf.ServiceDescriptorProto.options) + return _msg; +} +inline void ServiceDescriptorProto::set_allocated_options(::PROTOBUF_NAMESPACE_ID::ServiceOptions* options) { + ::PROTOBUF_NAMESPACE_ID::Arena* message_arena = GetArenaForAllocation(); + if (message_arena == nullptr) { + delete options_; + } + if (options) { + ::PROTOBUF_NAMESPACE_ID::Arena* submessage_arena = + ::PROTOBUF_NAMESPACE_ID::Arena::InternalHelper<::PROTOBUF_NAMESPACE_ID::ServiceOptions>::GetOwningArena(options); + if (message_arena != submessage_arena) { + options = ::PROTOBUF_NAMESPACE_ID::internal::GetOwnedMessage( + message_arena, options, submessage_arena); + } + _has_bits_[0] |= 0x00000002u; + } else { + _has_bits_[0] &= ~0x00000002u; + } + options_ = options; + // @@protoc_insertion_point(field_set_allocated:google.protobuf.ServiceDescriptorProto.options) +} + +// ------------------------------------------------------------------- + +// MethodDescriptorProto + +// optional string name = 1; +inline bool MethodDescriptorProto::_internal_has_name() const { + bool value = (_has_bits_[0] & 0x00000001u) != 0; + return value; +} +inline bool MethodDescriptorProto::has_name() const { + return _internal_has_name(); +} +inline void MethodDescriptorProto::clear_name() { + name_.ClearToEmpty(); + _has_bits_[0] &= ~0x00000001u; +} +inline const TProtoStringType& MethodDescriptorProto::name() const { + // @@protoc_insertion_point(field_get:google.protobuf.MethodDescriptorProto.name) + return _internal_name(); +} +template <typename ArgT0, typename... ArgT> +inline PROTOBUF_ALWAYS_INLINE +void MethodDescriptorProto::set_name(ArgT0&& arg0, ArgT... args) { + _has_bits_[0] |= 0x00000001u; + name_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, static_cast<ArgT0 &&>(arg0), args..., GetArenaForAllocation()); + // @@protoc_insertion_point(field_set:google.protobuf.MethodDescriptorProto.name) +} +inline TProtoStringType* MethodDescriptorProto::mutable_name() { + TProtoStringType* _s = _internal_mutable_name(); + // @@protoc_insertion_point(field_mutable:google.protobuf.MethodDescriptorProto.name) + return _s; +} +inline const TProtoStringType& MethodDescriptorProto::_internal_name() const { + return name_.Get(); +} +inline void MethodDescriptorProto::_internal_set_name(const TProtoStringType& value) { + _has_bits_[0] |= 0x00000001u; + name_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, value, GetArenaForAllocation()); +} +inline TProtoStringType* MethodDescriptorProto::_internal_mutable_name() { + _has_bits_[0] |= 0x00000001u; + return name_.Mutable(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, GetArenaForAllocation()); +} +inline TProtoStringType* MethodDescriptorProto::release_name() { + // @@protoc_insertion_point(field_release:google.protobuf.MethodDescriptorProto.name) + if (!_internal_has_name()) { + return nullptr; + } + _has_bits_[0] &= ~0x00000001u; + auto* p = name_.ReleaseNonDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArenaForAllocation()); +#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING + if (name_.IsDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited())) { + name_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation()); + } +#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING + return p; +} +inline void MethodDescriptorProto::set_allocated_name(TProtoStringType* name) { + if (name != nullptr) { + _has_bits_[0] |= 0x00000001u; + } else { + _has_bits_[0] &= ~0x00000001u; + } + name_.SetAllocated(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), name, + GetArenaForAllocation()); +#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING + if (name_.IsDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited())) { + name_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation()); + } +#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING + // @@protoc_insertion_point(field_set_allocated:google.protobuf.MethodDescriptorProto.name) +} + +// optional string input_type = 2; +inline bool MethodDescriptorProto::_internal_has_input_type() const { + bool value = (_has_bits_[0] & 0x00000002u) != 0; + return value; +} +inline bool MethodDescriptorProto::has_input_type() const { + return _internal_has_input_type(); +} +inline void MethodDescriptorProto::clear_input_type() { + input_type_.ClearToEmpty(); + _has_bits_[0] &= ~0x00000002u; +} +inline const TProtoStringType& MethodDescriptorProto::input_type() const { + // @@protoc_insertion_point(field_get:google.protobuf.MethodDescriptorProto.input_type) + return _internal_input_type(); +} +template <typename ArgT0, typename... ArgT> +inline PROTOBUF_ALWAYS_INLINE +void MethodDescriptorProto::set_input_type(ArgT0&& arg0, ArgT... args) { + _has_bits_[0] |= 0x00000002u; + input_type_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, static_cast<ArgT0 &&>(arg0), args..., GetArenaForAllocation()); + // @@protoc_insertion_point(field_set:google.protobuf.MethodDescriptorProto.input_type) +} +inline TProtoStringType* MethodDescriptorProto::mutable_input_type() { + TProtoStringType* _s = _internal_mutable_input_type(); + // @@protoc_insertion_point(field_mutable:google.protobuf.MethodDescriptorProto.input_type) + return _s; +} +inline const TProtoStringType& MethodDescriptorProto::_internal_input_type() const { + return input_type_.Get(); +} +inline void MethodDescriptorProto::_internal_set_input_type(const TProtoStringType& value) { + _has_bits_[0] |= 0x00000002u; + input_type_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, value, GetArenaForAllocation()); +} +inline TProtoStringType* MethodDescriptorProto::_internal_mutable_input_type() { + _has_bits_[0] |= 0x00000002u; + return input_type_.Mutable(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, GetArenaForAllocation()); +} +inline TProtoStringType* MethodDescriptorProto::release_input_type() { + // @@protoc_insertion_point(field_release:google.protobuf.MethodDescriptorProto.input_type) + if (!_internal_has_input_type()) { + return nullptr; + } + _has_bits_[0] &= ~0x00000002u; + auto* p = input_type_.ReleaseNonDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArenaForAllocation()); +#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING + if (input_type_.IsDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited())) { + input_type_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation()); + } +#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING + return p; +} +inline void MethodDescriptorProto::set_allocated_input_type(TProtoStringType* input_type) { + if (input_type != nullptr) { + _has_bits_[0] |= 0x00000002u; + } else { + _has_bits_[0] &= ~0x00000002u; + } + input_type_.SetAllocated(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), input_type, + GetArenaForAllocation()); +#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING + if (input_type_.IsDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited())) { + input_type_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation()); + } +#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING + // @@protoc_insertion_point(field_set_allocated:google.protobuf.MethodDescriptorProto.input_type) +} + +// optional string output_type = 3; +inline bool MethodDescriptorProto::_internal_has_output_type() const { + bool value = (_has_bits_[0] & 0x00000004u) != 0; + return value; +} +inline bool MethodDescriptorProto::has_output_type() const { + return _internal_has_output_type(); +} +inline void MethodDescriptorProto::clear_output_type() { + output_type_.ClearToEmpty(); + _has_bits_[0] &= ~0x00000004u; +} +inline const TProtoStringType& MethodDescriptorProto::output_type() const { + // @@protoc_insertion_point(field_get:google.protobuf.MethodDescriptorProto.output_type) + return _internal_output_type(); +} +template <typename ArgT0, typename... ArgT> +inline PROTOBUF_ALWAYS_INLINE +void MethodDescriptorProto::set_output_type(ArgT0&& arg0, ArgT... args) { + _has_bits_[0] |= 0x00000004u; + output_type_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, static_cast<ArgT0 &&>(arg0), args..., GetArenaForAllocation()); + // @@protoc_insertion_point(field_set:google.protobuf.MethodDescriptorProto.output_type) +} +inline TProtoStringType* MethodDescriptorProto::mutable_output_type() { + TProtoStringType* _s = _internal_mutable_output_type(); + // @@protoc_insertion_point(field_mutable:google.protobuf.MethodDescriptorProto.output_type) + return _s; +} +inline const TProtoStringType& MethodDescriptorProto::_internal_output_type() const { + return output_type_.Get(); +} +inline void MethodDescriptorProto::_internal_set_output_type(const TProtoStringType& value) { + _has_bits_[0] |= 0x00000004u; + output_type_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, value, GetArenaForAllocation()); +} +inline TProtoStringType* MethodDescriptorProto::_internal_mutable_output_type() { + _has_bits_[0] |= 0x00000004u; + return output_type_.Mutable(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, GetArenaForAllocation()); +} +inline TProtoStringType* MethodDescriptorProto::release_output_type() { + // @@protoc_insertion_point(field_release:google.protobuf.MethodDescriptorProto.output_type) + if (!_internal_has_output_type()) { + return nullptr; + } + _has_bits_[0] &= ~0x00000004u; + auto* p = output_type_.ReleaseNonDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArenaForAllocation()); +#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING + if (output_type_.IsDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited())) { + output_type_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation()); + } +#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING + return p; +} +inline void MethodDescriptorProto::set_allocated_output_type(TProtoStringType* output_type) { + if (output_type != nullptr) { + _has_bits_[0] |= 0x00000004u; + } else { + _has_bits_[0] &= ~0x00000004u; + } + output_type_.SetAllocated(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), output_type, + GetArenaForAllocation()); +#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING + if (output_type_.IsDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited())) { + output_type_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation()); + } +#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING + // @@protoc_insertion_point(field_set_allocated:google.protobuf.MethodDescriptorProto.output_type) +} + +// optional .google.protobuf.MethodOptions options = 4; +inline bool MethodDescriptorProto::_internal_has_options() const { + bool value = (_has_bits_[0] & 0x00000008u) != 0; + PROTOBUF_ASSUME(!value || options_ != nullptr); + return value; +} +inline bool MethodDescriptorProto::has_options() const { + return _internal_has_options(); +} +inline void MethodDescriptorProto::clear_options() { + if (options_ != nullptr) options_->Clear(); + _has_bits_[0] &= ~0x00000008u; +} +inline const ::PROTOBUF_NAMESPACE_ID::MethodOptions& MethodDescriptorProto::_internal_options() const { + const ::PROTOBUF_NAMESPACE_ID::MethodOptions* p = options_; + return p != nullptr ? *p : reinterpret_cast<const ::PROTOBUF_NAMESPACE_ID::MethodOptions&>( + ::PROTOBUF_NAMESPACE_ID::_MethodOptions_default_instance_); +} +inline const ::PROTOBUF_NAMESPACE_ID::MethodOptions& MethodDescriptorProto::options() const { + // @@protoc_insertion_point(field_get:google.protobuf.MethodDescriptorProto.options) + return _internal_options(); +} +inline void MethodDescriptorProto::unsafe_arena_set_allocated_options( + ::PROTOBUF_NAMESPACE_ID::MethodOptions* options) { + if (GetArenaForAllocation() == nullptr) { + delete reinterpret_cast<::PROTOBUF_NAMESPACE_ID::MessageLite*>(options_); + } + options_ = options; + if (options) { + _has_bits_[0] |= 0x00000008u; + } else { + _has_bits_[0] &= ~0x00000008u; + } + // @@protoc_insertion_point(field_unsafe_arena_set_allocated:google.protobuf.MethodDescriptorProto.options) +} +inline ::PROTOBUF_NAMESPACE_ID::MethodOptions* MethodDescriptorProto::release_options() { + _has_bits_[0] &= ~0x00000008u; + ::PROTOBUF_NAMESPACE_ID::MethodOptions* temp = options_; + options_ = nullptr; +#ifdef PROTOBUF_FORCE_COPY_IN_RELEASE + auto* old = reinterpret_cast<::PROTOBUF_NAMESPACE_ID::MessageLite*>(temp); + temp = ::PROTOBUF_NAMESPACE_ID::internal::DuplicateIfNonNull(temp); + if (GetArenaForAllocation() == nullptr) { delete old; } +#else // PROTOBUF_FORCE_COPY_IN_RELEASE + if (GetArenaForAllocation() != nullptr) { + temp = ::PROTOBUF_NAMESPACE_ID::internal::DuplicateIfNonNull(temp); + } +#endif // !PROTOBUF_FORCE_COPY_IN_RELEASE + return temp; +} +inline ::PROTOBUF_NAMESPACE_ID::MethodOptions* MethodDescriptorProto::unsafe_arena_release_options() { + // @@protoc_insertion_point(field_release:google.protobuf.MethodDescriptorProto.options) + _has_bits_[0] &= ~0x00000008u; + ::PROTOBUF_NAMESPACE_ID::MethodOptions* temp = options_; + options_ = nullptr; + return temp; +} +inline ::PROTOBUF_NAMESPACE_ID::MethodOptions* MethodDescriptorProto::_internal_mutable_options() { + _has_bits_[0] |= 0x00000008u; + if (options_ == nullptr) { + auto* p = CreateMaybeMessage<::PROTOBUF_NAMESPACE_ID::MethodOptions>(GetArenaForAllocation()); + options_ = p; + } + return options_; +} +inline ::PROTOBUF_NAMESPACE_ID::MethodOptions* MethodDescriptorProto::mutable_options() { + ::PROTOBUF_NAMESPACE_ID::MethodOptions* _msg = _internal_mutable_options(); + // @@protoc_insertion_point(field_mutable:google.protobuf.MethodDescriptorProto.options) + return _msg; +} +inline void MethodDescriptorProto::set_allocated_options(::PROTOBUF_NAMESPACE_ID::MethodOptions* options) { + ::PROTOBUF_NAMESPACE_ID::Arena* message_arena = GetArenaForAllocation(); + if (message_arena == nullptr) { + delete options_; + } + if (options) { + ::PROTOBUF_NAMESPACE_ID::Arena* submessage_arena = + ::PROTOBUF_NAMESPACE_ID::Arena::InternalHelper<::PROTOBUF_NAMESPACE_ID::MethodOptions>::GetOwningArena(options); + if (message_arena != submessage_arena) { + options = ::PROTOBUF_NAMESPACE_ID::internal::GetOwnedMessage( + message_arena, options, submessage_arena); + } + _has_bits_[0] |= 0x00000008u; + } else { + _has_bits_[0] &= ~0x00000008u; + } + options_ = options; + // @@protoc_insertion_point(field_set_allocated:google.protobuf.MethodDescriptorProto.options) +} + +// optional bool client_streaming = 5 [default = false]; +inline bool MethodDescriptorProto::_internal_has_client_streaming() const { + bool value = (_has_bits_[0] & 0x00000010u) != 0; + return value; +} +inline bool MethodDescriptorProto::has_client_streaming() const { + return _internal_has_client_streaming(); +} +inline void MethodDescriptorProto::clear_client_streaming() { + client_streaming_ = false; + _has_bits_[0] &= ~0x00000010u; +} +inline bool MethodDescriptorProto::_internal_client_streaming() const { + return client_streaming_; +} +inline bool MethodDescriptorProto::client_streaming() const { + // @@protoc_insertion_point(field_get:google.protobuf.MethodDescriptorProto.client_streaming) + return _internal_client_streaming(); +} +inline void MethodDescriptorProto::_internal_set_client_streaming(bool value) { + _has_bits_[0] |= 0x00000010u; + client_streaming_ = value; +} +inline void MethodDescriptorProto::set_client_streaming(bool value) { + _internal_set_client_streaming(value); + // @@protoc_insertion_point(field_set:google.protobuf.MethodDescriptorProto.client_streaming) +} + +// optional bool server_streaming = 6 [default = false]; +inline bool MethodDescriptorProto::_internal_has_server_streaming() const { + bool value = (_has_bits_[0] & 0x00000020u) != 0; + return value; +} +inline bool MethodDescriptorProto::has_server_streaming() const { + return _internal_has_server_streaming(); +} +inline void MethodDescriptorProto::clear_server_streaming() { + server_streaming_ = false; + _has_bits_[0] &= ~0x00000020u; +} +inline bool MethodDescriptorProto::_internal_server_streaming() const { + return server_streaming_; +} +inline bool MethodDescriptorProto::server_streaming() const { + // @@protoc_insertion_point(field_get:google.protobuf.MethodDescriptorProto.server_streaming) + return _internal_server_streaming(); +} +inline void MethodDescriptorProto::_internal_set_server_streaming(bool value) { + _has_bits_[0] |= 0x00000020u; + server_streaming_ = value; +} +inline void MethodDescriptorProto::set_server_streaming(bool value) { + _internal_set_server_streaming(value); + // @@protoc_insertion_point(field_set:google.protobuf.MethodDescriptorProto.server_streaming) +} + +// ------------------------------------------------------------------- + +// FileOptions + +// optional string java_package = 1; +inline bool FileOptions::_internal_has_java_package() const { + bool value = (_has_bits_[0] & 0x00000001u) != 0; + return value; +} +inline bool FileOptions::has_java_package() const { + return _internal_has_java_package(); +} +inline void FileOptions::clear_java_package() { + java_package_.ClearToEmpty(); + _has_bits_[0] &= ~0x00000001u; +} +inline const TProtoStringType& FileOptions::java_package() const { + // @@protoc_insertion_point(field_get:google.protobuf.FileOptions.java_package) + return _internal_java_package(); +} +template <typename ArgT0, typename... ArgT> +inline PROTOBUF_ALWAYS_INLINE +void FileOptions::set_java_package(ArgT0&& arg0, ArgT... args) { + _has_bits_[0] |= 0x00000001u; + java_package_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, static_cast<ArgT0 &&>(arg0), args..., GetArenaForAllocation()); + // @@protoc_insertion_point(field_set:google.protobuf.FileOptions.java_package) +} +inline TProtoStringType* FileOptions::mutable_java_package() { + TProtoStringType* _s = _internal_mutable_java_package(); + // @@protoc_insertion_point(field_mutable:google.protobuf.FileOptions.java_package) + return _s; +} +inline const TProtoStringType& FileOptions::_internal_java_package() const { + return java_package_.Get(); +} +inline void FileOptions::_internal_set_java_package(const TProtoStringType& value) { + _has_bits_[0] |= 0x00000001u; + java_package_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, value, GetArenaForAllocation()); +} +inline TProtoStringType* FileOptions::_internal_mutable_java_package() { + _has_bits_[0] |= 0x00000001u; + return java_package_.Mutable(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, GetArenaForAllocation()); +} +inline TProtoStringType* FileOptions::release_java_package() { + // @@protoc_insertion_point(field_release:google.protobuf.FileOptions.java_package) + if (!_internal_has_java_package()) { + return nullptr; + } + _has_bits_[0] &= ~0x00000001u; + auto* p = java_package_.ReleaseNonDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArenaForAllocation()); +#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING + if (java_package_.IsDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited())) { + java_package_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation()); + } +#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING + return p; +} +inline void FileOptions::set_allocated_java_package(TProtoStringType* java_package) { + if (java_package != nullptr) { + _has_bits_[0] |= 0x00000001u; + } else { + _has_bits_[0] &= ~0x00000001u; + } + java_package_.SetAllocated(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), java_package, + GetArenaForAllocation()); +#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING + if (java_package_.IsDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited())) { + java_package_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation()); + } +#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING + // @@protoc_insertion_point(field_set_allocated:google.protobuf.FileOptions.java_package) +} + +// optional string java_outer_classname = 8; +inline bool FileOptions::_internal_has_java_outer_classname() const { + bool value = (_has_bits_[0] & 0x00000002u) != 0; + return value; +} +inline bool FileOptions::has_java_outer_classname() const { + return _internal_has_java_outer_classname(); +} +inline void FileOptions::clear_java_outer_classname() { + java_outer_classname_.ClearToEmpty(); + _has_bits_[0] &= ~0x00000002u; +} +inline const TProtoStringType& FileOptions::java_outer_classname() const { + // @@protoc_insertion_point(field_get:google.protobuf.FileOptions.java_outer_classname) + return _internal_java_outer_classname(); +} +template <typename ArgT0, typename... ArgT> +inline PROTOBUF_ALWAYS_INLINE +void FileOptions::set_java_outer_classname(ArgT0&& arg0, ArgT... args) { + _has_bits_[0] |= 0x00000002u; + java_outer_classname_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, static_cast<ArgT0 &&>(arg0), args..., GetArenaForAllocation()); + // @@protoc_insertion_point(field_set:google.protobuf.FileOptions.java_outer_classname) +} +inline TProtoStringType* FileOptions::mutable_java_outer_classname() { + TProtoStringType* _s = _internal_mutable_java_outer_classname(); + // @@protoc_insertion_point(field_mutable:google.protobuf.FileOptions.java_outer_classname) + return _s; +} +inline const TProtoStringType& FileOptions::_internal_java_outer_classname() const { + return java_outer_classname_.Get(); +} +inline void FileOptions::_internal_set_java_outer_classname(const TProtoStringType& value) { + _has_bits_[0] |= 0x00000002u; + java_outer_classname_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, value, GetArenaForAllocation()); +} +inline TProtoStringType* FileOptions::_internal_mutable_java_outer_classname() { + _has_bits_[0] |= 0x00000002u; + return java_outer_classname_.Mutable(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, GetArenaForAllocation()); +} +inline TProtoStringType* FileOptions::release_java_outer_classname() { + // @@protoc_insertion_point(field_release:google.protobuf.FileOptions.java_outer_classname) + if (!_internal_has_java_outer_classname()) { + return nullptr; + } + _has_bits_[0] &= ~0x00000002u; + auto* p = java_outer_classname_.ReleaseNonDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArenaForAllocation()); +#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING + if (java_outer_classname_.IsDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited())) { + java_outer_classname_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation()); + } +#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING + return p; +} +inline void FileOptions::set_allocated_java_outer_classname(TProtoStringType* java_outer_classname) { + if (java_outer_classname != nullptr) { + _has_bits_[0] |= 0x00000002u; + } else { + _has_bits_[0] &= ~0x00000002u; + } + java_outer_classname_.SetAllocated(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), java_outer_classname, + GetArenaForAllocation()); +#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING + if (java_outer_classname_.IsDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited())) { + java_outer_classname_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation()); + } +#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING + // @@protoc_insertion_point(field_set_allocated:google.protobuf.FileOptions.java_outer_classname) +} + +// optional bool java_multiple_files = 10 [default = false]; +inline bool FileOptions::_internal_has_java_multiple_files() const { + bool value = (_has_bits_[0] & 0x00000400u) != 0; + return value; +} +inline bool FileOptions::has_java_multiple_files() const { + return _internal_has_java_multiple_files(); +} +inline void FileOptions::clear_java_multiple_files() { + java_multiple_files_ = false; + _has_bits_[0] &= ~0x00000400u; +} +inline bool FileOptions::_internal_java_multiple_files() const { + return java_multiple_files_; +} +inline bool FileOptions::java_multiple_files() const { + // @@protoc_insertion_point(field_get:google.protobuf.FileOptions.java_multiple_files) + return _internal_java_multiple_files(); +} +inline void FileOptions::_internal_set_java_multiple_files(bool value) { + _has_bits_[0] |= 0x00000400u; + java_multiple_files_ = value; +} +inline void FileOptions::set_java_multiple_files(bool value) { + _internal_set_java_multiple_files(value); + // @@protoc_insertion_point(field_set:google.protobuf.FileOptions.java_multiple_files) +} + +// optional bool java_generate_equals_and_hash = 20 [deprecated = true]; +inline bool FileOptions::_internal_has_java_generate_equals_and_hash() const { + bool value = (_has_bits_[0] & 0x00000800u) != 0; + return value; +} +inline bool FileOptions::has_java_generate_equals_and_hash() const { + return _internal_has_java_generate_equals_and_hash(); +} +inline void FileOptions::clear_java_generate_equals_and_hash() { + java_generate_equals_and_hash_ = false; + _has_bits_[0] &= ~0x00000800u; +} +inline bool FileOptions::_internal_java_generate_equals_and_hash() const { + return java_generate_equals_and_hash_; +} +inline bool FileOptions::java_generate_equals_and_hash() const { + // @@protoc_insertion_point(field_get:google.protobuf.FileOptions.java_generate_equals_and_hash) + return _internal_java_generate_equals_and_hash(); +} +inline void FileOptions::_internal_set_java_generate_equals_and_hash(bool value) { + _has_bits_[0] |= 0x00000800u; + java_generate_equals_and_hash_ = value; +} +inline void FileOptions::set_java_generate_equals_and_hash(bool value) { + _internal_set_java_generate_equals_and_hash(value); + // @@protoc_insertion_point(field_set:google.protobuf.FileOptions.java_generate_equals_and_hash) +} + +// optional bool java_string_check_utf8 = 27 [default = false]; +inline bool FileOptions::_internal_has_java_string_check_utf8() const { + bool value = (_has_bits_[0] & 0x00001000u) != 0; + return value; +} +inline bool FileOptions::has_java_string_check_utf8() const { + return _internal_has_java_string_check_utf8(); +} +inline void FileOptions::clear_java_string_check_utf8() { + java_string_check_utf8_ = false; + _has_bits_[0] &= ~0x00001000u; +} +inline bool FileOptions::_internal_java_string_check_utf8() const { + return java_string_check_utf8_; +} +inline bool FileOptions::java_string_check_utf8() const { + // @@protoc_insertion_point(field_get:google.protobuf.FileOptions.java_string_check_utf8) + return _internal_java_string_check_utf8(); +} +inline void FileOptions::_internal_set_java_string_check_utf8(bool value) { + _has_bits_[0] |= 0x00001000u; + java_string_check_utf8_ = value; +} +inline void FileOptions::set_java_string_check_utf8(bool value) { + _internal_set_java_string_check_utf8(value); + // @@protoc_insertion_point(field_set:google.protobuf.FileOptions.java_string_check_utf8) +} + +// optional .google.protobuf.FileOptions.OptimizeMode optimize_for = 9 [default = SPEED]; +inline bool FileOptions::_internal_has_optimize_for() const { + bool value = (_has_bits_[0] & 0x00040000u) != 0; + return value; +} +inline bool FileOptions::has_optimize_for() const { + return _internal_has_optimize_for(); +} +inline void FileOptions::clear_optimize_for() { + optimize_for_ = 1; + _has_bits_[0] &= ~0x00040000u; +} +inline ::PROTOBUF_NAMESPACE_ID::FileOptions_OptimizeMode FileOptions::_internal_optimize_for() const { + return static_cast< ::PROTOBUF_NAMESPACE_ID::FileOptions_OptimizeMode >(optimize_for_); +} +inline ::PROTOBUF_NAMESPACE_ID::FileOptions_OptimizeMode FileOptions::optimize_for() const { + // @@protoc_insertion_point(field_get:google.protobuf.FileOptions.optimize_for) + return _internal_optimize_for(); +} +inline void FileOptions::_internal_set_optimize_for(::PROTOBUF_NAMESPACE_ID::FileOptions_OptimizeMode value) { + assert(::PROTOBUF_NAMESPACE_ID::FileOptions_OptimizeMode_IsValid(value)); + _has_bits_[0] |= 0x00040000u; + optimize_for_ = value; +} +inline void FileOptions::set_optimize_for(::PROTOBUF_NAMESPACE_ID::FileOptions_OptimizeMode value) { + _internal_set_optimize_for(value); + // @@protoc_insertion_point(field_set:google.protobuf.FileOptions.optimize_for) +} + +// optional string go_package = 11; +inline bool FileOptions::_internal_has_go_package() const { + bool value = (_has_bits_[0] & 0x00000004u) != 0; + return value; +} +inline bool FileOptions::has_go_package() const { + return _internal_has_go_package(); +} +inline void FileOptions::clear_go_package() { + go_package_.ClearToEmpty(); + _has_bits_[0] &= ~0x00000004u; +} +inline const TProtoStringType& FileOptions::go_package() const { + // @@protoc_insertion_point(field_get:google.protobuf.FileOptions.go_package) + return _internal_go_package(); +} +template <typename ArgT0, typename... ArgT> +inline PROTOBUF_ALWAYS_INLINE +void FileOptions::set_go_package(ArgT0&& arg0, ArgT... args) { + _has_bits_[0] |= 0x00000004u; + go_package_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, static_cast<ArgT0 &&>(arg0), args..., GetArenaForAllocation()); + // @@protoc_insertion_point(field_set:google.protobuf.FileOptions.go_package) +} +inline TProtoStringType* FileOptions::mutable_go_package() { + TProtoStringType* _s = _internal_mutable_go_package(); + // @@protoc_insertion_point(field_mutable:google.protobuf.FileOptions.go_package) + return _s; +} +inline const TProtoStringType& FileOptions::_internal_go_package() const { + return go_package_.Get(); +} +inline void FileOptions::_internal_set_go_package(const TProtoStringType& value) { + _has_bits_[0] |= 0x00000004u; + go_package_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, value, GetArenaForAllocation()); +} +inline TProtoStringType* FileOptions::_internal_mutable_go_package() { + _has_bits_[0] |= 0x00000004u; + return go_package_.Mutable(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, GetArenaForAllocation()); +} +inline TProtoStringType* FileOptions::release_go_package() { + // @@protoc_insertion_point(field_release:google.protobuf.FileOptions.go_package) + if (!_internal_has_go_package()) { + return nullptr; + } + _has_bits_[0] &= ~0x00000004u; + auto* p = go_package_.ReleaseNonDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArenaForAllocation()); +#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING + if (go_package_.IsDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited())) { + go_package_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation()); + } +#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING + return p; +} +inline void FileOptions::set_allocated_go_package(TProtoStringType* go_package) { + if (go_package != nullptr) { + _has_bits_[0] |= 0x00000004u; + } else { + _has_bits_[0] &= ~0x00000004u; + } + go_package_.SetAllocated(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), go_package, + GetArenaForAllocation()); +#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING + if (go_package_.IsDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited())) { + go_package_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation()); + } +#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING + // @@protoc_insertion_point(field_set_allocated:google.protobuf.FileOptions.go_package) +} + +// optional bool cc_generic_services = 16 [default = false]; +inline bool FileOptions::_internal_has_cc_generic_services() const { + bool value = (_has_bits_[0] & 0x00002000u) != 0; + return value; +} +inline bool FileOptions::has_cc_generic_services() const { + return _internal_has_cc_generic_services(); +} +inline void FileOptions::clear_cc_generic_services() { + cc_generic_services_ = false; + _has_bits_[0] &= ~0x00002000u; +} +inline bool FileOptions::_internal_cc_generic_services() const { + return cc_generic_services_; +} +inline bool FileOptions::cc_generic_services() const { + // @@protoc_insertion_point(field_get:google.protobuf.FileOptions.cc_generic_services) + return _internal_cc_generic_services(); +} +inline void FileOptions::_internal_set_cc_generic_services(bool value) { + _has_bits_[0] |= 0x00002000u; + cc_generic_services_ = value; +} +inline void FileOptions::set_cc_generic_services(bool value) { + _internal_set_cc_generic_services(value); + // @@protoc_insertion_point(field_set:google.protobuf.FileOptions.cc_generic_services) +} + +// optional bool java_generic_services = 17 [default = false]; +inline bool FileOptions::_internal_has_java_generic_services() const { + bool value = (_has_bits_[0] & 0x00004000u) != 0; + return value; +} +inline bool FileOptions::has_java_generic_services() const { + return _internal_has_java_generic_services(); +} +inline void FileOptions::clear_java_generic_services() { + java_generic_services_ = false; + _has_bits_[0] &= ~0x00004000u; +} +inline bool FileOptions::_internal_java_generic_services() const { + return java_generic_services_; +} +inline bool FileOptions::java_generic_services() const { + // @@protoc_insertion_point(field_get:google.protobuf.FileOptions.java_generic_services) + return _internal_java_generic_services(); +} +inline void FileOptions::_internal_set_java_generic_services(bool value) { + _has_bits_[0] |= 0x00004000u; + java_generic_services_ = value; +} +inline void FileOptions::set_java_generic_services(bool value) { + _internal_set_java_generic_services(value); + // @@protoc_insertion_point(field_set:google.protobuf.FileOptions.java_generic_services) +} + +// optional bool py_generic_services = 18 [default = false]; +inline bool FileOptions::_internal_has_py_generic_services() const { + bool value = (_has_bits_[0] & 0x00008000u) != 0; + return value; +} +inline bool FileOptions::has_py_generic_services() const { + return _internal_has_py_generic_services(); +} +inline void FileOptions::clear_py_generic_services() { + py_generic_services_ = false; + _has_bits_[0] &= ~0x00008000u; +} +inline bool FileOptions::_internal_py_generic_services() const { + return py_generic_services_; +} +inline bool FileOptions::py_generic_services() const { + // @@protoc_insertion_point(field_get:google.protobuf.FileOptions.py_generic_services) + return _internal_py_generic_services(); +} +inline void FileOptions::_internal_set_py_generic_services(bool value) { + _has_bits_[0] |= 0x00008000u; + py_generic_services_ = value; +} +inline void FileOptions::set_py_generic_services(bool value) { + _internal_set_py_generic_services(value); + // @@protoc_insertion_point(field_set:google.protobuf.FileOptions.py_generic_services) +} + +// optional bool php_generic_services = 42 [default = false]; +inline bool FileOptions::_internal_has_php_generic_services() const { + bool value = (_has_bits_[0] & 0x00010000u) != 0; + return value; +} +inline bool FileOptions::has_php_generic_services() const { + return _internal_has_php_generic_services(); +} +inline void FileOptions::clear_php_generic_services() { + php_generic_services_ = false; + _has_bits_[0] &= ~0x00010000u; +} +inline bool FileOptions::_internal_php_generic_services() const { + return php_generic_services_; +} +inline bool FileOptions::php_generic_services() const { + // @@protoc_insertion_point(field_get:google.protobuf.FileOptions.php_generic_services) + return _internal_php_generic_services(); +} +inline void FileOptions::_internal_set_php_generic_services(bool value) { + _has_bits_[0] |= 0x00010000u; + php_generic_services_ = value; +} +inline void FileOptions::set_php_generic_services(bool value) { + _internal_set_php_generic_services(value); + // @@protoc_insertion_point(field_set:google.protobuf.FileOptions.php_generic_services) +} + +// optional bool deprecated = 23 [default = false]; +inline bool FileOptions::_internal_has_deprecated() const { + bool value = (_has_bits_[0] & 0x00020000u) != 0; + return value; +} +inline bool FileOptions::has_deprecated() const { + return _internal_has_deprecated(); +} +inline void FileOptions::clear_deprecated() { + deprecated_ = false; + _has_bits_[0] &= ~0x00020000u; +} +inline bool FileOptions::_internal_deprecated() const { + return deprecated_; +} +inline bool FileOptions::deprecated() const { + // @@protoc_insertion_point(field_get:google.protobuf.FileOptions.deprecated) + return _internal_deprecated(); +} +inline void FileOptions::_internal_set_deprecated(bool value) { + _has_bits_[0] |= 0x00020000u; + deprecated_ = value; +} +inline void FileOptions::set_deprecated(bool value) { + _internal_set_deprecated(value); + // @@protoc_insertion_point(field_set:google.protobuf.FileOptions.deprecated) +} + +// optional bool cc_enable_arenas = 31 [default = true]; +inline bool FileOptions::_internal_has_cc_enable_arenas() const { + bool value = (_has_bits_[0] & 0x00080000u) != 0; + return value; +} +inline bool FileOptions::has_cc_enable_arenas() const { + return _internal_has_cc_enable_arenas(); +} +inline void FileOptions::clear_cc_enable_arenas() { + cc_enable_arenas_ = true; + _has_bits_[0] &= ~0x00080000u; +} +inline bool FileOptions::_internal_cc_enable_arenas() const { + return cc_enable_arenas_; +} +inline bool FileOptions::cc_enable_arenas() const { + // @@protoc_insertion_point(field_get:google.protobuf.FileOptions.cc_enable_arenas) + return _internal_cc_enable_arenas(); +} +inline void FileOptions::_internal_set_cc_enable_arenas(bool value) { + _has_bits_[0] |= 0x00080000u; + cc_enable_arenas_ = value; +} +inline void FileOptions::set_cc_enable_arenas(bool value) { + _internal_set_cc_enable_arenas(value); + // @@protoc_insertion_point(field_set:google.protobuf.FileOptions.cc_enable_arenas) +} + +// optional string objc_class_prefix = 36; +inline bool FileOptions::_internal_has_objc_class_prefix() const { + bool value = (_has_bits_[0] & 0x00000008u) != 0; + return value; +} +inline bool FileOptions::has_objc_class_prefix() const { + return _internal_has_objc_class_prefix(); +} +inline void FileOptions::clear_objc_class_prefix() { + objc_class_prefix_.ClearToEmpty(); + _has_bits_[0] &= ~0x00000008u; +} +inline const TProtoStringType& FileOptions::objc_class_prefix() const { + // @@protoc_insertion_point(field_get:google.protobuf.FileOptions.objc_class_prefix) + return _internal_objc_class_prefix(); +} +template <typename ArgT0, typename... ArgT> +inline PROTOBUF_ALWAYS_INLINE +void FileOptions::set_objc_class_prefix(ArgT0&& arg0, ArgT... args) { + _has_bits_[0] |= 0x00000008u; + objc_class_prefix_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, static_cast<ArgT0 &&>(arg0), args..., GetArenaForAllocation()); + // @@protoc_insertion_point(field_set:google.protobuf.FileOptions.objc_class_prefix) +} +inline TProtoStringType* FileOptions::mutable_objc_class_prefix() { + TProtoStringType* _s = _internal_mutable_objc_class_prefix(); + // @@protoc_insertion_point(field_mutable:google.protobuf.FileOptions.objc_class_prefix) + return _s; +} +inline const TProtoStringType& FileOptions::_internal_objc_class_prefix() const { + return objc_class_prefix_.Get(); +} +inline void FileOptions::_internal_set_objc_class_prefix(const TProtoStringType& value) { + _has_bits_[0] |= 0x00000008u; + objc_class_prefix_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, value, GetArenaForAllocation()); +} +inline TProtoStringType* FileOptions::_internal_mutable_objc_class_prefix() { + _has_bits_[0] |= 0x00000008u; + return objc_class_prefix_.Mutable(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, GetArenaForAllocation()); +} +inline TProtoStringType* FileOptions::release_objc_class_prefix() { + // @@protoc_insertion_point(field_release:google.protobuf.FileOptions.objc_class_prefix) + if (!_internal_has_objc_class_prefix()) { + return nullptr; + } + _has_bits_[0] &= ~0x00000008u; + auto* p = objc_class_prefix_.ReleaseNonDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArenaForAllocation()); +#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING + if (objc_class_prefix_.IsDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited())) { + objc_class_prefix_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation()); + } +#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING + return p; +} +inline void FileOptions::set_allocated_objc_class_prefix(TProtoStringType* objc_class_prefix) { + if (objc_class_prefix != nullptr) { + _has_bits_[0] |= 0x00000008u; + } else { + _has_bits_[0] &= ~0x00000008u; + } + objc_class_prefix_.SetAllocated(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), objc_class_prefix, + GetArenaForAllocation()); +#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING + if (objc_class_prefix_.IsDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited())) { + objc_class_prefix_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation()); + } +#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING + // @@protoc_insertion_point(field_set_allocated:google.protobuf.FileOptions.objc_class_prefix) +} + +// optional string csharp_namespace = 37; +inline bool FileOptions::_internal_has_csharp_namespace() const { + bool value = (_has_bits_[0] & 0x00000010u) != 0; + return value; +} +inline bool FileOptions::has_csharp_namespace() const { + return _internal_has_csharp_namespace(); +} +inline void FileOptions::clear_csharp_namespace() { + csharp_namespace_.ClearToEmpty(); + _has_bits_[0] &= ~0x00000010u; +} +inline const TProtoStringType& FileOptions::csharp_namespace() const { + // @@protoc_insertion_point(field_get:google.protobuf.FileOptions.csharp_namespace) + return _internal_csharp_namespace(); +} +template <typename ArgT0, typename... ArgT> +inline PROTOBUF_ALWAYS_INLINE +void FileOptions::set_csharp_namespace(ArgT0&& arg0, ArgT... args) { + _has_bits_[0] |= 0x00000010u; + csharp_namespace_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, static_cast<ArgT0 &&>(arg0), args..., GetArenaForAllocation()); + // @@protoc_insertion_point(field_set:google.protobuf.FileOptions.csharp_namespace) +} +inline TProtoStringType* FileOptions::mutable_csharp_namespace() { + TProtoStringType* _s = _internal_mutable_csharp_namespace(); + // @@protoc_insertion_point(field_mutable:google.protobuf.FileOptions.csharp_namespace) + return _s; +} +inline const TProtoStringType& FileOptions::_internal_csharp_namespace() const { + return csharp_namespace_.Get(); +} +inline void FileOptions::_internal_set_csharp_namespace(const TProtoStringType& value) { + _has_bits_[0] |= 0x00000010u; + csharp_namespace_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, value, GetArenaForAllocation()); +} +inline TProtoStringType* FileOptions::_internal_mutable_csharp_namespace() { + _has_bits_[0] |= 0x00000010u; + return csharp_namespace_.Mutable(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, GetArenaForAllocation()); +} +inline TProtoStringType* FileOptions::release_csharp_namespace() { + // @@protoc_insertion_point(field_release:google.protobuf.FileOptions.csharp_namespace) + if (!_internal_has_csharp_namespace()) { + return nullptr; + } + _has_bits_[0] &= ~0x00000010u; + auto* p = csharp_namespace_.ReleaseNonDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArenaForAllocation()); +#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING + if (csharp_namespace_.IsDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited())) { + csharp_namespace_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation()); + } +#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING + return p; +} +inline void FileOptions::set_allocated_csharp_namespace(TProtoStringType* csharp_namespace) { + if (csharp_namespace != nullptr) { + _has_bits_[0] |= 0x00000010u; + } else { + _has_bits_[0] &= ~0x00000010u; + } + csharp_namespace_.SetAllocated(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), csharp_namespace, + GetArenaForAllocation()); +#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING + if (csharp_namespace_.IsDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited())) { + csharp_namespace_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation()); + } +#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING + // @@protoc_insertion_point(field_set_allocated:google.protobuf.FileOptions.csharp_namespace) +} + +// optional string swift_prefix = 39; +inline bool FileOptions::_internal_has_swift_prefix() const { + bool value = (_has_bits_[0] & 0x00000020u) != 0; + return value; +} +inline bool FileOptions::has_swift_prefix() const { + return _internal_has_swift_prefix(); +} +inline void FileOptions::clear_swift_prefix() { + swift_prefix_.ClearToEmpty(); + _has_bits_[0] &= ~0x00000020u; +} +inline const TProtoStringType& FileOptions::swift_prefix() const { + // @@protoc_insertion_point(field_get:google.protobuf.FileOptions.swift_prefix) + return _internal_swift_prefix(); +} +template <typename ArgT0, typename... ArgT> +inline PROTOBUF_ALWAYS_INLINE +void FileOptions::set_swift_prefix(ArgT0&& arg0, ArgT... args) { + _has_bits_[0] |= 0x00000020u; + swift_prefix_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, static_cast<ArgT0 &&>(arg0), args..., GetArenaForAllocation()); + // @@protoc_insertion_point(field_set:google.protobuf.FileOptions.swift_prefix) +} +inline TProtoStringType* FileOptions::mutable_swift_prefix() { + TProtoStringType* _s = _internal_mutable_swift_prefix(); + // @@protoc_insertion_point(field_mutable:google.protobuf.FileOptions.swift_prefix) + return _s; +} +inline const TProtoStringType& FileOptions::_internal_swift_prefix() const { + return swift_prefix_.Get(); +} +inline void FileOptions::_internal_set_swift_prefix(const TProtoStringType& value) { + _has_bits_[0] |= 0x00000020u; + swift_prefix_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, value, GetArenaForAllocation()); +} +inline TProtoStringType* FileOptions::_internal_mutable_swift_prefix() { + _has_bits_[0] |= 0x00000020u; + return swift_prefix_.Mutable(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, GetArenaForAllocation()); +} +inline TProtoStringType* FileOptions::release_swift_prefix() { + // @@protoc_insertion_point(field_release:google.protobuf.FileOptions.swift_prefix) + if (!_internal_has_swift_prefix()) { + return nullptr; + } + _has_bits_[0] &= ~0x00000020u; + auto* p = swift_prefix_.ReleaseNonDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArenaForAllocation()); +#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING + if (swift_prefix_.IsDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited())) { + swift_prefix_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation()); + } +#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING + return p; +} +inline void FileOptions::set_allocated_swift_prefix(TProtoStringType* swift_prefix) { + if (swift_prefix != nullptr) { + _has_bits_[0] |= 0x00000020u; + } else { + _has_bits_[0] &= ~0x00000020u; + } + swift_prefix_.SetAllocated(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), swift_prefix, + GetArenaForAllocation()); +#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING + if (swift_prefix_.IsDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited())) { + swift_prefix_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation()); + } +#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING + // @@protoc_insertion_point(field_set_allocated:google.protobuf.FileOptions.swift_prefix) +} + +// optional string php_class_prefix = 40; +inline bool FileOptions::_internal_has_php_class_prefix() const { + bool value = (_has_bits_[0] & 0x00000040u) != 0; + return value; +} +inline bool FileOptions::has_php_class_prefix() const { + return _internal_has_php_class_prefix(); +} +inline void FileOptions::clear_php_class_prefix() { + php_class_prefix_.ClearToEmpty(); + _has_bits_[0] &= ~0x00000040u; +} +inline const TProtoStringType& FileOptions::php_class_prefix() const { + // @@protoc_insertion_point(field_get:google.protobuf.FileOptions.php_class_prefix) + return _internal_php_class_prefix(); +} +template <typename ArgT0, typename... ArgT> +inline PROTOBUF_ALWAYS_INLINE +void FileOptions::set_php_class_prefix(ArgT0&& arg0, ArgT... args) { + _has_bits_[0] |= 0x00000040u; + php_class_prefix_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, static_cast<ArgT0 &&>(arg0), args..., GetArenaForAllocation()); + // @@protoc_insertion_point(field_set:google.protobuf.FileOptions.php_class_prefix) +} +inline TProtoStringType* FileOptions::mutable_php_class_prefix() { + TProtoStringType* _s = _internal_mutable_php_class_prefix(); + // @@protoc_insertion_point(field_mutable:google.protobuf.FileOptions.php_class_prefix) + return _s; +} +inline const TProtoStringType& FileOptions::_internal_php_class_prefix() const { + return php_class_prefix_.Get(); +} +inline void FileOptions::_internal_set_php_class_prefix(const TProtoStringType& value) { + _has_bits_[0] |= 0x00000040u; + php_class_prefix_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, value, GetArenaForAllocation()); +} +inline TProtoStringType* FileOptions::_internal_mutable_php_class_prefix() { + _has_bits_[0] |= 0x00000040u; + return php_class_prefix_.Mutable(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, GetArenaForAllocation()); +} +inline TProtoStringType* FileOptions::release_php_class_prefix() { + // @@protoc_insertion_point(field_release:google.protobuf.FileOptions.php_class_prefix) + if (!_internal_has_php_class_prefix()) { + return nullptr; + } + _has_bits_[0] &= ~0x00000040u; + auto* p = php_class_prefix_.ReleaseNonDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArenaForAllocation()); +#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING + if (php_class_prefix_.IsDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited())) { + php_class_prefix_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation()); + } +#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING + return p; +} +inline void FileOptions::set_allocated_php_class_prefix(TProtoStringType* php_class_prefix) { + if (php_class_prefix != nullptr) { + _has_bits_[0] |= 0x00000040u; + } else { + _has_bits_[0] &= ~0x00000040u; + } + php_class_prefix_.SetAllocated(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), php_class_prefix, + GetArenaForAllocation()); +#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING + if (php_class_prefix_.IsDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited())) { + php_class_prefix_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation()); + } +#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING + // @@protoc_insertion_point(field_set_allocated:google.protobuf.FileOptions.php_class_prefix) +} + +// optional string php_namespace = 41; +inline bool FileOptions::_internal_has_php_namespace() const { + bool value = (_has_bits_[0] & 0x00000080u) != 0; + return value; +} +inline bool FileOptions::has_php_namespace() const { + return _internal_has_php_namespace(); +} +inline void FileOptions::clear_php_namespace() { + php_namespace_.ClearToEmpty(); + _has_bits_[0] &= ~0x00000080u; +} +inline const TProtoStringType& FileOptions::php_namespace() const { + // @@protoc_insertion_point(field_get:google.protobuf.FileOptions.php_namespace) + return _internal_php_namespace(); +} +template <typename ArgT0, typename... ArgT> +inline PROTOBUF_ALWAYS_INLINE +void FileOptions::set_php_namespace(ArgT0&& arg0, ArgT... args) { + _has_bits_[0] |= 0x00000080u; + php_namespace_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, static_cast<ArgT0 &&>(arg0), args..., GetArenaForAllocation()); + // @@protoc_insertion_point(field_set:google.protobuf.FileOptions.php_namespace) +} +inline TProtoStringType* FileOptions::mutable_php_namespace() { + TProtoStringType* _s = _internal_mutable_php_namespace(); + // @@protoc_insertion_point(field_mutable:google.protobuf.FileOptions.php_namespace) + return _s; +} +inline const TProtoStringType& FileOptions::_internal_php_namespace() const { + return php_namespace_.Get(); +} +inline void FileOptions::_internal_set_php_namespace(const TProtoStringType& value) { + _has_bits_[0] |= 0x00000080u; + php_namespace_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, value, GetArenaForAllocation()); +} +inline TProtoStringType* FileOptions::_internal_mutable_php_namespace() { + _has_bits_[0] |= 0x00000080u; + return php_namespace_.Mutable(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, GetArenaForAllocation()); +} +inline TProtoStringType* FileOptions::release_php_namespace() { + // @@protoc_insertion_point(field_release:google.protobuf.FileOptions.php_namespace) + if (!_internal_has_php_namespace()) { + return nullptr; + } + _has_bits_[0] &= ~0x00000080u; + auto* p = php_namespace_.ReleaseNonDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArenaForAllocation()); +#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING + if (php_namespace_.IsDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited())) { + php_namespace_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation()); + } +#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING + return p; +} +inline void FileOptions::set_allocated_php_namespace(TProtoStringType* php_namespace) { + if (php_namespace != nullptr) { + _has_bits_[0] |= 0x00000080u; + } else { + _has_bits_[0] &= ~0x00000080u; + } + php_namespace_.SetAllocated(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), php_namespace, + GetArenaForAllocation()); +#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING + if (php_namespace_.IsDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited())) { + php_namespace_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation()); + } +#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING + // @@protoc_insertion_point(field_set_allocated:google.protobuf.FileOptions.php_namespace) +} + +// optional string php_metadata_namespace = 44; +inline bool FileOptions::_internal_has_php_metadata_namespace() const { + bool value = (_has_bits_[0] & 0x00000100u) != 0; + return value; +} +inline bool FileOptions::has_php_metadata_namespace() const { + return _internal_has_php_metadata_namespace(); +} +inline void FileOptions::clear_php_metadata_namespace() { + php_metadata_namespace_.ClearToEmpty(); + _has_bits_[0] &= ~0x00000100u; +} +inline const TProtoStringType& FileOptions::php_metadata_namespace() const { + // @@protoc_insertion_point(field_get:google.protobuf.FileOptions.php_metadata_namespace) + return _internal_php_metadata_namespace(); +} +template <typename ArgT0, typename... ArgT> +inline PROTOBUF_ALWAYS_INLINE +void FileOptions::set_php_metadata_namespace(ArgT0&& arg0, ArgT... args) { + _has_bits_[0] |= 0x00000100u; + php_metadata_namespace_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, static_cast<ArgT0 &&>(arg0), args..., GetArenaForAllocation()); + // @@protoc_insertion_point(field_set:google.protobuf.FileOptions.php_metadata_namespace) +} +inline TProtoStringType* FileOptions::mutable_php_metadata_namespace() { + TProtoStringType* _s = _internal_mutable_php_metadata_namespace(); + // @@protoc_insertion_point(field_mutable:google.protobuf.FileOptions.php_metadata_namespace) + return _s; +} +inline const TProtoStringType& FileOptions::_internal_php_metadata_namespace() const { + return php_metadata_namespace_.Get(); +} +inline void FileOptions::_internal_set_php_metadata_namespace(const TProtoStringType& value) { + _has_bits_[0] |= 0x00000100u; + php_metadata_namespace_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, value, GetArenaForAllocation()); +} +inline TProtoStringType* FileOptions::_internal_mutable_php_metadata_namespace() { + _has_bits_[0] |= 0x00000100u; + return php_metadata_namespace_.Mutable(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, GetArenaForAllocation()); +} +inline TProtoStringType* FileOptions::release_php_metadata_namespace() { + // @@protoc_insertion_point(field_release:google.protobuf.FileOptions.php_metadata_namespace) + if (!_internal_has_php_metadata_namespace()) { + return nullptr; + } + _has_bits_[0] &= ~0x00000100u; + auto* p = php_metadata_namespace_.ReleaseNonDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArenaForAllocation()); +#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING + if (php_metadata_namespace_.IsDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited())) { + php_metadata_namespace_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation()); + } +#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING + return p; +} +inline void FileOptions::set_allocated_php_metadata_namespace(TProtoStringType* php_metadata_namespace) { + if (php_metadata_namespace != nullptr) { + _has_bits_[0] |= 0x00000100u; + } else { + _has_bits_[0] &= ~0x00000100u; + } + php_metadata_namespace_.SetAllocated(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), php_metadata_namespace, + GetArenaForAllocation()); +#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING + if (php_metadata_namespace_.IsDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited())) { + php_metadata_namespace_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation()); + } +#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING + // @@protoc_insertion_point(field_set_allocated:google.protobuf.FileOptions.php_metadata_namespace) +} + +// optional string ruby_package = 45; +inline bool FileOptions::_internal_has_ruby_package() const { + bool value = (_has_bits_[0] & 0x00000200u) != 0; + return value; +} +inline bool FileOptions::has_ruby_package() const { + return _internal_has_ruby_package(); +} +inline void FileOptions::clear_ruby_package() { + ruby_package_.ClearToEmpty(); + _has_bits_[0] &= ~0x00000200u; +} +inline const TProtoStringType& FileOptions::ruby_package() const { + // @@protoc_insertion_point(field_get:google.protobuf.FileOptions.ruby_package) + return _internal_ruby_package(); +} +template <typename ArgT0, typename... ArgT> +inline PROTOBUF_ALWAYS_INLINE +void FileOptions::set_ruby_package(ArgT0&& arg0, ArgT... args) { + _has_bits_[0] |= 0x00000200u; + ruby_package_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, static_cast<ArgT0 &&>(arg0), args..., GetArenaForAllocation()); + // @@protoc_insertion_point(field_set:google.protobuf.FileOptions.ruby_package) +} +inline TProtoStringType* FileOptions::mutable_ruby_package() { + TProtoStringType* _s = _internal_mutable_ruby_package(); + // @@protoc_insertion_point(field_mutable:google.protobuf.FileOptions.ruby_package) + return _s; +} +inline const TProtoStringType& FileOptions::_internal_ruby_package() const { + return ruby_package_.Get(); +} +inline void FileOptions::_internal_set_ruby_package(const TProtoStringType& value) { + _has_bits_[0] |= 0x00000200u; + ruby_package_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, value, GetArenaForAllocation()); +} +inline TProtoStringType* FileOptions::_internal_mutable_ruby_package() { + _has_bits_[0] |= 0x00000200u; + return ruby_package_.Mutable(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, GetArenaForAllocation()); +} +inline TProtoStringType* FileOptions::release_ruby_package() { + // @@protoc_insertion_point(field_release:google.protobuf.FileOptions.ruby_package) + if (!_internal_has_ruby_package()) { + return nullptr; + } + _has_bits_[0] &= ~0x00000200u; + auto* p = ruby_package_.ReleaseNonDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArenaForAllocation()); +#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING + if (ruby_package_.IsDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited())) { + ruby_package_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation()); + } +#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING + return p; +} +inline void FileOptions::set_allocated_ruby_package(TProtoStringType* ruby_package) { + if (ruby_package != nullptr) { + _has_bits_[0] |= 0x00000200u; + } else { + _has_bits_[0] &= ~0x00000200u; + } + ruby_package_.SetAllocated(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ruby_package, + GetArenaForAllocation()); +#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING + if (ruby_package_.IsDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited())) { + ruby_package_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation()); + } +#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING + // @@protoc_insertion_point(field_set_allocated:google.protobuf.FileOptions.ruby_package) +} + +// repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999; +inline int FileOptions::_internal_uninterpreted_option_size() const { + return uninterpreted_option_.size(); +} +inline int FileOptions::uninterpreted_option_size() const { + return _internal_uninterpreted_option_size(); +} +inline void FileOptions::clear_uninterpreted_option() { + uninterpreted_option_.Clear(); +} +inline ::PROTOBUF_NAMESPACE_ID::UninterpretedOption* FileOptions::mutable_uninterpreted_option(int index) { + // @@protoc_insertion_point(field_mutable:google.protobuf.FileOptions.uninterpreted_option) + return uninterpreted_option_.Mutable(index); +} +inline ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::UninterpretedOption >* +FileOptions::mutable_uninterpreted_option() { + // @@protoc_insertion_point(field_mutable_list:google.protobuf.FileOptions.uninterpreted_option) + return &uninterpreted_option_; +} +inline const ::PROTOBUF_NAMESPACE_ID::UninterpretedOption& FileOptions::_internal_uninterpreted_option(int index) const { + return uninterpreted_option_.Get(index); +} +inline const ::PROTOBUF_NAMESPACE_ID::UninterpretedOption& FileOptions::uninterpreted_option(int index) const { + // @@protoc_insertion_point(field_get:google.protobuf.FileOptions.uninterpreted_option) + return _internal_uninterpreted_option(index); +} +inline ::PROTOBUF_NAMESPACE_ID::UninterpretedOption* FileOptions::_internal_add_uninterpreted_option() { + return uninterpreted_option_.Add(); +} +inline ::PROTOBUF_NAMESPACE_ID::UninterpretedOption* FileOptions::add_uninterpreted_option() { + ::PROTOBUF_NAMESPACE_ID::UninterpretedOption* _add = _internal_add_uninterpreted_option(); + // @@protoc_insertion_point(field_add:google.protobuf.FileOptions.uninterpreted_option) + return _add; +} +inline const ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::UninterpretedOption >& +FileOptions::uninterpreted_option() const { + // @@protoc_insertion_point(field_list:google.protobuf.FileOptions.uninterpreted_option) + return uninterpreted_option_; +} + +// ------------------------------------------------------------------- + +// MessageOptions + +// optional bool message_set_wire_format = 1 [default = false]; +inline bool MessageOptions::_internal_has_message_set_wire_format() const { + bool value = (_has_bits_[0] & 0x00000001u) != 0; + return value; +} +inline bool MessageOptions::has_message_set_wire_format() const { + return _internal_has_message_set_wire_format(); +} +inline void MessageOptions::clear_message_set_wire_format() { + message_set_wire_format_ = false; + _has_bits_[0] &= ~0x00000001u; +} +inline bool MessageOptions::_internal_message_set_wire_format() const { + return message_set_wire_format_; +} +inline bool MessageOptions::message_set_wire_format() const { + // @@protoc_insertion_point(field_get:google.protobuf.MessageOptions.message_set_wire_format) + return _internal_message_set_wire_format(); +} +inline void MessageOptions::_internal_set_message_set_wire_format(bool value) { + _has_bits_[0] |= 0x00000001u; + message_set_wire_format_ = value; +} +inline void MessageOptions::set_message_set_wire_format(bool value) { + _internal_set_message_set_wire_format(value); + // @@protoc_insertion_point(field_set:google.protobuf.MessageOptions.message_set_wire_format) +} + +// optional bool no_standard_descriptor_accessor = 2 [default = false]; +inline bool MessageOptions::_internal_has_no_standard_descriptor_accessor() const { + bool value = (_has_bits_[0] & 0x00000002u) != 0; + return value; +} +inline bool MessageOptions::has_no_standard_descriptor_accessor() const { + return _internal_has_no_standard_descriptor_accessor(); +} +inline void MessageOptions::clear_no_standard_descriptor_accessor() { + no_standard_descriptor_accessor_ = false; + _has_bits_[0] &= ~0x00000002u; +} +inline bool MessageOptions::_internal_no_standard_descriptor_accessor() const { + return no_standard_descriptor_accessor_; +} +inline bool MessageOptions::no_standard_descriptor_accessor() const { + // @@protoc_insertion_point(field_get:google.protobuf.MessageOptions.no_standard_descriptor_accessor) + return _internal_no_standard_descriptor_accessor(); +} +inline void MessageOptions::_internal_set_no_standard_descriptor_accessor(bool value) { + _has_bits_[0] |= 0x00000002u; + no_standard_descriptor_accessor_ = value; +} +inline void MessageOptions::set_no_standard_descriptor_accessor(bool value) { + _internal_set_no_standard_descriptor_accessor(value); + // @@protoc_insertion_point(field_set:google.protobuf.MessageOptions.no_standard_descriptor_accessor) +} + +// optional bool deprecated = 3 [default = false]; +inline bool MessageOptions::_internal_has_deprecated() const { + bool value = (_has_bits_[0] & 0x00000004u) != 0; + return value; +} +inline bool MessageOptions::has_deprecated() const { + return _internal_has_deprecated(); +} +inline void MessageOptions::clear_deprecated() { + deprecated_ = false; + _has_bits_[0] &= ~0x00000004u; +} +inline bool MessageOptions::_internal_deprecated() const { + return deprecated_; +} +inline bool MessageOptions::deprecated() const { + // @@protoc_insertion_point(field_get:google.protobuf.MessageOptions.deprecated) + return _internal_deprecated(); +} +inline void MessageOptions::_internal_set_deprecated(bool value) { + _has_bits_[0] |= 0x00000004u; + deprecated_ = value; +} +inline void MessageOptions::set_deprecated(bool value) { + _internal_set_deprecated(value); + // @@protoc_insertion_point(field_set:google.protobuf.MessageOptions.deprecated) +} + +// optional bool map_entry = 7; +inline bool MessageOptions::_internal_has_map_entry() const { + bool value = (_has_bits_[0] & 0x00000008u) != 0; + return value; +} +inline bool MessageOptions::has_map_entry() const { + return _internal_has_map_entry(); +} +inline void MessageOptions::clear_map_entry() { + map_entry_ = false; + _has_bits_[0] &= ~0x00000008u; +} +inline bool MessageOptions::_internal_map_entry() const { + return map_entry_; +} +inline bool MessageOptions::map_entry() const { + // @@protoc_insertion_point(field_get:google.protobuf.MessageOptions.map_entry) + return _internal_map_entry(); +} +inline void MessageOptions::_internal_set_map_entry(bool value) { + _has_bits_[0] |= 0x00000008u; + map_entry_ = value; +} +inline void MessageOptions::set_map_entry(bool value) { + _internal_set_map_entry(value); + // @@protoc_insertion_point(field_set:google.protobuf.MessageOptions.map_entry) +} + +// repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999; +inline int MessageOptions::_internal_uninterpreted_option_size() const { + return uninterpreted_option_.size(); +} +inline int MessageOptions::uninterpreted_option_size() const { + return _internal_uninterpreted_option_size(); +} +inline void MessageOptions::clear_uninterpreted_option() { + uninterpreted_option_.Clear(); +} +inline ::PROTOBUF_NAMESPACE_ID::UninterpretedOption* MessageOptions::mutable_uninterpreted_option(int index) { + // @@protoc_insertion_point(field_mutable:google.protobuf.MessageOptions.uninterpreted_option) + return uninterpreted_option_.Mutable(index); +} +inline ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::UninterpretedOption >* +MessageOptions::mutable_uninterpreted_option() { + // @@protoc_insertion_point(field_mutable_list:google.protobuf.MessageOptions.uninterpreted_option) + return &uninterpreted_option_; +} +inline const ::PROTOBUF_NAMESPACE_ID::UninterpretedOption& MessageOptions::_internal_uninterpreted_option(int index) const { + return uninterpreted_option_.Get(index); +} +inline const ::PROTOBUF_NAMESPACE_ID::UninterpretedOption& MessageOptions::uninterpreted_option(int index) const { + // @@protoc_insertion_point(field_get:google.protobuf.MessageOptions.uninterpreted_option) + return _internal_uninterpreted_option(index); +} +inline ::PROTOBUF_NAMESPACE_ID::UninterpretedOption* MessageOptions::_internal_add_uninterpreted_option() { + return uninterpreted_option_.Add(); +} +inline ::PROTOBUF_NAMESPACE_ID::UninterpretedOption* MessageOptions::add_uninterpreted_option() { + ::PROTOBUF_NAMESPACE_ID::UninterpretedOption* _add = _internal_add_uninterpreted_option(); + // @@protoc_insertion_point(field_add:google.protobuf.MessageOptions.uninterpreted_option) + return _add; +} +inline const ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::UninterpretedOption >& +MessageOptions::uninterpreted_option() const { + // @@protoc_insertion_point(field_list:google.protobuf.MessageOptions.uninterpreted_option) + return uninterpreted_option_; +} + +// ------------------------------------------------------------------- + +// FieldOptions + +// optional .google.protobuf.FieldOptions.CType ctype = 1 [default = STRING]; +inline bool FieldOptions::_internal_has_ctype() const { + bool value = (_has_bits_[0] & 0x00000001u) != 0; + return value; +} +inline bool FieldOptions::has_ctype() const { + return _internal_has_ctype(); +} +inline void FieldOptions::clear_ctype() { + ctype_ = 0; + _has_bits_[0] &= ~0x00000001u; +} +inline ::PROTOBUF_NAMESPACE_ID::FieldOptions_CType FieldOptions::_internal_ctype() const { + return static_cast< ::PROTOBUF_NAMESPACE_ID::FieldOptions_CType >(ctype_); +} +inline ::PROTOBUF_NAMESPACE_ID::FieldOptions_CType FieldOptions::ctype() const { + // @@protoc_insertion_point(field_get:google.protobuf.FieldOptions.ctype) + return _internal_ctype(); +} +inline void FieldOptions::_internal_set_ctype(::PROTOBUF_NAMESPACE_ID::FieldOptions_CType value) { + assert(::PROTOBUF_NAMESPACE_ID::FieldOptions_CType_IsValid(value)); + _has_bits_[0] |= 0x00000001u; + ctype_ = value; +} +inline void FieldOptions::set_ctype(::PROTOBUF_NAMESPACE_ID::FieldOptions_CType value) { + _internal_set_ctype(value); + // @@protoc_insertion_point(field_set:google.protobuf.FieldOptions.ctype) +} + +// optional bool packed = 2; +inline bool FieldOptions::_internal_has_packed() const { + bool value = (_has_bits_[0] & 0x00000002u) != 0; + return value; +} +inline bool FieldOptions::has_packed() const { + return _internal_has_packed(); +} +inline void FieldOptions::clear_packed() { + packed_ = false; + _has_bits_[0] &= ~0x00000002u; +} +inline bool FieldOptions::_internal_packed() const { + return packed_; +} +inline bool FieldOptions::packed() const { + // @@protoc_insertion_point(field_get:google.protobuf.FieldOptions.packed) + return _internal_packed(); +} +inline void FieldOptions::_internal_set_packed(bool value) { + _has_bits_[0] |= 0x00000002u; + packed_ = value; +} +inline void FieldOptions::set_packed(bool value) { + _internal_set_packed(value); + // @@protoc_insertion_point(field_set:google.protobuf.FieldOptions.packed) +} + +// optional .google.protobuf.FieldOptions.JSType jstype = 6 [default = JS_NORMAL]; +inline bool FieldOptions::_internal_has_jstype() const { + bool value = (_has_bits_[0] & 0x00000020u) != 0; + return value; +} +inline bool FieldOptions::has_jstype() const { + return _internal_has_jstype(); +} +inline void FieldOptions::clear_jstype() { + jstype_ = 0; + _has_bits_[0] &= ~0x00000020u; +} +inline ::PROTOBUF_NAMESPACE_ID::FieldOptions_JSType FieldOptions::_internal_jstype() const { + return static_cast< ::PROTOBUF_NAMESPACE_ID::FieldOptions_JSType >(jstype_); +} +inline ::PROTOBUF_NAMESPACE_ID::FieldOptions_JSType FieldOptions::jstype() const { + // @@protoc_insertion_point(field_get:google.protobuf.FieldOptions.jstype) + return _internal_jstype(); +} +inline void FieldOptions::_internal_set_jstype(::PROTOBUF_NAMESPACE_ID::FieldOptions_JSType value) { + assert(::PROTOBUF_NAMESPACE_ID::FieldOptions_JSType_IsValid(value)); + _has_bits_[0] |= 0x00000020u; + jstype_ = value; +} +inline void FieldOptions::set_jstype(::PROTOBUF_NAMESPACE_ID::FieldOptions_JSType value) { + _internal_set_jstype(value); + // @@protoc_insertion_point(field_set:google.protobuf.FieldOptions.jstype) +} + +// optional bool lazy = 5 [default = false]; +inline bool FieldOptions::_internal_has_lazy() const { + bool value = (_has_bits_[0] & 0x00000004u) != 0; + return value; +} +inline bool FieldOptions::has_lazy() const { + return _internal_has_lazy(); +} +inline void FieldOptions::clear_lazy() { + lazy_ = false; + _has_bits_[0] &= ~0x00000004u; +} +inline bool FieldOptions::_internal_lazy() const { + return lazy_; +} +inline bool FieldOptions::lazy() const { + // @@protoc_insertion_point(field_get:google.protobuf.FieldOptions.lazy) + return _internal_lazy(); +} +inline void FieldOptions::_internal_set_lazy(bool value) { + _has_bits_[0] |= 0x00000004u; + lazy_ = value; +} +inline void FieldOptions::set_lazy(bool value) { + _internal_set_lazy(value); + // @@protoc_insertion_point(field_set:google.protobuf.FieldOptions.lazy) +} + +// optional bool deprecated = 3 [default = false]; +inline bool FieldOptions::_internal_has_deprecated() const { + bool value = (_has_bits_[0] & 0x00000008u) != 0; + return value; +} +inline bool FieldOptions::has_deprecated() const { + return _internal_has_deprecated(); +} +inline void FieldOptions::clear_deprecated() { + deprecated_ = false; + _has_bits_[0] &= ~0x00000008u; +} +inline bool FieldOptions::_internal_deprecated() const { + return deprecated_; +} +inline bool FieldOptions::deprecated() const { + // @@protoc_insertion_point(field_get:google.protobuf.FieldOptions.deprecated) + return _internal_deprecated(); +} +inline void FieldOptions::_internal_set_deprecated(bool value) { + _has_bits_[0] |= 0x00000008u; + deprecated_ = value; +} +inline void FieldOptions::set_deprecated(bool value) { + _internal_set_deprecated(value); + // @@protoc_insertion_point(field_set:google.protobuf.FieldOptions.deprecated) +} + +// optional bool weak = 10 [default = false]; +inline bool FieldOptions::_internal_has_weak() const { + bool value = (_has_bits_[0] & 0x00000010u) != 0; + return value; +} +inline bool FieldOptions::has_weak() const { + return _internal_has_weak(); +} +inline void FieldOptions::clear_weak() { + weak_ = false; + _has_bits_[0] &= ~0x00000010u; +} +inline bool FieldOptions::_internal_weak() const { + return weak_; +} +inline bool FieldOptions::weak() const { + // @@protoc_insertion_point(field_get:google.protobuf.FieldOptions.weak) + return _internal_weak(); +} +inline void FieldOptions::_internal_set_weak(bool value) { + _has_bits_[0] |= 0x00000010u; + weak_ = value; +} +inline void FieldOptions::set_weak(bool value) { + _internal_set_weak(value); + // @@protoc_insertion_point(field_set:google.protobuf.FieldOptions.weak) +} + +// repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999; +inline int FieldOptions::_internal_uninterpreted_option_size() const { + return uninterpreted_option_.size(); +} +inline int FieldOptions::uninterpreted_option_size() const { + return _internal_uninterpreted_option_size(); +} +inline void FieldOptions::clear_uninterpreted_option() { + uninterpreted_option_.Clear(); +} +inline ::PROTOBUF_NAMESPACE_ID::UninterpretedOption* FieldOptions::mutable_uninterpreted_option(int index) { + // @@protoc_insertion_point(field_mutable:google.protobuf.FieldOptions.uninterpreted_option) + return uninterpreted_option_.Mutable(index); +} +inline ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::UninterpretedOption >* +FieldOptions::mutable_uninterpreted_option() { + // @@protoc_insertion_point(field_mutable_list:google.protobuf.FieldOptions.uninterpreted_option) + return &uninterpreted_option_; +} +inline const ::PROTOBUF_NAMESPACE_ID::UninterpretedOption& FieldOptions::_internal_uninterpreted_option(int index) const { + return uninterpreted_option_.Get(index); +} +inline const ::PROTOBUF_NAMESPACE_ID::UninterpretedOption& FieldOptions::uninterpreted_option(int index) const { + // @@protoc_insertion_point(field_get:google.protobuf.FieldOptions.uninterpreted_option) + return _internal_uninterpreted_option(index); +} +inline ::PROTOBUF_NAMESPACE_ID::UninterpretedOption* FieldOptions::_internal_add_uninterpreted_option() { + return uninterpreted_option_.Add(); +} +inline ::PROTOBUF_NAMESPACE_ID::UninterpretedOption* FieldOptions::add_uninterpreted_option() { + ::PROTOBUF_NAMESPACE_ID::UninterpretedOption* _add = _internal_add_uninterpreted_option(); + // @@protoc_insertion_point(field_add:google.protobuf.FieldOptions.uninterpreted_option) + return _add; +} +inline const ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::UninterpretedOption >& +FieldOptions::uninterpreted_option() const { + // @@protoc_insertion_point(field_list:google.protobuf.FieldOptions.uninterpreted_option) + return uninterpreted_option_; +} + +// ------------------------------------------------------------------- + +// OneofOptions + +// repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999; +inline int OneofOptions::_internal_uninterpreted_option_size() const { + return uninterpreted_option_.size(); +} +inline int OneofOptions::uninterpreted_option_size() const { + return _internal_uninterpreted_option_size(); +} +inline void OneofOptions::clear_uninterpreted_option() { + uninterpreted_option_.Clear(); +} +inline ::PROTOBUF_NAMESPACE_ID::UninterpretedOption* OneofOptions::mutable_uninterpreted_option(int index) { + // @@protoc_insertion_point(field_mutable:google.protobuf.OneofOptions.uninterpreted_option) + return uninterpreted_option_.Mutable(index); +} +inline ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::UninterpretedOption >* +OneofOptions::mutable_uninterpreted_option() { + // @@protoc_insertion_point(field_mutable_list:google.protobuf.OneofOptions.uninterpreted_option) + return &uninterpreted_option_; +} +inline const ::PROTOBUF_NAMESPACE_ID::UninterpretedOption& OneofOptions::_internal_uninterpreted_option(int index) const { + return uninterpreted_option_.Get(index); +} +inline const ::PROTOBUF_NAMESPACE_ID::UninterpretedOption& OneofOptions::uninterpreted_option(int index) const { + // @@protoc_insertion_point(field_get:google.protobuf.OneofOptions.uninterpreted_option) + return _internal_uninterpreted_option(index); +} +inline ::PROTOBUF_NAMESPACE_ID::UninterpretedOption* OneofOptions::_internal_add_uninterpreted_option() { + return uninterpreted_option_.Add(); +} +inline ::PROTOBUF_NAMESPACE_ID::UninterpretedOption* OneofOptions::add_uninterpreted_option() { + ::PROTOBUF_NAMESPACE_ID::UninterpretedOption* _add = _internal_add_uninterpreted_option(); + // @@protoc_insertion_point(field_add:google.protobuf.OneofOptions.uninterpreted_option) + return _add; +} +inline const ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::UninterpretedOption >& +OneofOptions::uninterpreted_option() const { + // @@protoc_insertion_point(field_list:google.protobuf.OneofOptions.uninterpreted_option) + return uninterpreted_option_; +} + +// ------------------------------------------------------------------- + +// EnumOptions + +// optional bool allow_alias = 2; +inline bool EnumOptions::_internal_has_allow_alias() const { + bool value = (_has_bits_[0] & 0x00000001u) != 0; + return value; +} +inline bool EnumOptions::has_allow_alias() const { + return _internal_has_allow_alias(); +} +inline void EnumOptions::clear_allow_alias() { + allow_alias_ = false; + _has_bits_[0] &= ~0x00000001u; +} +inline bool EnumOptions::_internal_allow_alias() const { + return allow_alias_; +} +inline bool EnumOptions::allow_alias() const { + // @@protoc_insertion_point(field_get:google.protobuf.EnumOptions.allow_alias) + return _internal_allow_alias(); +} +inline void EnumOptions::_internal_set_allow_alias(bool value) { + _has_bits_[0] |= 0x00000001u; + allow_alias_ = value; +} +inline void EnumOptions::set_allow_alias(bool value) { + _internal_set_allow_alias(value); + // @@protoc_insertion_point(field_set:google.protobuf.EnumOptions.allow_alias) +} + +// optional bool deprecated = 3 [default = false]; +inline bool EnumOptions::_internal_has_deprecated() const { + bool value = (_has_bits_[0] & 0x00000002u) != 0; + return value; +} +inline bool EnumOptions::has_deprecated() const { + return _internal_has_deprecated(); +} +inline void EnumOptions::clear_deprecated() { + deprecated_ = false; + _has_bits_[0] &= ~0x00000002u; +} +inline bool EnumOptions::_internal_deprecated() const { + return deprecated_; +} +inline bool EnumOptions::deprecated() const { + // @@protoc_insertion_point(field_get:google.protobuf.EnumOptions.deprecated) + return _internal_deprecated(); +} +inline void EnumOptions::_internal_set_deprecated(bool value) { + _has_bits_[0] |= 0x00000002u; + deprecated_ = value; +} +inline void EnumOptions::set_deprecated(bool value) { + _internal_set_deprecated(value); + // @@protoc_insertion_point(field_set:google.protobuf.EnumOptions.deprecated) +} + +// repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999; +inline int EnumOptions::_internal_uninterpreted_option_size() const { + return uninterpreted_option_.size(); +} +inline int EnumOptions::uninterpreted_option_size() const { + return _internal_uninterpreted_option_size(); +} +inline void EnumOptions::clear_uninterpreted_option() { + uninterpreted_option_.Clear(); +} +inline ::PROTOBUF_NAMESPACE_ID::UninterpretedOption* EnumOptions::mutable_uninterpreted_option(int index) { + // @@protoc_insertion_point(field_mutable:google.protobuf.EnumOptions.uninterpreted_option) + return uninterpreted_option_.Mutable(index); +} +inline ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::UninterpretedOption >* +EnumOptions::mutable_uninterpreted_option() { + // @@protoc_insertion_point(field_mutable_list:google.protobuf.EnumOptions.uninterpreted_option) + return &uninterpreted_option_; +} +inline const ::PROTOBUF_NAMESPACE_ID::UninterpretedOption& EnumOptions::_internal_uninterpreted_option(int index) const { + return uninterpreted_option_.Get(index); +} +inline const ::PROTOBUF_NAMESPACE_ID::UninterpretedOption& EnumOptions::uninterpreted_option(int index) const { + // @@protoc_insertion_point(field_get:google.protobuf.EnumOptions.uninterpreted_option) + return _internal_uninterpreted_option(index); +} +inline ::PROTOBUF_NAMESPACE_ID::UninterpretedOption* EnumOptions::_internal_add_uninterpreted_option() { + return uninterpreted_option_.Add(); +} +inline ::PROTOBUF_NAMESPACE_ID::UninterpretedOption* EnumOptions::add_uninterpreted_option() { + ::PROTOBUF_NAMESPACE_ID::UninterpretedOption* _add = _internal_add_uninterpreted_option(); + // @@protoc_insertion_point(field_add:google.protobuf.EnumOptions.uninterpreted_option) + return _add; +} +inline const ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::UninterpretedOption >& +EnumOptions::uninterpreted_option() const { + // @@protoc_insertion_point(field_list:google.protobuf.EnumOptions.uninterpreted_option) + return uninterpreted_option_; +} + +// ------------------------------------------------------------------- + +// EnumValueOptions + +// optional bool deprecated = 1 [default = false]; +inline bool EnumValueOptions::_internal_has_deprecated() const { + bool value = (_has_bits_[0] & 0x00000001u) != 0; + return value; +} +inline bool EnumValueOptions::has_deprecated() const { + return _internal_has_deprecated(); +} +inline void EnumValueOptions::clear_deprecated() { + deprecated_ = false; + _has_bits_[0] &= ~0x00000001u; +} +inline bool EnumValueOptions::_internal_deprecated() const { + return deprecated_; +} +inline bool EnumValueOptions::deprecated() const { + // @@protoc_insertion_point(field_get:google.protobuf.EnumValueOptions.deprecated) + return _internal_deprecated(); +} +inline void EnumValueOptions::_internal_set_deprecated(bool value) { + _has_bits_[0] |= 0x00000001u; + deprecated_ = value; +} +inline void EnumValueOptions::set_deprecated(bool value) { + _internal_set_deprecated(value); + // @@protoc_insertion_point(field_set:google.protobuf.EnumValueOptions.deprecated) +} + +// repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999; +inline int EnumValueOptions::_internal_uninterpreted_option_size() const { + return uninterpreted_option_.size(); +} +inline int EnumValueOptions::uninterpreted_option_size() const { + return _internal_uninterpreted_option_size(); +} +inline void EnumValueOptions::clear_uninterpreted_option() { + uninterpreted_option_.Clear(); +} +inline ::PROTOBUF_NAMESPACE_ID::UninterpretedOption* EnumValueOptions::mutable_uninterpreted_option(int index) { + // @@protoc_insertion_point(field_mutable:google.protobuf.EnumValueOptions.uninterpreted_option) + return uninterpreted_option_.Mutable(index); +} +inline ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::UninterpretedOption >* +EnumValueOptions::mutable_uninterpreted_option() { + // @@protoc_insertion_point(field_mutable_list:google.protobuf.EnumValueOptions.uninterpreted_option) + return &uninterpreted_option_; +} +inline const ::PROTOBUF_NAMESPACE_ID::UninterpretedOption& EnumValueOptions::_internal_uninterpreted_option(int index) const { + return uninterpreted_option_.Get(index); +} +inline const ::PROTOBUF_NAMESPACE_ID::UninterpretedOption& EnumValueOptions::uninterpreted_option(int index) const { + // @@protoc_insertion_point(field_get:google.protobuf.EnumValueOptions.uninterpreted_option) + return _internal_uninterpreted_option(index); +} +inline ::PROTOBUF_NAMESPACE_ID::UninterpretedOption* EnumValueOptions::_internal_add_uninterpreted_option() { + return uninterpreted_option_.Add(); +} +inline ::PROTOBUF_NAMESPACE_ID::UninterpretedOption* EnumValueOptions::add_uninterpreted_option() { + ::PROTOBUF_NAMESPACE_ID::UninterpretedOption* _add = _internal_add_uninterpreted_option(); + // @@protoc_insertion_point(field_add:google.protobuf.EnumValueOptions.uninterpreted_option) + return _add; +} +inline const ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::UninterpretedOption >& +EnumValueOptions::uninterpreted_option() const { + // @@protoc_insertion_point(field_list:google.protobuf.EnumValueOptions.uninterpreted_option) + return uninterpreted_option_; +} + +// ------------------------------------------------------------------- + +// ServiceOptions + +// optional bool deprecated = 33 [default = false]; +inline bool ServiceOptions::_internal_has_deprecated() const { + bool value = (_has_bits_[0] & 0x00000001u) != 0; + return value; +} +inline bool ServiceOptions::has_deprecated() const { + return _internal_has_deprecated(); +} +inline void ServiceOptions::clear_deprecated() { + deprecated_ = false; + _has_bits_[0] &= ~0x00000001u; +} +inline bool ServiceOptions::_internal_deprecated() const { + return deprecated_; +} +inline bool ServiceOptions::deprecated() const { + // @@protoc_insertion_point(field_get:google.protobuf.ServiceOptions.deprecated) + return _internal_deprecated(); +} +inline void ServiceOptions::_internal_set_deprecated(bool value) { + _has_bits_[0] |= 0x00000001u; + deprecated_ = value; +} +inline void ServiceOptions::set_deprecated(bool value) { + _internal_set_deprecated(value); + // @@protoc_insertion_point(field_set:google.protobuf.ServiceOptions.deprecated) +} + +// repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999; +inline int ServiceOptions::_internal_uninterpreted_option_size() const { + return uninterpreted_option_.size(); +} +inline int ServiceOptions::uninterpreted_option_size() const { + return _internal_uninterpreted_option_size(); +} +inline void ServiceOptions::clear_uninterpreted_option() { + uninterpreted_option_.Clear(); +} +inline ::PROTOBUF_NAMESPACE_ID::UninterpretedOption* ServiceOptions::mutable_uninterpreted_option(int index) { + // @@protoc_insertion_point(field_mutable:google.protobuf.ServiceOptions.uninterpreted_option) + return uninterpreted_option_.Mutable(index); +} +inline ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::UninterpretedOption >* +ServiceOptions::mutable_uninterpreted_option() { + // @@protoc_insertion_point(field_mutable_list:google.protobuf.ServiceOptions.uninterpreted_option) + return &uninterpreted_option_; +} +inline const ::PROTOBUF_NAMESPACE_ID::UninterpretedOption& ServiceOptions::_internal_uninterpreted_option(int index) const { + return uninterpreted_option_.Get(index); +} +inline const ::PROTOBUF_NAMESPACE_ID::UninterpretedOption& ServiceOptions::uninterpreted_option(int index) const { + // @@protoc_insertion_point(field_get:google.protobuf.ServiceOptions.uninterpreted_option) + return _internal_uninterpreted_option(index); +} +inline ::PROTOBUF_NAMESPACE_ID::UninterpretedOption* ServiceOptions::_internal_add_uninterpreted_option() { + return uninterpreted_option_.Add(); +} +inline ::PROTOBUF_NAMESPACE_ID::UninterpretedOption* ServiceOptions::add_uninterpreted_option() { + ::PROTOBUF_NAMESPACE_ID::UninterpretedOption* _add = _internal_add_uninterpreted_option(); + // @@protoc_insertion_point(field_add:google.protobuf.ServiceOptions.uninterpreted_option) + return _add; +} +inline const ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::UninterpretedOption >& +ServiceOptions::uninterpreted_option() const { + // @@protoc_insertion_point(field_list:google.protobuf.ServiceOptions.uninterpreted_option) + return uninterpreted_option_; +} + +// ------------------------------------------------------------------- + +// MethodOptions + +// optional bool deprecated = 33 [default = false]; +inline bool MethodOptions::_internal_has_deprecated() const { + bool value = (_has_bits_[0] & 0x00000001u) != 0; + return value; +} +inline bool MethodOptions::has_deprecated() const { + return _internal_has_deprecated(); +} +inline void MethodOptions::clear_deprecated() { + deprecated_ = false; + _has_bits_[0] &= ~0x00000001u; +} +inline bool MethodOptions::_internal_deprecated() const { + return deprecated_; +} +inline bool MethodOptions::deprecated() const { + // @@protoc_insertion_point(field_get:google.protobuf.MethodOptions.deprecated) + return _internal_deprecated(); +} +inline void MethodOptions::_internal_set_deprecated(bool value) { + _has_bits_[0] |= 0x00000001u; + deprecated_ = value; +} +inline void MethodOptions::set_deprecated(bool value) { + _internal_set_deprecated(value); + // @@protoc_insertion_point(field_set:google.protobuf.MethodOptions.deprecated) +} + +// optional .google.protobuf.MethodOptions.IdempotencyLevel idempotency_level = 34 [default = IDEMPOTENCY_UNKNOWN]; +inline bool MethodOptions::_internal_has_idempotency_level() const { + bool value = (_has_bits_[0] & 0x00000002u) != 0; + return value; +} +inline bool MethodOptions::has_idempotency_level() const { + return _internal_has_idempotency_level(); +} +inline void MethodOptions::clear_idempotency_level() { + idempotency_level_ = 0; + _has_bits_[0] &= ~0x00000002u; +} +inline ::PROTOBUF_NAMESPACE_ID::MethodOptions_IdempotencyLevel MethodOptions::_internal_idempotency_level() const { + return static_cast< ::PROTOBUF_NAMESPACE_ID::MethodOptions_IdempotencyLevel >(idempotency_level_); +} +inline ::PROTOBUF_NAMESPACE_ID::MethodOptions_IdempotencyLevel MethodOptions::idempotency_level() const { + // @@protoc_insertion_point(field_get:google.protobuf.MethodOptions.idempotency_level) + return _internal_idempotency_level(); +} +inline void MethodOptions::_internal_set_idempotency_level(::PROTOBUF_NAMESPACE_ID::MethodOptions_IdempotencyLevel value) { + assert(::PROTOBUF_NAMESPACE_ID::MethodOptions_IdempotencyLevel_IsValid(value)); + _has_bits_[0] |= 0x00000002u; + idempotency_level_ = value; +} +inline void MethodOptions::set_idempotency_level(::PROTOBUF_NAMESPACE_ID::MethodOptions_IdempotencyLevel value) { + _internal_set_idempotency_level(value); + // @@protoc_insertion_point(field_set:google.protobuf.MethodOptions.idempotency_level) +} + +// repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999; +inline int MethodOptions::_internal_uninterpreted_option_size() const { + return uninterpreted_option_.size(); +} +inline int MethodOptions::uninterpreted_option_size() const { + return _internal_uninterpreted_option_size(); +} +inline void MethodOptions::clear_uninterpreted_option() { + uninterpreted_option_.Clear(); +} +inline ::PROTOBUF_NAMESPACE_ID::UninterpretedOption* MethodOptions::mutable_uninterpreted_option(int index) { + // @@protoc_insertion_point(field_mutable:google.protobuf.MethodOptions.uninterpreted_option) + return uninterpreted_option_.Mutable(index); +} +inline ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::UninterpretedOption >* +MethodOptions::mutable_uninterpreted_option() { + // @@protoc_insertion_point(field_mutable_list:google.protobuf.MethodOptions.uninterpreted_option) + return &uninterpreted_option_; +} +inline const ::PROTOBUF_NAMESPACE_ID::UninterpretedOption& MethodOptions::_internal_uninterpreted_option(int index) const { + return uninterpreted_option_.Get(index); +} +inline const ::PROTOBUF_NAMESPACE_ID::UninterpretedOption& MethodOptions::uninterpreted_option(int index) const { + // @@protoc_insertion_point(field_get:google.protobuf.MethodOptions.uninterpreted_option) + return _internal_uninterpreted_option(index); +} +inline ::PROTOBUF_NAMESPACE_ID::UninterpretedOption* MethodOptions::_internal_add_uninterpreted_option() { + return uninterpreted_option_.Add(); +} +inline ::PROTOBUF_NAMESPACE_ID::UninterpretedOption* MethodOptions::add_uninterpreted_option() { + ::PROTOBUF_NAMESPACE_ID::UninterpretedOption* _add = _internal_add_uninterpreted_option(); + // @@protoc_insertion_point(field_add:google.protobuf.MethodOptions.uninterpreted_option) + return _add; +} +inline const ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::UninterpretedOption >& +MethodOptions::uninterpreted_option() const { + // @@protoc_insertion_point(field_list:google.protobuf.MethodOptions.uninterpreted_option) + return uninterpreted_option_; +} + +// ------------------------------------------------------------------- + +// UninterpretedOption_NamePart + +// required string name_part = 1; +inline bool UninterpretedOption_NamePart::_internal_has_name_part() const { + bool value = (_has_bits_[0] & 0x00000001u) != 0; + return value; +} +inline bool UninterpretedOption_NamePart::has_name_part() const { + return _internal_has_name_part(); +} +inline void UninterpretedOption_NamePart::clear_name_part() { + name_part_.ClearToEmpty(); + _has_bits_[0] &= ~0x00000001u; +} +inline const TProtoStringType& UninterpretedOption_NamePart::name_part() const { + // @@protoc_insertion_point(field_get:google.protobuf.UninterpretedOption.NamePart.name_part) + return _internal_name_part(); +} +template <typename ArgT0, typename... ArgT> +inline PROTOBUF_ALWAYS_INLINE +void UninterpretedOption_NamePart::set_name_part(ArgT0&& arg0, ArgT... args) { + _has_bits_[0] |= 0x00000001u; + name_part_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, static_cast<ArgT0 &&>(arg0), args..., GetArenaForAllocation()); + // @@protoc_insertion_point(field_set:google.protobuf.UninterpretedOption.NamePart.name_part) +} +inline TProtoStringType* UninterpretedOption_NamePart::mutable_name_part() { + TProtoStringType* _s = _internal_mutable_name_part(); + // @@protoc_insertion_point(field_mutable:google.protobuf.UninterpretedOption.NamePart.name_part) + return _s; +} +inline const TProtoStringType& UninterpretedOption_NamePart::_internal_name_part() const { + return name_part_.Get(); +} +inline void UninterpretedOption_NamePart::_internal_set_name_part(const TProtoStringType& value) { + _has_bits_[0] |= 0x00000001u; + name_part_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, value, GetArenaForAllocation()); +} +inline TProtoStringType* UninterpretedOption_NamePart::_internal_mutable_name_part() { + _has_bits_[0] |= 0x00000001u; + return name_part_.Mutable(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, GetArenaForAllocation()); +} +inline TProtoStringType* UninterpretedOption_NamePart::release_name_part() { + // @@protoc_insertion_point(field_release:google.protobuf.UninterpretedOption.NamePart.name_part) + if (!_internal_has_name_part()) { + return nullptr; + } + _has_bits_[0] &= ~0x00000001u; + auto* p = name_part_.ReleaseNonDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArenaForAllocation()); +#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING + if (name_part_.IsDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited())) { + name_part_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation()); + } +#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING + return p; +} +inline void UninterpretedOption_NamePart::set_allocated_name_part(TProtoStringType* name_part) { + if (name_part != nullptr) { + _has_bits_[0] |= 0x00000001u; + } else { + _has_bits_[0] &= ~0x00000001u; + } + name_part_.SetAllocated(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), name_part, + GetArenaForAllocation()); +#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING + if (name_part_.IsDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited())) { + name_part_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation()); + } +#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING + // @@protoc_insertion_point(field_set_allocated:google.protobuf.UninterpretedOption.NamePart.name_part) +} + +// required bool is_extension = 2; +inline bool UninterpretedOption_NamePart::_internal_has_is_extension() const { + bool value = (_has_bits_[0] & 0x00000002u) != 0; + return value; +} +inline bool UninterpretedOption_NamePart::has_is_extension() const { + return _internal_has_is_extension(); +} +inline void UninterpretedOption_NamePart::clear_is_extension() { + is_extension_ = false; + _has_bits_[0] &= ~0x00000002u; +} +inline bool UninterpretedOption_NamePart::_internal_is_extension() const { + return is_extension_; +} +inline bool UninterpretedOption_NamePart::is_extension() const { + // @@protoc_insertion_point(field_get:google.protobuf.UninterpretedOption.NamePart.is_extension) + return _internal_is_extension(); +} +inline void UninterpretedOption_NamePart::_internal_set_is_extension(bool value) { + _has_bits_[0] |= 0x00000002u; + is_extension_ = value; +} +inline void UninterpretedOption_NamePart::set_is_extension(bool value) { + _internal_set_is_extension(value); + // @@protoc_insertion_point(field_set:google.protobuf.UninterpretedOption.NamePart.is_extension) +} + +// ------------------------------------------------------------------- + +// UninterpretedOption + +// repeated .google.protobuf.UninterpretedOption.NamePart name = 2; +inline int UninterpretedOption::_internal_name_size() const { + return name_.size(); +} +inline int UninterpretedOption::name_size() const { + return _internal_name_size(); +} +inline void UninterpretedOption::clear_name() { + name_.Clear(); +} +inline ::PROTOBUF_NAMESPACE_ID::UninterpretedOption_NamePart* UninterpretedOption::mutable_name(int index) { + // @@protoc_insertion_point(field_mutable:google.protobuf.UninterpretedOption.name) + return name_.Mutable(index); +} +inline ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::UninterpretedOption_NamePart >* +UninterpretedOption::mutable_name() { + // @@protoc_insertion_point(field_mutable_list:google.protobuf.UninterpretedOption.name) + return &name_; +} +inline const ::PROTOBUF_NAMESPACE_ID::UninterpretedOption_NamePart& UninterpretedOption::_internal_name(int index) const { + return name_.Get(index); +} +inline const ::PROTOBUF_NAMESPACE_ID::UninterpretedOption_NamePart& UninterpretedOption::name(int index) const { + // @@protoc_insertion_point(field_get:google.protobuf.UninterpretedOption.name) + return _internal_name(index); +} +inline ::PROTOBUF_NAMESPACE_ID::UninterpretedOption_NamePart* UninterpretedOption::_internal_add_name() { + return name_.Add(); +} +inline ::PROTOBUF_NAMESPACE_ID::UninterpretedOption_NamePart* UninterpretedOption::add_name() { + ::PROTOBUF_NAMESPACE_ID::UninterpretedOption_NamePart* _add = _internal_add_name(); + // @@protoc_insertion_point(field_add:google.protobuf.UninterpretedOption.name) + return _add; +} +inline const ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::UninterpretedOption_NamePart >& +UninterpretedOption::name() const { + // @@protoc_insertion_point(field_list:google.protobuf.UninterpretedOption.name) + return name_; +} + +// optional string identifier_value = 3; +inline bool UninterpretedOption::_internal_has_identifier_value() const { + bool value = (_has_bits_[0] & 0x00000001u) != 0; + return value; +} +inline bool UninterpretedOption::has_identifier_value() const { + return _internal_has_identifier_value(); +} +inline void UninterpretedOption::clear_identifier_value() { + identifier_value_.ClearToEmpty(); + _has_bits_[0] &= ~0x00000001u; +} +inline const TProtoStringType& UninterpretedOption::identifier_value() const { + // @@protoc_insertion_point(field_get:google.protobuf.UninterpretedOption.identifier_value) + return _internal_identifier_value(); +} +template <typename ArgT0, typename... ArgT> +inline PROTOBUF_ALWAYS_INLINE +void UninterpretedOption::set_identifier_value(ArgT0&& arg0, ArgT... args) { + _has_bits_[0] |= 0x00000001u; + identifier_value_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, static_cast<ArgT0 &&>(arg0), args..., GetArenaForAllocation()); + // @@protoc_insertion_point(field_set:google.protobuf.UninterpretedOption.identifier_value) +} +inline TProtoStringType* UninterpretedOption::mutable_identifier_value() { + TProtoStringType* _s = _internal_mutable_identifier_value(); + // @@protoc_insertion_point(field_mutable:google.protobuf.UninterpretedOption.identifier_value) + return _s; +} +inline const TProtoStringType& UninterpretedOption::_internal_identifier_value() const { + return identifier_value_.Get(); +} +inline void UninterpretedOption::_internal_set_identifier_value(const TProtoStringType& value) { + _has_bits_[0] |= 0x00000001u; + identifier_value_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, value, GetArenaForAllocation()); +} +inline TProtoStringType* UninterpretedOption::_internal_mutable_identifier_value() { + _has_bits_[0] |= 0x00000001u; + return identifier_value_.Mutable(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, GetArenaForAllocation()); +} +inline TProtoStringType* UninterpretedOption::release_identifier_value() { + // @@protoc_insertion_point(field_release:google.protobuf.UninterpretedOption.identifier_value) + if (!_internal_has_identifier_value()) { + return nullptr; + } + _has_bits_[0] &= ~0x00000001u; + auto* p = identifier_value_.ReleaseNonDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArenaForAllocation()); +#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING + if (identifier_value_.IsDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited())) { + identifier_value_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation()); + } +#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING + return p; +} +inline void UninterpretedOption::set_allocated_identifier_value(TProtoStringType* identifier_value) { + if (identifier_value != nullptr) { + _has_bits_[0] |= 0x00000001u; + } else { + _has_bits_[0] &= ~0x00000001u; + } + identifier_value_.SetAllocated(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), identifier_value, + GetArenaForAllocation()); +#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING + if (identifier_value_.IsDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited())) { + identifier_value_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation()); + } +#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING + // @@protoc_insertion_point(field_set_allocated:google.protobuf.UninterpretedOption.identifier_value) +} + +// optional uint64 positive_int_value = 4; +inline bool UninterpretedOption::_internal_has_positive_int_value() const { + bool value = (_has_bits_[0] & 0x00000008u) != 0; + return value; +} +inline bool UninterpretedOption::has_positive_int_value() const { + return _internal_has_positive_int_value(); +} +inline void UninterpretedOption::clear_positive_int_value() { + positive_int_value_ = arc_ui64{0u}; + _has_bits_[0] &= ~0x00000008u; +} +inline arc_ui64 UninterpretedOption::_internal_positive_int_value() const { + return positive_int_value_; +} +inline arc_ui64 UninterpretedOption::positive_int_value() const { + // @@protoc_insertion_point(field_get:google.protobuf.UninterpretedOption.positive_int_value) + return _internal_positive_int_value(); +} +inline void UninterpretedOption::_internal_set_positive_int_value(arc_ui64 value) { + _has_bits_[0] |= 0x00000008u; + positive_int_value_ = value; +} +inline void UninterpretedOption::set_positive_int_value(arc_ui64 value) { + _internal_set_positive_int_value(value); + // @@protoc_insertion_point(field_set:google.protobuf.UninterpretedOption.positive_int_value) +} + +// optional int64 negative_int_value = 5; +inline bool UninterpretedOption::_internal_has_negative_int_value() const { + bool value = (_has_bits_[0] & 0x00000010u) != 0; + return value; +} +inline bool UninterpretedOption::has_negative_int_value() const { + return _internal_has_negative_int_value(); +} +inline void UninterpretedOption::clear_negative_int_value() { + negative_int_value_ = arc_i64{0}; + _has_bits_[0] &= ~0x00000010u; +} +inline arc_i64 UninterpretedOption::_internal_negative_int_value() const { + return negative_int_value_; +} +inline arc_i64 UninterpretedOption::negative_int_value() const { + // @@protoc_insertion_point(field_get:google.protobuf.UninterpretedOption.negative_int_value) + return _internal_negative_int_value(); +} +inline void UninterpretedOption::_internal_set_negative_int_value(arc_i64 value) { + _has_bits_[0] |= 0x00000010u; + negative_int_value_ = value; +} +inline void UninterpretedOption::set_negative_int_value(arc_i64 value) { + _internal_set_negative_int_value(value); + // @@protoc_insertion_point(field_set:google.protobuf.UninterpretedOption.negative_int_value) +} + +// optional double double_value = 6; +inline bool UninterpretedOption::_internal_has_double_value() const { + bool value = (_has_bits_[0] & 0x00000020u) != 0; + return value; +} +inline bool UninterpretedOption::has_double_value() const { + return _internal_has_double_value(); +} +inline void UninterpretedOption::clear_double_value() { + double_value_ = 0; + _has_bits_[0] &= ~0x00000020u; +} +inline double UninterpretedOption::_internal_double_value() const { + return double_value_; +} +inline double UninterpretedOption::double_value() const { + // @@protoc_insertion_point(field_get:google.protobuf.UninterpretedOption.double_value) + return _internal_double_value(); +} +inline void UninterpretedOption::_internal_set_double_value(double value) { + _has_bits_[0] |= 0x00000020u; + double_value_ = value; +} +inline void UninterpretedOption::set_double_value(double value) { + _internal_set_double_value(value); + // @@protoc_insertion_point(field_set:google.protobuf.UninterpretedOption.double_value) +} + +// optional bytes string_value = 7; +inline bool UninterpretedOption::_internal_has_string_value() const { + bool value = (_has_bits_[0] & 0x00000002u) != 0; + return value; +} +inline bool UninterpretedOption::has_string_value() const { + return _internal_has_string_value(); +} +inline void UninterpretedOption::clear_string_value() { + string_value_.ClearToEmpty(); + _has_bits_[0] &= ~0x00000002u; +} +inline const TProtoStringType& UninterpretedOption::string_value() const { + // @@protoc_insertion_point(field_get:google.protobuf.UninterpretedOption.string_value) + return _internal_string_value(); +} +template <typename ArgT0, typename... ArgT> +inline PROTOBUF_ALWAYS_INLINE +void UninterpretedOption::set_string_value(ArgT0&& arg0, ArgT... args) { + _has_bits_[0] |= 0x00000002u; + string_value_.SetBytes(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, static_cast<ArgT0 &&>(arg0), args..., GetArenaForAllocation()); + // @@protoc_insertion_point(field_set:google.protobuf.UninterpretedOption.string_value) +} +inline TProtoStringType* UninterpretedOption::mutable_string_value() { + TProtoStringType* _s = _internal_mutable_string_value(); + // @@protoc_insertion_point(field_mutable:google.protobuf.UninterpretedOption.string_value) + return _s; +} +inline const TProtoStringType& UninterpretedOption::_internal_string_value() const { + return string_value_.Get(); +} +inline void UninterpretedOption::_internal_set_string_value(const TProtoStringType& value) { + _has_bits_[0] |= 0x00000002u; + string_value_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, value, GetArenaForAllocation()); +} +inline TProtoStringType* UninterpretedOption::_internal_mutable_string_value() { + _has_bits_[0] |= 0x00000002u; + return string_value_.Mutable(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, GetArenaForAllocation()); +} +inline TProtoStringType* UninterpretedOption::release_string_value() { + // @@protoc_insertion_point(field_release:google.protobuf.UninterpretedOption.string_value) + if (!_internal_has_string_value()) { + return nullptr; + } + _has_bits_[0] &= ~0x00000002u; + auto* p = string_value_.ReleaseNonDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArenaForAllocation()); +#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING + if (string_value_.IsDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited())) { + string_value_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation()); + } +#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING + return p; +} +inline void UninterpretedOption::set_allocated_string_value(TProtoStringType* string_value) { + if (string_value != nullptr) { + _has_bits_[0] |= 0x00000002u; + } else { + _has_bits_[0] &= ~0x00000002u; + } + string_value_.SetAllocated(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), string_value, + GetArenaForAllocation()); +#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING + if (string_value_.IsDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited())) { + string_value_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation()); + } +#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING + // @@protoc_insertion_point(field_set_allocated:google.protobuf.UninterpretedOption.string_value) +} + +// optional string aggregate_value = 8; +inline bool UninterpretedOption::_internal_has_aggregate_value() const { + bool value = (_has_bits_[0] & 0x00000004u) != 0; + return value; +} +inline bool UninterpretedOption::has_aggregate_value() const { + return _internal_has_aggregate_value(); +} +inline void UninterpretedOption::clear_aggregate_value() { + aggregate_value_.ClearToEmpty(); + _has_bits_[0] &= ~0x00000004u; +} +inline const TProtoStringType& UninterpretedOption::aggregate_value() const { + // @@protoc_insertion_point(field_get:google.protobuf.UninterpretedOption.aggregate_value) + return _internal_aggregate_value(); +} +template <typename ArgT0, typename... ArgT> +inline PROTOBUF_ALWAYS_INLINE +void UninterpretedOption::set_aggregate_value(ArgT0&& arg0, ArgT... args) { + _has_bits_[0] |= 0x00000004u; + aggregate_value_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, static_cast<ArgT0 &&>(arg0), args..., GetArenaForAllocation()); + // @@protoc_insertion_point(field_set:google.protobuf.UninterpretedOption.aggregate_value) +} +inline TProtoStringType* UninterpretedOption::mutable_aggregate_value() { + TProtoStringType* _s = _internal_mutable_aggregate_value(); + // @@protoc_insertion_point(field_mutable:google.protobuf.UninterpretedOption.aggregate_value) + return _s; +} +inline const TProtoStringType& UninterpretedOption::_internal_aggregate_value() const { + return aggregate_value_.Get(); +} +inline void UninterpretedOption::_internal_set_aggregate_value(const TProtoStringType& value) { + _has_bits_[0] |= 0x00000004u; + aggregate_value_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, value, GetArenaForAllocation()); +} +inline TProtoStringType* UninterpretedOption::_internal_mutable_aggregate_value() { + _has_bits_[0] |= 0x00000004u; + return aggregate_value_.Mutable(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, GetArenaForAllocation()); +} +inline TProtoStringType* UninterpretedOption::release_aggregate_value() { + // @@protoc_insertion_point(field_release:google.protobuf.UninterpretedOption.aggregate_value) + if (!_internal_has_aggregate_value()) { + return nullptr; + } + _has_bits_[0] &= ~0x00000004u; + auto* p = aggregate_value_.ReleaseNonDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArenaForAllocation()); +#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING + if (aggregate_value_.IsDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited())) { + aggregate_value_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation()); + } +#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING + return p; +} +inline void UninterpretedOption::set_allocated_aggregate_value(TProtoStringType* aggregate_value) { + if (aggregate_value != nullptr) { + _has_bits_[0] |= 0x00000004u; + } else { + _has_bits_[0] &= ~0x00000004u; + } + aggregate_value_.SetAllocated(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), aggregate_value, + GetArenaForAllocation()); +#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING + if (aggregate_value_.IsDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited())) { + aggregate_value_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation()); + } +#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING + // @@protoc_insertion_point(field_set_allocated:google.protobuf.UninterpretedOption.aggregate_value) +} + +// ------------------------------------------------------------------- + +// SourceCodeInfo_Location + +// repeated int32 path = 1 [packed = true]; +inline int SourceCodeInfo_Location::_internal_path_size() const { + return path_.size(); +} +inline int SourceCodeInfo_Location::path_size() const { + return _internal_path_size(); +} +inline void SourceCodeInfo_Location::clear_path() { + path_.Clear(); +} +inline arc_i32 SourceCodeInfo_Location::_internal_path(int index) const { + return path_.Get(index); +} +inline arc_i32 SourceCodeInfo_Location::path(int index) const { + // @@protoc_insertion_point(field_get:google.protobuf.SourceCodeInfo.Location.path) + return _internal_path(index); +} +inline void SourceCodeInfo_Location::set_path(int index, arc_i32 value) { + path_.Set(index, value); + // @@protoc_insertion_point(field_set:google.protobuf.SourceCodeInfo.Location.path) +} +inline void SourceCodeInfo_Location::_internal_add_path(arc_i32 value) { + path_.Add(value); +} +inline void SourceCodeInfo_Location::add_path(arc_i32 value) { + _internal_add_path(value); + // @@protoc_insertion_point(field_add:google.protobuf.SourceCodeInfo.Location.path) +} +inline const ::PROTOBUF_NAMESPACE_ID::RepeatedField< arc_i32 >& +SourceCodeInfo_Location::_internal_path() const { + return path_; +} +inline const ::PROTOBUF_NAMESPACE_ID::RepeatedField< arc_i32 >& +SourceCodeInfo_Location::path() const { + // @@protoc_insertion_point(field_list:google.protobuf.SourceCodeInfo.Location.path) + return _internal_path(); +} +inline ::PROTOBUF_NAMESPACE_ID::RepeatedField< arc_i32 >* +SourceCodeInfo_Location::_internal_mutable_path() { + return &path_; +} +inline ::PROTOBUF_NAMESPACE_ID::RepeatedField< arc_i32 >* +SourceCodeInfo_Location::mutable_path() { + // @@protoc_insertion_point(field_mutable_list:google.protobuf.SourceCodeInfo.Location.path) + return _internal_mutable_path(); +} + +// repeated int32 span = 2 [packed = true]; +inline int SourceCodeInfo_Location::_internal_span_size() const { + return span_.size(); +} +inline int SourceCodeInfo_Location::span_size() const { + return _internal_span_size(); +} +inline void SourceCodeInfo_Location::clear_span() { + span_.Clear(); +} +inline arc_i32 SourceCodeInfo_Location::_internal_span(int index) const { + return span_.Get(index); +} +inline arc_i32 SourceCodeInfo_Location::span(int index) const { + // @@protoc_insertion_point(field_get:google.protobuf.SourceCodeInfo.Location.span) + return _internal_span(index); +} +inline void SourceCodeInfo_Location::set_span(int index, arc_i32 value) { + span_.Set(index, value); + // @@protoc_insertion_point(field_set:google.protobuf.SourceCodeInfo.Location.span) +} +inline void SourceCodeInfo_Location::_internal_add_span(arc_i32 value) { + span_.Add(value); +} +inline void SourceCodeInfo_Location::add_span(arc_i32 value) { + _internal_add_span(value); + // @@protoc_insertion_point(field_add:google.protobuf.SourceCodeInfo.Location.span) +} +inline const ::PROTOBUF_NAMESPACE_ID::RepeatedField< arc_i32 >& +SourceCodeInfo_Location::_internal_span() const { + return span_; +} +inline const ::PROTOBUF_NAMESPACE_ID::RepeatedField< arc_i32 >& +SourceCodeInfo_Location::span() const { + // @@protoc_insertion_point(field_list:google.protobuf.SourceCodeInfo.Location.span) + return _internal_span(); +} +inline ::PROTOBUF_NAMESPACE_ID::RepeatedField< arc_i32 >* +SourceCodeInfo_Location::_internal_mutable_span() { + return &span_; +} +inline ::PROTOBUF_NAMESPACE_ID::RepeatedField< arc_i32 >* +SourceCodeInfo_Location::mutable_span() { + // @@protoc_insertion_point(field_mutable_list:google.protobuf.SourceCodeInfo.Location.span) + return _internal_mutable_span(); +} + +// optional string leading_comments = 3; +inline bool SourceCodeInfo_Location::_internal_has_leading_comments() const { + bool value = (_has_bits_[0] & 0x00000001u) != 0; + return value; +} +inline bool SourceCodeInfo_Location::has_leading_comments() const { + return _internal_has_leading_comments(); +} +inline void SourceCodeInfo_Location::clear_leading_comments() { + leading_comments_.ClearToEmpty(); + _has_bits_[0] &= ~0x00000001u; +} +inline const TProtoStringType& SourceCodeInfo_Location::leading_comments() const { + // @@protoc_insertion_point(field_get:google.protobuf.SourceCodeInfo.Location.leading_comments) + return _internal_leading_comments(); +} +template <typename ArgT0, typename... ArgT> +inline PROTOBUF_ALWAYS_INLINE +void SourceCodeInfo_Location::set_leading_comments(ArgT0&& arg0, ArgT... args) { + _has_bits_[0] |= 0x00000001u; + leading_comments_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, static_cast<ArgT0 &&>(arg0), args..., GetArenaForAllocation()); + // @@protoc_insertion_point(field_set:google.protobuf.SourceCodeInfo.Location.leading_comments) +} +inline TProtoStringType* SourceCodeInfo_Location::mutable_leading_comments() { + TProtoStringType* _s = _internal_mutable_leading_comments(); + // @@protoc_insertion_point(field_mutable:google.protobuf.SourceCodeInfo.Location.leading_comments) + return _s; +} +inline const TProtoStringType& SourceCodeInfo_Location::_internal_leading_comments() const { + return leading_comments_.Get(); +} +inline void SourceCodeInfo_Location::_internal_set_leading_comments(const TProtoStringType& value) { + _has_bits_[0] |= 0x00000001u; + leading_comments_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, value, GetArenaForAllocation()); +} +inline TProtoStringType* SourceCodeInfo_Location::_internal_mutable_leading_comments() { + _has_bits_[0] |= 0x00000001u; + return leading_comments_.Mutable(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, GetArenaForAllocation()); +} +inline TProtoStringType* SourceCodeInfo_Location::release_leading_comments() { + // @@protoc_insertion_point(field_release:google.protobuf.SourceCodeInfo.Location.leading_comments) + if (!_internal_has_leading_comments()) { + return nullptr; + } + _has_bits_[0] &= ~0x00000001u; + auto* p = leading_comments_.ReleaseNonDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArenaForAllocation()); +#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING + if (leading_comments_.IsDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited())) { + leading_comments_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation()); + } +#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING + return p; +} +inline void SourceCodeInfo_Location::set_allocated_leading_comments(TProtoStringType* leading_comments) { + if (leading_comments != nullptr) { + _has_bits_[0] |= 0x00000001u; + } else { + _has_bits_[0] &= ~0x00000001u; + } + leading_comments_.SetAllocated(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), leading_comments, + GetArenaForAllocation()); +#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING + if (leading_comments_.IsDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited())) { + leading_comments_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation()); + } +#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING + // @@protoc_insertion_point(field_set_allocated:google.protobuf.SourceCodeInfo.Location.leading_comments) +} + +// optional string trailing_comments = 4; +inline bool SourceCodeInfo_Location::_internal_has_trailing_comments() const { + bool value = (_has_bits_[0] & 0x00000002u) != 0; + return value; +} +inline bool SourceCodeInfo_Location::has_trailing_comments() const { + return _internal_has_trailing_comments(); +} +inline void SourceCodeInfo_Location::clear_trailing_comments() { + trailing_comments_.ClearToEmpty(); + _has_bits_[0] &= ~0x00000002u; +} +inline const TProtoStringType& SourceCodeInfo_Location::trailing_comments() const { + // @@protoc_insertion_point(field_get:google.protobuf.SourceCodeInfo.Location.trailing_comments) + return _internal_trailing_comments(); +} +template <typename ArgT0, typename... ArgT> +inline PROTOBUF_ALWAYS_INLINE +void SourceCodeInfo_Location::set_trailing_comments(ArgT0&& arg0, ArgT... args) { + _has_bits_[0] |= 0x00000002u; + trailing_comments_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, static_cast<ArgT0 &&>(arg0), args..., GetArenaForAllocation()); + // @@protoc_insertion_point(field_set:google.protobuf.SourceCodeInfo.Location.trailing_comments) +} +inline TProtoStringType* SourceCodeInfo_Location::mutable_trailing_comments() { + TProtoStringType* _s = _internal_mutable_trailing_comments(); + // @@protoc_insertion_point(field_mutable:google.protobuf.SourceCodeInfo.Location.trailing_comments) + return _s; +} +inline const TProtoStringType& SourceCodeInfo_Location::_internal_trailing_comments() const { + return trailing_comments_.Get(); +} +inline void SourceCodeInfo_Location::_internal_set_trailing_comments(const TProtoStringType& value) { + _has_bits_[0] |= 0x00000002u; + trailing_comments_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, value, GetArenaForAllocation()); +} +inline TProtoStringType* SourceCodeInfo_Location::_internal_mutable_trailing_comments() { + _has_bits_[0] |= 0x00000002u; + return trailing_comments_.Mutable(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, GetArenaForAllocation()); +} +inline TProtoStringType* SourceCodeInfo_Location::release_trailing_comments() { + // @@protoc_insertion_point(field_release:google.protobuf.SourceCodeInfo.Location.trailing_comments) + if (!_internal_has_trailing_comments()) { + return nullptr; + } + _has_bits_[0] &= ~0x00000002u; + auto* p = trailing_comments_.ReleaseNonDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArenaForAllocation()); +#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING + if (trailing_comments_.IsDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited())) { + trailing_comments_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation()); + } +#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING + return p; +} +inline void SourceCodeInfo_Location::set_allocated_trailing_comments(TProtoStringType* trailing_comments) { + if (trailing_comments != nullptr) { + _has_bits_[0] |= 0x00000002u; + } else { + _has_bits_[0] &= ~0x00000002u; + } + trailing_comments_.SetAllocated(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), trailing_comments, + GetArenaForAllocation()); +#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING + if (trailing_comments_.IsDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited())) { + trailing_comments_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation()); + } +#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING + // @@protoc_insertion_point(field_set_allocated:google.protobuf.SourceCodeInfo.Location.trailing_comments) +} + +// repeated string leading_detached_comments = 6; +inline int SourceCodeInfo_Location::_internal_leading_detached_comments_size() const { + return leading_detached_comments_.size(); +} +inline int SourceCodeInfo_Location::leading_detached_comments_size() const { + return _internal_leading_detached_comments_size(); +} +inline void SourceCodeInfo_Location::clear_leading_detached_comments() { + leading_detached_comments_.Clear(); +} +inline TProtoStringType* SourceCodeInfo_Location::add_leading_detached_comments() { + TProtoStringType* _s = _internal_add_leading_detached_comments(); + // @@protoc_insertion_point(field_add_mutable:google.protobuf.SourceCodeInfo.Location.leading_detached_comments) + return _s; +} +inline const TProtoStringType& SourceCodeInfo_Location::_internal_leading_detached_comments(int index) const { + return leading_detached_comments_.Get(index); +} +inline const TProtoStringType& SourceCodeInfo_Location::leading_detached_comments(int index) const { + // @@protoc_insertion_point(field_get:google.protobuf.SourceCodeInfo.Location.leading_detached_comments) + return _internal_leading_detached_comments(index); +} +inline TProtoStringType* SourceCodeInfo_Location::mutable_leading_detached_comments(int index) { + // @@protoc_insertion_point(field_mutable:google.protobuf.SourceCodeInfo.Location.leading_detached_comments) + return leading_detached_comments_.Mutable(index); +} +inline void SourceCodeInfo_Location::set_leading_detached_comments(int index, const TProtoStringType& value) { + leading_detached_comments_.Mutable(index)->assign(value); + // @@protoc_insertion_point(field_set:google.protobuf.SourceCodeInfo.Location.leading_detached_comments) +} +inline void SourceCodeInfo_Location::set_leading_detached_comments(int index, TProtoStringType&& value) { + leading_detached_comments_.Mutable(index)->assign(std::move(value)); + // @@protoc_insertion_point(field_set:google.protobuf.SourceCodeInfo.Location.leading_detached_comments) +} +inline void SourceCodeInfo_Location::set_leading_detached_comments(int index, const char* value) { + GOOGLE_DCHECK(value != nullptr); + leading_detached_comments_.Mutable(index)->assign(value); + // @@protoc_insertion_point(field_set_char:google.protobuf.SourceCodeInfo.Location.leading_detached_comments) +} +inline void SourceCodeInfo_Location::set_leading_detached_comments(int index, const char* value, size_t size) { + leading_detached_comments_.Mutable(index)->assign( + reinterpret_cast<const char*>(value), size); + // @@protoc_insertion_point(field_set_pointer:google.protobuf.SourceCodeInfo.Location.leading_detached_comments) +} +inline TProtoStringType* SourceCodeInfo_Location::_internal_add_leading_detached_comments() { + return leading_detached_comments_.Add(); +} +inline void SourceCodeInfo_Location::add_leading_detached_comments(const TProtoStringType& value) { + leading_detached_comments_.Add()->assign(value); + // @@protoc_insertion_point(field_add:google.protobuf.SourceCodeInfo.Location.leading_detached_comments) +} +inline void SourceCodeInfo_Location::add_leading_detached_comments(TProtoStringType&& value) { + leading_detached_comments_.Add(std::move(value)); + // @@protoc_insertion_point(field_add:google.protobuf.SourceCodeInfo.Location.leading_detached_comments) +} +inline void SourceCodeInfo_Location::add_leading_detached_comments(const char* value) { + GOOGLE_DCHECK(value != nullptr); + leading_detached_comments_.Add()->assign(value); + // @@protoc_insertion_point(field_add_char:google.protobuf.SourceCodeInfo.Location.leading_detached_comments) +} +inline void SourceCodeInfo_Location::add_leading_detached_comments(const char* value, size_t size) { + leading_detached_comments_.Add()->assign(reinterpret_cast<const char*>(value), size); + // @@protoc_insertion_point(field_add_pointer:google.protobuf.SourceCodeInfo.Location.leading_detached_comments) +} +inline const ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField<TProtoStringType>& +SourceCodeInfo_Location::leading_detached_comments() const { + // @@protoc_insertion_point(field_list:google.protobuf.SourceCodeInfo.Location.leading_detached_comments) + return leading_detached_comments_; +} +inline ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField<TProtoStringType>* +SourceCodeInfo_Location::mutable_leading_detached_comments() { + // @@protoc_insertion_point(field_mutable_list:google.protobuf.SourceCodeInfo.Location.leading_detached_comments) + return &leading_detached_comments_; +} + +// ------------------------------------------------------------------- + +// SourceCodeInfo + +// repeated .google.protobuf.SourceCodeInfo.Location location = 1; +inline int SourceCodeInfo::_internal_location_size() const { + return location_.size(); +} +inline int SourceCodeInfo::location_size() const { + return _internal_location_size(); +} +inline void SourceCodeInfo::clear_location() { + location_.Clear(); +} +inline ::PROTOBUF_NAMESPACE_ID::SourceCodeInfo_Location* SourceCodeInfo::mutable_location(int index) { + // @@protoc_insertion_point(field_mutable:google.protobuf.SourceCodeInfo.location) + return location_.Mutable(index); +} +inline ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::SourceCodeInfo_Location >* +SourceCodeInfo::mutable_location() { + // @@protoc_insertion_point(field_mutable_list:google.protobuf.SourceCodeInfo.location) + return &location_; +} +inline const ::PROTOBUF_NAMESPACE_ID::SourceCodeInfo_Location& SourceCodeInfo::_internal_location(int index) const { + return location_.Get(index); +} +inline const ::PROTOBUF_NAMESPACE_ID::SourceCodeInfo_Location& SourceCodeInfo::location(int index) const { + // @@protoc_insertion_point(field_get:google.protobuf.SourceCodeInfo.location) + return _internal_location(index); +} +inline ::PROTOBUF_NAMESPACE_ID::SourceCodeInfo_Location* SourceCodeInfo::_internal_add_location() { + return location_.Add(); +} +inline ::PROTOBUF_NAMESPACE_ID::SourceCodeInfo_Location* SourceCodeInfo::add_location() { + ::PROTOBUF_NAMESPACE_ID::SourceCodeInfo_Location* _add = _internal_add_location(); + // @@protoc_insertion_point(field_add:google.protobuf.SourceCodeInfo.location) + return _add; +} +inline const ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::SourceCodeInfo_Location >& +SourceCodeInfo::location() const { + // @@protoc_insertion_point(field_list:google.protobuf.SourceCodeInfo.location) + return location_; +} + +// ------------------------------------------------------------------- + +// GeneratedCodeInfo_Annotation + +// repeated int32 path = 1 [packed = true]; +inline int GeneratedCodeInfo_Annotation::_internal_path_size() const { + return path_.size(); +} +inline int GeneratedCodeInfo_Annotation::path_size() const { + return _internal_path_size(); +} +inline void GeneratedCodeInfo_Annotation::clear_path() { + path_.Clear(); +} +inline arc_i32 GeneratedCodeInfo_Annotation::_internal_path(int index) const { + return path_.Get(index); +} +inline arc_i32 GeneratedCodeInfo_Annotation::path(int index) const { + // @@protoc_insertion_point(field_get:google.protobuf.GeneratedCodeInfo.Annotation.path) + return _internal_path(index); +} +inline void GeneratedCodeInfo_Annotation::set_path(int index, arc_i32 value) { + path_.Set(index, value); + // @@protoc_insertion_point(field_set:google.protobuf.GeneratedCodeInfo.Annotation.path) +} +inline void GeneratedCodeInfo_Annotation::_internal_add_path(arc_i32 value) { + path_.Add(value); +} +inline void GeneratedCodeInfo_Annotation::add_path(arc_i32 value) { + _internal_add_path(value); + // @@protoc_insertion_point(field_add:google.protobuf.GeneratedCodeInfo.Annotation.path) +} +inline const ::PROTOBUF_NAMESPACE_ID::RepeatedField< arc_i32 >& +GeneratedCodeInfo_Annotation::_internal_path() const { + return path_; +} +inline const ::PROTOBUF_NAMESPACE_ID::RepeatedField< arc_i32 >& +GeneratedCodeInfo_Annotation::path() const { + // @@protoc_insertion_point(field_list:google.protobuf.GeneratedCodeInfo.Annotation.path) + return _internal_path(); +} +inline ::PROTOBUF_NAMESPACE_ID::RepeatedField< arc_i32 >* +GeneratedCodeInfo_Annotation::_internal_mutable_path() { + return &path_; +} +inline ::PROTOBUF_NAMESPACE_ID::RepeatedField< arc_i32 >* +GeneratedCodeInfo_Annotation::mutable_path() { + // @@protoc_insertion_point(field_mutable_list:google.protobuf.GeneratedCodeInfo.Annotation.path) + return _internal_mutable_path(); +} + +// optional string source_file = 2; +inline bool GeneratedCodeInfo_Annotation::_internal_has_source_file() const { + bool value = (_has_bits_[0] & 0x00000001u) != 0; + return value; +} +inline bool GeneratedCodeInfo_Annotation::has_source_file() const { + return _internal_has_source_file(); +} +inline void GeneratedCodeInfo_Annotation::clear_source_file() { + source_file_.ClearToEmpty(); + _has_bits_[0] &= ~0x00000001u; +} +inline const TProtoStringType& GeneratedCodeInfo_Annotation::source_file() const { + // @@protoc_insertion_point(field_get:google.protobuf.GeneratedCodeInfo.Annotation.source_file) + return _internal_source_file(); +} +template <typename ArgT0, typename... ArgT> +inline PROTOBUF_ALWAYS_INLINE +void GeneratedCodeInfo_Annotation::set_source_file(ArgT0&& arg0, ArgT... args) { + _has_bits_[0] |= 0x00000001u; + source_file_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, static_cast<ArgT0 &&>(arg0), args..., GetArenaForAllocation()); + // @@protoc_insertion_point(field_set:google.protobuf.GeneratedCodeInfo.Annotation.source_file) +} +inline TProtoStringType* GeneratedCodeInfo_Annotation::mutable_source_file() { + TProtoStringType* _s = _internal_mutable_source_file(); + // @@protoc_insertion_point(field_mutable:google.protobuf.GeneratedCodeInfo.Annotation.source_file) + return _s; +} +inline const TProtoStringType& GeneratedCodeInfo_Annotation::_internal_source_file() const { + return source_file_.Get(); +} +inline void GeneratedCodeInfo_Annotation::_internal_set_source_file(const TProtoStringType& value) { + _has_bits_[0] |= 0x00000001u; + source_file_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, value, GetArenaForAllocation()); +} +inline TProtoStringType* GeneratedCodeInfo_Annotation::_internal_mutable_source_file() { + _has_bits_[0] |= 0x00000001u; + return source_file_.Mutable(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, GetArenaForAllocation()); +} +inline TProtoStringType* GeneratedCodeInfo_Annotation::release_source_file() { + // @@protoc_insertion_point(field_release:google.protobuf.GeneratedCodeInfo.Annotation.source_file) + if (!_internal_has_source_file()) { + return nullptr; + } + _has_bits_[0] &= ~0x00000001u; + auto* p = source_file_.ReleaseNonDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArenaForAllocation()); +#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING + if (source_file_.IsDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited())) { + source_file_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation()); + } +#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING + return p; +} +inline void GeneratedCodeInfo_Annotation::set_allocated_source_file(TProtoStringType* source_file) { + if (source_file != nullptr) { + _has_bits_[0] |= 0x00000001u; + } else { + _has_bits_[0] &= ~0x00000001u; + } + source_file_.SetAllocated(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), source_file, + GetArenaForAllocation()); +#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING + if (source_file_.IsDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited())) { + source_file_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation()); + } +#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING + // @@protoc_insertion_point(field_set_allocated:google.protobuf.GeneratedCodeInfo.Annotation.source_file) +} + +// optional int32 begin = 3; +inline bool GeneratedCodeInfo_Annotation::_internal_has_begin() const { + bool value = (_has_bits_[0] & 0x00000002u) != 0; + return value; +} +inline bool GeneratedCodeInfo_Annotation::has_begin() const { + return _internal_has_begin(); +} +inline void GeneratedCodeInfo_Annotation::clear_begin() { + begin_ = 0; + _has_bits_[0] &= ~0x00000002u; +} +inline arc_i32 GeneratedCodeInfo_Annotation::_internal_begin() const { + return begin_; +} +inline arc_i32 GeneratedCodeInfo_Annotation::begin() const { + // @@protoc_insertion_point(field_get:google.protobuf.GeneratedCodeInfo.Annotation.begin) + return _internal_begin(); +} +inline void GeneratedCodeInfo_Annotation::_internal_set_begin(arc_i32 value) { + _has_bits_[0] |= 0x00000002u; + begin_ = value; +} +inline void GeneratedCodeInfo_Annotation::set_begin(arc_i32 value) { + _internal_set_begin(value); + // @@protoc_insertion_point(field_set:google.protobuf.GeneratedCodeInfo.Annotation.begin) +} + +// optional int32 end = 4; +inline bool GeneratedCodeInfo_Annotation::_internal_has_end() const { + bool value = (_has_bits_[0] & 0x00000004u) != 0; + return value; +} +inline bool GeneratedCodeInfo_Annotation::has_end() const { + return _internal_has_end(); +} +inline void GeneratedCodeInfo_Annotation::clear_end() { + end_ = 0; + _has_bits_[0] &= ~0x00000004u; +} +inline arc_i32 GeneratedCodeInfo_Annotation::_internal_end() const { + return end_; +} +inline arc_i32 GeneratedCodeInfo_Annotation::end() const { + // @@protoc_insertion_point(field_get:google.protobuf.GeneratedCodeInfo.Annotation.end) + return _internal_end(); +} +inline void GeneratedCodeInfo_Annotation::_internal_set_end(arc_i32 value) { + _has_bits_[0] |= 0x00000004u; + end_ = value; +} +inline void GeneratedCodeInfo_Annotation::set_end(arc_i32 value) { + _internal_set_end(value); + // @@protoc_insertion_point(field_set:google.protobuf.GeneratedCodeInfo.Annotation.end) +} + +// ------------------------------------------------------------------- + +// GeneratedCodeInfo + +// repeated .google.protobuf.GeneratedCodeInfo.Annotation annotation = 1; +inline int GeneratedCodeInfo::_internal_annotation_size() const { + return annotation_.size(); +} +inline int GeneratedCodeInfo::annotation_size() const { + return _internal_annotation_size(); +} +inline void GeneratedCodeInfo::clear_annotation() { + annotation_.Clear(); +} +inline ::PROTOBUF_NAMESPACE_ID::GeneratedCodeInfo_Annotation* GeneratedCodeInfo::mutable_annotation(int index) { + // @@protoc_insertion_point(field_mutable:google.protobuf.GeneratedCodeInfo.annotation) + return annotation_.Mutable(index); +} +inline ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::GeneratedCodeInfo_Annotation >* +GeneratedCodeInfo::mutable_annotation() { + // @@protoc_insertion_point(field_mutable_list:google.protobuf.GeneratedCodeInfo.annotation) + return &annotation_; +} +inline const ::PROTOBUF_NAMESPACE_ID::GeneratedCodeInfo_Annotation& GeneratedCodeInfo::_internal_annotation(int index) const { + return annotation_.Get(index); +} +inline const ::PROTOBUF_NAMESPACE_ID::GeneratedCodeInfo_Annotation& GeneratedCodeInfo::annotation(int index) const { + // @@protoc_insertion_point(field_get:google.protobuf.GeneratedCodeInfo.annotation) + return _internal_annotation(index); +} +inline ::PROTOBUF_NAMESPACE_ID::GeneratedCodeInfo_Annotation* GeneratedCodeInfo::_internal_add_annotation() { + return annotation_.Add(); +} +inline ::PROTOBUF_NAMESPACE_ID::GeneratedCodeInfo_Annotation* GeneratedCodeInfo::add_annotation() { + ::PROTOBUF_NAMESPACE_ID::GeneratedCodeInfo_Annotation* _add = _internal_add_annotation(); + // @@protoc_insertion_point(field_add:google.protobuf.GeneratedCodeInfo.annotation) + return _add; +} +inline const ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::GeneratedCodeInfo_Annotation >& +GeneratedCodeInfo::annotation() const { + // @@protoc_insertion_point(field_list:google.protobuf.GeneratedCodeInfo.annotation) + return annotation_; +} + +#ifdef __GNUC__ + #pragma GCC diagnostic pop +#endif // __GNUC__ +// ------------------------------------------------------------------- + +// ------------------------------------------------------------------- + +// ------------------------------------------------------------------- + +// ------------------------------------------------------------------- + +// ------------------------------------------------------------------- + +// ------------------------------------------------------------------- + +// ------------------------------------------------------------------- + +// ------------------------------------------------------------------- + +// ------------------------------------------------------------------- + +// ------------------------------------------------------------------- + +// ------------------------------------------------------------------- + +// ------------------------------------------------------------------- + +// ------------------------------------------------------------------- + +// ------------------------------------------------------------------- + +// ------------------------------------------------------------------- + +// ------------------------------------------------------------------- + +// ------------------------------------------------------------------- + +// ------------------------------------------------------------------- + +// ------------------------------------------------------------------- + +// ------------------------------------------------------------------- + +// ------------------------------------------------------------------- + +// ------------------------------------------------------------------- + +// ------------------------------------------------------------------- + +// ------------------------------------------------------------------- + +// ------------------------------------------------------------------- + +// ------------------------------------------------------------------- + + +// @@protoc_insertion_point(namespace_scope) + +PROTOBUF_NAMESPACE_CLOSE + +PROTOBUF_NAMESPACE_OPEN + +template <> struct is_proto_enum< ::PROTOBUF_NAMESPACE_ID::FieldDescriptorProto_Type> : ::std::true_type {}; +template <> +inline const EnumDescriptor* GetEnumDescriptor< ::PROTOBUF_NAMESPACE_ID::FieldDescriptorProto_Type>() { + return ::PROTOBUF_NAMESPACE_ID::FieldDescriptorProto_Type_descriptor(); +} +template <> struct is_proto_enum< ::PROTOBUF_NAMESPACE_ID::FieldDescriptorProto_Label> : ::std::true_type {}; +template <> +inline const EnumDescriptor* GetEnumDescriptor< ::PROTOBUF_NAMESPACE_ID::FieldDescriptorProto_Label>() { + return ::PROTOBUF_NAMESPACE_ID::FieldDescriptorProto_Label_descriptor(); +} +template <> struct is_proto_enum< ::PROTOBUF_NAMESPACE_ID::FileOptions_OptimizeMode> : ::std::true_type {}; +template <> +inline const EnumDescriptor* GetEnumDescriptor< ::PROTOBUF_NAMESPACE_ID::FileOptions_OptimizeMode>() { + return ::PROTOBUF_NAMESPACE_ID::FileOptions_OptimizeMode_descriptor(); +} +template <> struct is_proto_enum< ::PROTOBUF_NAMESPACE_ID::FieldOptions_CType> : ::std::true_type {}; +template <> +inline const EnumDescriptor* GetEnumDescriptor< ::PROTOBUF_NAMESPACE_ID::FieldOptions_CType>() { + return ::PROTOBUF_NAMESPACE_ID::FieldOptions_CType_descriptor(); +} +template <> struct is_proto_enum< ::PROTOBUF_NAMESPACE_ID::FieldOptions_JSType> : ::std::true_type {}; +template <> +inline const EnumDescriptor* GetEnumDescriptor< ::PROTOBUF_NAMESPACE_ID::FieldOptions_JSType>() { + return ::PROTOBUF_NAMESPACE_ID::FieldOptions_JSType_descriptor(); +} +template <> struct is_proto_enum< ::PROTOBUF_NAMESPACE_ID::MethodOptions_IdempotencyLevel> : ::std::true_type {}; +template <> +inline const EnumDescriptor* GetEnumDescriptor< ::PROTOBUF_NAMESPACE_ID::MethodOptions_IdempotencyLevel>() { + return ::PROTOBUF_NAMESPACE_ID::MethodOptions_IdempotencyLevel_descriptor(); +} + +PROTOBUF_NAMESPACE_CLOSE + +// @@protoc_insertion_point(global_scope) + +#include <google/protobuf/port_undef.inc> +#endif // GOOGLE_PROTOBUF_INCLUDED_GOOGLE_PROTOBUF_INCLUDED_google_2fprotobuf_2fdescriptor_2eproto diff --git a/contrib/libs/protobuf_old/src/google/protobuf/descriptor.proto b/contrib/libs/protobuf_old/src/google/protobuf/descriptor.proto new file mode 100644 index 0000000000..156e410ae1 --- /dev/null +++ b/contrib/libs/protobuf_old/src/google/protobuf/descriptor.proto @@ -0,0 +1,911 @@ +// 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: kenton@google.com (Kenton Varda) +// Based on original Protocol Buffers design by +// Sanjay Ghemawat, Jeff Dean, and others. +// +// The messages in this file describe the definitions found in .proto files. +// A valid .proto file can be translated directly to a FileDescriptorProto +// without any other information (e.g. without reading its imports). + + +syntax = "proto2"; + +package google.protobuf; + +option go_package = "google.golang.org/protobuf/types/descriptorpb"; +option java_package = "com.google.protobuf"; +option java_outer_classname = "DescriptorProtos"; +option csharp_namespace = "Google.Protobuf.Reflection"; +option objc_class_prefix = "GPB"; +option cc_enable_arenas = true; + +// descriptor.proto must be optimized for speed because reflection-based +// algorithms don't work during bootstrapping. +option optimize_for = SPEED; + +// The protocol compiler can output a FileDescriptorSet containing the .proto +// files it parses. +message FileDescriptorSet { + repeated FileDescriptorProto file = 1; +} + +// Describes a complete .proto file. +message FileDescriptorProto { + optional string name = 1; // file name, relative to root of source tree + optional string package = 2; // e.g. "foo", "foo.bar", etc. + + // Names of files imported by this file. + repeated string dependency = 3; + // Indexes of the public imported files in the dependency list above. + repeated int32 public_dependency = 10; + // Indexes of the weak imported files in the dependency list. + // For Google-internal migration only. Do not use. + repeated int32 weak_dependency = 11; + + // All top-level definitions in this file. + repeated DescriptorProto message_type = 4; + repeated EnumDescriptorProto enum_type = 5; + repeated ServiceDescriptorProto service = 6; + repeated FieldDescriptorProto extension = 7; + + optional FileOptions options = 8; + + // This field contains optional information about the original source code. + // You may safely remove this entire field without harming runtime + // functionality of the descriptors -- the information is needed only by + // development tools. + optional SourceCodeInfo source_code_info = 9; + + // The syntax of the proto file. + // The supported values are "proto2" and "proto3". + optional string syntax = 12; +} + +// Describes a message type. +message DescriptorProto { + optional string name = 1; + + repeated FieldDescriptorProto field = 2; + repeated FieldDescriptorProto extension = 6; + + repeated DescriptorProto nested_type = 3; + repeated EnumDescriptorProto enum_type = 4; + + message ExtensionRange { + optional int32 start = 1; // Inclusive. + optional int32 end = 2; // Exclusive. + + optional ExtensionRangeOptions options = 3; + } + repeated ExtensionRange extension_range = 5; + + repeated OneofDescriptorProto oneof_decl = 8; + + optional MessageOptions options = 7; + + // Range of reserved tag numbers. Reserved tag numbers may not be used by + // fields or extension ranges in the same message. Reserved ranges may + // not overlap. + message ReservedRange { + optional int32 start = 1; // Inclusive. + optional int32 end = 2; // Exclusive. + } + repeated ReservedRange reserved_range = 9; + // Reserved field names, which may not be used by fields in the same message. + // A given name may only be reserved once. + repeated string reserved_name = 10; +} + +message ExtensionRangeOptions { + // The parser stores options it doesn't recognize here. See above. + repeated UninterpretedOption uninterpreted_option = 999; + + + // Clients can define custom options in extensions of this message. See above. + extensions 1000 to max; +} + +// Describes a field within a message. +message FieldDescriptorProto { + enum Type { + // 0 is reserved for errors. + // Order is weird for historical reasons. + TYPE_DOUBLE = 1; + TYPE_FLOAT = 2; + // Not ZigZag encoded. Negative numbers take 10 bytes. Use TYPE_SINT64 if + // negative values are likely. + TYPE_INT64 = 3; + TYPE_UINT64 = 4; + // Not ZigZag encoded. Negative numbers take 10 bytes. Use TYPE_SINT32 if + // negative values are likely. + TYPE_INT32 = 5; + TYPE_FIXED64 = 6; + TYPE_FIXED32 = 7; + TYPE_BOOL = 8; + TYPE_STRING = 9; + // Tag-delimited aggregate. + // Group type is deprecated and not supported in proto3. However, Proto3 + // implementations should still be able to parse the group wire format and + // treat group fields as unknown fields. + TYPE_GROUP = 10; + TYPE_MESSAGE = 11; // Length-delimited aggregate. + + // New in version 2. + TYPE_BYTES = 12; + TYPE_UINT32 = 13; + TYPE_ENUM = 14; + TYPE_SFIXED32 = 15; + TYPE_SFIXED64 = 16; + TYPE_SINT32 = 17; // Uses ZigZag encoding. + TYPE_SINT64 = 18; // Uses ZigZag encoding. + } + + enum Label { + // 0 is reserved for errors + LABEL_OPTIONAL = 1; + LABEL_REQUIRED = 2; + LABEL_REPEATED = 3; + } + + optional string name = 1; + optional int32 number = 3; + optional Label label = 4; + + // If type_name is set, this need not be set. If both this and type_name + // are set, this must be one of TYPE_ENUM, TYPE_MESSAGE or TYPE_GROUP. + optional Type type = 5; + + // For message and enum types, this is the name of the type. If the name + // starts with a '.', it is fully-qualified. Otherwise, C++-like scoping + // rules are used to find the type (i.e. first the nested types within this + // message are searched, then within the parent, on up to the root + // namespace). + optional string type_name = 6; + + // For extensions, this is the name of the type being extended. It is + // resolved in the same manner as type_name. + optional string extendee = 2; + + // For numeric types, contains the original text representation of the value. + // For booleans, "true" or "false". + // For strings, contains the default text contents (not escaped in any way). + // For bytes, contains the C escaped value. All bytes >= 128 are escaped. + // TODO(kenton): Base-64 encode? + optional string default_value = 7; + + // If set, gives the index of a oneof in the containing type's oneof_decl + // list. This field is a member of that oneof. + optional int32 oneof_index = 9; + + // JSON name of this field. The value is set by protocol compiler. If the + // user has set a "json_name" option on this field, that option's value + // will be used. Otherwise, it's deduced from the field's name by converting + // it to camelCase. + optional string json_name = 10; + + optional FieldOptions options = 8; + + // If true, this is a proto3 "optional". When a proto3 field is optional, it + // tracks presence regardless of field type. + // + // When proto3_optional is true, this field must be belong to a oneof to + // signal to old proto3 clients that presence is tracked for this field. This + // oneof is known as a "synthetic" oneof, and this field must be its sole + // member (each proto3 optional field gets its own synthetic oneof). Synthetic + // oneofs exist in the descriptor only, and do not generate any API. Synthetic + // oneofs must be ordered after all "real" oneofs. + // + // For message fields, proto3_optional doesn't create any semantic change, + // since non-repeated message fields always track presence. However it still + // indicates the semantic detail of whether the user wrote "optional" or not. + // This can be useful for round-tripping the .proto file. For consistency we + // give message fields a synthetic oneof also, even though it is not required + // to track presence. This is especially important because the parser can't + // tell if a field is a message or an enum, so it must always create a + // synthetic oneof. + // + // Proto2 optional fields do not set this flag, because they already indicate + // optional with `LABEL_OPTIONAL`. + optional bool proto3_optional = 17; +} + +// Describes a oneof. +message OneofDescriptorProto { + optional string name = 1; + optional OneofOptions options = 2; +} + +// Describes an enum type. +message EnumDescriptorProto { + optional string name = 1; + + repeated EnumValueDescriptorProto value = 2; + + optional EnumOptions options = 3; + + // Range of reserved numeric values. Reserved values may not be used by + // entries in the same enum. Reserved ranges may not overlap. + // + // Note that this is distinct from DescriptorProto.ReservedRange in that it + // is inclusive such that it can appropriately represent the entire int32 + // domain. + message EnumReservedRange { + optional int32 start = 1; // Inclusive. + optional int32 end = 2; // Inclusive. + } + + // Range of reserved numeric values. Reserved numeric values may not be used + // by enum values in the same enum declaration. Reserved ranges may not + // overlap. + repeated EnumReservedRange reserved_range = 4; + + // Reserved enum value names, which may not be reused. A given name may only + // be reserved once. + repeated string reserved_name = 5; +} + +// Describes a value within an enum. +message EnumValueDescriptorProto { + optional string name = 1; + optional int32 number = 2; + + optional EnumValueOptions options = 3; +} + +// Describes a service. +message ServiceDescriptorProto { + optional string name = 1; + repeated MethodDescriptorProto method = 2; + + optional ServiceOptions options = 3; +} + +// Describes a method of a service. +message MethodDescriptorProto { + optional string name = 1; + + // Input and output type names. These are resolved in the same way as + // FieldDescriptorProto.type_name, but must refer to a message type. + optional string input_type = 2; + optional string output_type = 3; + + optional MethodOptions options = 4; + + // Identifies if client streams multiple client messages + optional bool client_streaming = 5 [default = false]; + // Identifies if server streams multiple server messages + optional bool server_streaming = 6 [default = false]; +} + + +// =================================================================== +// Options + +// Each of the definitions above may have "options" attached. These are +// just annotations which may cause code to be generated slightly differently +// or may contain hints for code that manipulates protocol messages. +// +// Clients may define custom options as extensions of the *Options messages. +// These extensions may not yet be known at parsing time, so the parser cannot +// store the values in them. Instead it stores them in a field in the *Options +// message called uninterpreted_option. This field must have the same name +// across all *Options messages. We then use this field to populate the +// extensions when we build a descriptor, at which point all protos have been +// parsed and so all extensions are known. +// +// Extension numbers for custom options may be chosen as follows: +// * For options which will only be used within a single application or +// organization, or for experimental options, use field numbers 50000 +// through 99999. It is up to you to ensure that you do not use the +// same number for multiple options. +// * For options which will be published and used publicly by multiple +// independent entities, e-mail protobuf-global-extension-registry@google.com +// to reserve extension numbers. Simply provide your project name (e.g. +// Objective-C plugin) and your project website (if available) -- there's no +// need to explain how you intend to use them. Usually you only need one +// extension number. You can declare multiple options with only one extension +// number by putting them in a sub-message. See the Custom Options section of +// the docs for examples: +// https://developers.google.com/protocol-buffers/docs/proto#options +// If this turns out to be popular, a web service will be set up +// to automatically assign option numbers. + +message FileOptions { + + // Sets the Java package where classes generated from this .proto will be + // placed. By default, the proto package is used, but this is often + // inappropriate because proto packages do not normally start with backwards + // domain names. + optional string java_package = 1; + + + // Controls the name of the wrapper Java class generated for the .proto file. + // That class will always contain the .proto file's getDescriptor() method as + // well as any top-level extensions defined in the .proto file. + // If java_multiple_files is disabled, then all the other classes from the + // .proto file will be nested inside the single wrapper outer class. + optional string java_outer_classname = 8; + + // If enabled, then the Java code generator will generate a separate .java + // file for each top-level message, enum, and service defined in the .proto + // file. Thus, these types will *not* be nested inside the wrapper class + // named by java_outer_classname. However, the wrapper class will still be + // generated to contain the file's getDescriptor() method as well as any + // top-level extensions defined in the file. + optional bool java_multiple_files = 10 [default = false]; + + // This option does nothing. + optional bool java_generate_equals_and_hash = 20 [deprecated=true]; + + // If set true, then the Java2 code generator will generate code that + // throws an exception whenever an attempt is made to assign a non-UTF-8 + // byte sequence to a string field. + // Message reflection will do the same. + // However, an extension field still accepts non-UTF-8 byte sequences. + // This option has no effect on when used with the lite runtime. + optional bool java_string_check_utf8 = 27 [default = false]; + + + // Generated classes can be optimized for speed or code size. + enum OptimizeMode { + SPEED = 1; // Generate complete code for parsing, serialization, + // etc. + CODE_SIZE = 2; // Use ReflectionOps to implement these methods. + LITE_RUNTIME = 3; // Generate code using MessageLite and the lite runtime. + } + optional OptimizeMode optimize_for = 9 [default = SPEED]; + + // Sets the Go package where structs generated from this .proto will be + // placed. If omitted, the Go package will be derived from the following: + // - The basename of the package import path, if provided. + // - Otherwise, the package statement in the .proto file, if present. + // - Otherwise, the basename of the .proto file, without extension. + optional string go_package = 11; + + + + + // Should generic services be generated in each language? "Generic" services + // are not specific to any particular RPC system. They are generated by the + // main code generators in each language (without additional plugins). + // Generic services were the only kind of service generation supported by + // early versions of google.protobuf. + // + // Generic services are now considered deprecated in favor of using plugins + // that generate code specific to your particular RPC system. Therefore, + // these default to false. Old code which depends on generic services should + // explicitly set them to true. + optional bool cc_generic_services = 16 [default = false]; + optional bool java_generic_services = 17 [default = false]; + optional bool py_generic_services = 18 [default = false]; + optional bool php_generic_services = 42 [default = false]; + + // Is this file deprecated? + // Depending on the target platform, this can emit Deprecated annotations + // for everything in the file, or it will be completely ignored; in the very + // least, this is a formalization for deprecating files. + optional bool deprecated = 23 [default = false]; + + // Enables the use of arenas for the proto messages in this file. This applies + // only to generated classes for C++. + optional bool cc_enable_arenas = 31 [default = true]; + + + // Sets the objective c class prefix which is prepended to all objective c + // generated classes from this .proto. There is no default. + optional string objc_class_prefix = 36; + + // Namespace for generated classes; defaults to the package. + optional string csharp_namespace = 37; + + // By default Swift generators will take the proto package and CamelCase it + // replacing '.' with underscore and use that to prefix the types/symbols + // defined. When this options is provided, they will use this value instead + // to prefix the types/symbols defined. + optional string swift_prefix = 39; + + // Sets the php class prefix which is prepended to all php generated classes + // from this .proto. Default is empty. + optional string php_class_prefix = 40; + + // Use this option to change the namespace of php generated classes. Default + // is empty. When this option is empty, the package name will be used for + // determining the namespace. + optional string php_namespace = 41; + + // Use this option to change the namespace of php generated metadata classes. + // Default is empty. When this option is empty, the proto file name will be + // used for determining the namespace. + optional string php_metadata_namespace = 44; + + // Use this option to change the package of ruby generated classes. Default + // is empty. When this option is not set, the package name will be used for + // determining the ruby package. + optional string ruby_package = 45; + + + // The parser stores options it doesn't recognize here. + // See the documentation for the "Options" section above. + repeated UninterpretedOption uninterpreted_option = 999; + + // Clients can define custom options in extensions of this message. + // See the documentation for the "Options" section above. + extensions 1000 to max; + + reserved 38; +} + +message MessageOptions { + // Set true to use the old proto1 MessageSet wire format for extensions. + // This is provided for backwards-compatibility with the MessageSet wire + // format. You should not use this for any other reason: It's less + // efficient, has fewer features, and is more complicated. + // + // The message must be defined exactly as follows: + // message Foo { + // option message_set_wire_format = true; + // extensions 4 to max; + // } + // Note that the message cannot have any defined fields; MessageSets only + // have extensions. + // + // All extensions of your type must be singular messages; e.g. they cannot + // be int32s, enums, or repeated messages. + // + // Because this is an option, the above two restrictions are not enforced by + // the protocol compiler. + optional bool message_set_wire_format = 1 [default = false]; + + // Disables the generation of the standard "descriptor()" accessor, which can + // conflict with a field of the same name. This is meant to make migration + // from proto1 easier; new code should avoid fields named "descriptor". + optional bool no_standard_descriptor_accessor = 2 [default = false]; + + // Is this message deprecated? + // Depending on the target platform, this can emit Deprecated annotations + // for the message, or it will be completely ignored; in the very least, + // this is a formalization for deprecating messages. + optional bool deprecated = 3 [default = false]; + + reserved 4, 5, 6; + + // Whether the message is an automatically generated map entry type for the + // maps field. + // + // For maps fields: + // map<KeyType, ValueType> map_field = 1; + // The parsed descriptor looks like: + // message MapFieldEntry { + // option map_entry = true; + // optional KeyType key = 1; + // optional ValueType value = 2; + // } + // repeated MapFieldEntry map_field = 1; + // + // Implementations may choose not to generate the map_entry=true message, but + // use a native map in the target language to hold the keys and values. + // The reflection APIs in such implementations still need to work as + // if the field is a repeated message field. + // + // NOTE: Do not set the option in .proto files. Always use the maps syntax + // instead. The option should only be implicitly set by the proto compiler + // parser. + optional bool map_entry = 7; + + reserved 8; // javalite_serializable + reserved 9; // javanano_as_lite + + + // The parser stores options it doesn't recognize here. See above. + repeated UninterpretedOption uninterpreted_option = 999; + + // Clients can define custom options in extensions of this message. See above. + extensions 1000 to max; +} + +message FieldOptions { + // The ctype option instructs the C++ code generator to use a different + // representation of the field than it normally would. See the specific + // options below. This option is not yet implemented in the open source + // release -- sorry, we'll try to include it in a future version! + optional CType ctype = 1 [default = STRING]; + enum CType { + // Default mode. + STRING = 0; + + CORD = 1; + + STRING_PIECE = 2; + } + // The packed option can be enabled for repeated primitive fields to enable + // a more efficient representation on the wire. Rather than repeatedly + // writing the tag and type for each element, the entire array is encoded as + // a single length-delimited blob. In proto3, only explicit setting it to + // false will avoid using packed encoding. + optional bool packed = 2; + + // The jstype option determines the JavaScript type used for values of the + // field. The option is permitted only for 64 bit integral and fixed types + // (int64, uint64, sint64, fixed64, sfixed64). A field with jstype JS_STRING + // is represented as JavaScript string, which avoids loss of precision that + // can happen when a large value is converted to a floating point JavaScript. + // Specifying JS_NUMBER for the jstype causes the generated JavaScript code to + // use the JavaScript "number" type. The behavior of the default option + // JS_NORMAL is implementation dependent. + // + // This option is an enum to permit additional types to be added, e.g. + // goog.math.Integer. + optional JSType jstype = 6 [default = JS_NORMAL]; + enum JSType { + // Use the default type. + JS_NORMAL = 0; + + // Use JavaScript strings. + JS_STRING = 1; + + // Use JavaScript numbers. + JS_NUMBER = 2; + } + + // Should this field be parsed lazily? Lazy applies only to message-type + // fields. It means that when the outer message is initially parsed, the + // inner message's contents will not be parsed but instead stored in encoded + // form. The inner message will actually be parsed when it is first accessed. + // + // This is only a hint. Implementations are free to choose whether to use + // eager or lazy parsing regardless of the value of this option. However, + // setting this option true suggests that the protocol author believes that + // using lazy parsing on this field is worth the additional bookkeeping + // overhead typically needed to implement it. + // + // This option does not affect the public interface of any generated code; + // all method signatures remain the same. Furthermore, thread-safety of the + // interface is not affected by this option; const methods remain safe to + // call from multiple threads concurrently, while non-const methods continue + // to require exclusive access. + // + // + // Note that implementations may choose not to check required fields within + // a lazy sub-message. That is, calling IsInitialized() on the outer message + // may return true even if the inner message has missing required fields. + // This is necessary because otherwise the inner message would have to be + // parsed in order to perform the check, defeating the purpose of lazy + // parsing. An implementation which chooses not to check required fields + // must be consistent about it. That is, for any particular sub-message, the + // implementation must either *always* check its required fields, or *never* + // check its required fields, regardless of whether or not the message has + // been parsed. + optional bool lazy = 5 [default = false]; + + // Is this field deprecated? + // Depending on the target platform, this can emit Deprecated annotations + // for accessors, or it will be completely ignored; in the very least, this + // is a formalization for deprecating fields. + optional bool deprecated = 3 [default = false]; + + // For Google-internal migration only. Do not use. + optional bool weak = 10 [default = false]; + + + // The parser stores options it doesn't recognize here. See above. + repeated UninterpretedOption uninterpreted_option = 999; + + // Clients can define custom options in extensions of this message. See above. + extensions 1000 to max; + + reserved 4; // removed jtype +} + +message OneofOptions { + // The parser stores options it doesn't recognize here. See above. + repeated UninterpretedOption uninterpreted_option = 999; + + // Clients can define custom options in extensions of this message. See above. + extensions 1000 to max; +} + +message EnumOptions { + + // Set this option to true to allow mapping different tag names to the same + // value. + optional bool allow_alias = 2; + + // Is this enum deprecated? + // Depending on the target platform, this can emit Deprecated annotations + // for the enum, or it will be completely ignored; in the very least, this + // is a formalization for deprecating enums. + optional bool deprecated = 3 [default = false]; + + reserved 5; // javanano_as_lite + + // The parser stores options it doesn't recognize here. See above. + repeated UninterpretedOption uninterpreted_option = 999; + + // Clients can define custom options in extensions of this message. See above. + extensions 1000 to max; +} + +message EnumValueOptions { + // Is this enum value deprecated? + // Depending on the target platform, this can emit Deprecated annotations + // for the enum value, or it will be completely ignored; in the very least, + // this is a formalization for deprecating enum values. + optional bool deprecated = 1 [default = false]; + + // The parser stores options it doesn't recognize here. See above. + repeated UninterpretedOption uninterpreted_option = 999; + + // Clients can define custom options in extensions of this message. See above. + extensions 1000 to max; +} + +message ServiceOptions { + + // Note: Field numbers 1 through 32 are reserved for Google's internal RPC + // framework. We apologize for hoarding these numbers to ourselves, but + // we were already using them long before we decided to release Protocol + // Buffers. + + // Is this service deprecated? + // Depending on the target platform, this can emit Deprecated annotations + // for the service, or it will be completely ignored; in the very least, + // this is a formalization for deprecating services. + optional bool deprecated = 33 [default = false]; + + // The parser stores options it doesn't recognize here. See above. + repeated UninterpretedOption uninterpreted_option = 999; + + // Clients can define custom options in extensions of this message. See above. + extensions 1000 to max; +} + +message MethodOptions { + + // Note: Field numbers 1 through 32 are reserved for Google's internal RPC + // framework. We apologize for hoarding these numbers to ourselves, but + // we were already using them long before we decided to release Protocol + // Buffers. + + // Is this method deprecated? + // Depending on the target platform, this can emit Deprecated annotations + // for the method, or it will be completely ignored; in the very least, + // this is a formalization for deprecating methods. + optional bool deprecated = 33 [default = false]; + + // Is this method side-effect-free (or safe in HTTP parlance), or idempotent, + // or neither? HTTP based RPC implementation may choose GET verb for safe + // methods, and PUT verb for idempotent methods instead of the default POST. + enum IdempotencyLevel { + IDEMPOTENCY_UNKNOWN = 0; + NO_SIDE_EFFECTS = 1; // implies idempotent + IDEMPOTENT = 2; // idempotent, but may have side effects + } + optional IdempotencyLevel idempotency_level = 34 + [default = IDEMPOTENCY_UNKNOWN]; + + // The parser stores options it doesn't recognize here. See above. + repeated UninterpretedOption uninterpreted_option = 999; + + // Clients can define custom options in extensions of this message. See above. + extensions 1000 to max; +} + + +// A message representing a option the parser does not recognize. This only +// appears in options protos created by the compiler::Parser class. +// DescriptorPool resolves these when building Descriptor objects. Therefore, +// options protos in descriptor objects (e.g. returned by Descriptor::options(), +// or produced by Descriptor::CopyTo()) will never have UninterpretedOptions +// in them. +message UninterpretedOption { + // The name of the uninterpreted option. Each string represents a segment in + // a dot-separated name. is_extension is true iff a segment represents an + // extension (denoted with parentheses in options specs in .proto files). + // E.g.,{ ["foo", false], ["bar.baz", true], ["qux", false] } represents + // "foo.(bar.baz).qux". + message NamePart { + required string name_part = 1; + required bool is_extension = 2; + } + repeated NamePart name = 2; + + // The value of the uninterpreted option, in whatever type the tokenizer + // identified it as during parsing. Exactly one of these should be set. + optional string identifier_value = 3; + optional uint64 positive_int_value = 4; + optional int64 negative_int_value = 5; + optional double double_value = 6; + optional bytes string_value = 7; + optional string aggregate_value = 8; +} + +// =================================================================== +// Optional source code info + +// Encapsulates information about the original source file from which a +// FileDescriptorProto was generated. +message SourceCodeInfo { + // A Location identifies a piece of source code in a .proto file which + // corresponds to a particular definition. This information is intended + // to be useful to IDEs, code indexers, documentation generators, and similar + // tools. + // + // For example, say we have a file like: + // message Foo { + // optional string foo = 1; + // } + // Let's look at just the field definition: + // optional string foo = 1; + // ^ ^^ ^^ ^ ^^^ + // a bc de f ghi + // We have the following locations: + // span path represents + // [a,i) [ 4, 0, 2, 0 ] The whole field definition. + // [a,b) [ 4, 0, 2, 0, 4 ] The label (optional). + // [c,d) [ 4, 0, 2, 0, 5 ] The type (string). + // [e,f) [ 4, 0, 2, 0, 1 ] The name (foo). + // [g,h) [ 4, 0, 2, 0, 3 ] The number (1). + // + // Notes: + // - A location may refer to a repeated field itself (i.e. not to any + // particular index within it). This is used whenever a set of elements are + // logically enclosed in a single code segment. For example, an entire + // extend block (possibly containing multiple extension definitions) will + // have an outer location whose path refers to the "extensions" repeated + // field without an index. + // - Multiple locations may have the same path. This happens when a single + // logical declaration is spread out across multiple places. The most + // obvious example is the "extend" block again -- there may be multiple + // extend blocks in the same scope, each of which will have the same path. + // - A location's span is not always a subset of its parent's span. For + // example, the "extendee" of an extension declaration appears at the + // beginning of the "extend" block and is shared by all extensions within + // the block. + // - Just because a location's span is a subset of some other location's span + // does not mean that it is a descendant. For example, a "group" defines + // both a type and a field in a single declaration. Thus, the locations + // corresponding to the type and field and their components will overlap. + // - Code which tries to interpret locations should probably be designed to + // ignore those that it doesn't understand, as more types of locations could + // be recorded in the future. + repeated Location location = 1; + message Location { + // Identifies which part of the FileDescriptorProto was defined at this + // location. + // + // Each element is a field number or an index. They form a path from + // the root FileDescriptorProto to the place where the definition. For + // example, this path: + // [ 4, 3, 2, 7, 1 ] + // refers to: + // file.message_type(3) // 4, 3 + // .field(7) // 2, 7 + // .name() // 1 + // This is because FileDescriptorProto.message_type has field number 4: + // repeated DescriptorProto message_type = 4; + // and DescriptorProto.field has field number 2: + // repeated FieldDescriptorProto field = 2; + // and FieldDescriptorProto.name has field number 1: + // optional string name = 1; + // + // Thus, the above path gives the location of a field name. If we removed + // the last element: + // [ 4, 3, 2, 7 ] + // this path refers to the whole field declaration (from the beginning + // of the label to the terminating semicolon). + repeated int32 path = 1 [packed = true]; + + // Always has exactly three or four elements: start line, start column, + // end line (optional, otherwise assumed same as start line), end column. + // These are packed into a single field for efficiency. Note that line + // and column numbers are zero-based -- typically you will want to add + // 1 to each before displaying to a user. + repeated int32 span = 2 [packed = true]; + + // If this SourceCodeInfo represents a complete declaration, these are any + // comments appearing before and after the declaration which appear to be + // attached to the declaration. + // + // A series of line comments appearing on consecutive lines, with no other + // tokens appearing on those lines, will be treated as a single comment. + // + // leading_detached_comments will keep paragraphs of comments that appear + // before (but not connected to) the current element. Each paragraph, + // separated by empty lines, will be one comment element in the repeated + // field. + // + // Only the comment content is provided; comment markers (e.g. //) are + // stripped out. For block comments, leading whitespace and an asterisk + // will be stripped from the beginning of each line other than the first. + // Newlines are included in the output. + // + // Examples: + // + // optional int32 foo = 1; // Comment attached to foo. + // // Comment attached to bar. + // optional int32 bar = 2; + // + // optional string baz = 3; + // // Comment attached to baz. + // // Another line attached to baz. + // + // // Comment attached to qux. + // // + // // Another line attached to qux. + // optional double qux = 4; + // + // // Detached comment for corge. This is not leading or trailing comments + // // to qux or corge because there are blank lines separating it from + // // both. + // + // // Detached comment for corge paragraph 2. + // + // optional string corge = 5; + // /* Block comment attached + // * to corge. Leading asterisks + // * will be removed. */ + // /* Block comment attached to + // * grault. */ + // optional int32 grault = 6; + // + // // ignored detached comments. + optional string leading_comments = 3; + optional string trailing_comments = 4; + repeated string leading_detached_comments = 6; + } +} + +// Describes the relationship between generated code and its original source +// file. A GeneratedCodeInfo message is associated with only one generated +// source file, but may contain references to different source .proto files. +message GeneratedCodeInfo { + // An Annotation connects some span of text in generated code to an element + // of its generating .proto file. + repeated Annotation annotation = 1; + message Annotation { + // Identifies the element in the original source .proto file. This field + // is formatted the same as SourceCodeInfo.Location.path. + repeated int32 path = 1 [packed = true]; + + // Identifies the filesystem path to the original source .proto. + optional string source_file = 2; + + // Identifies the starting offset in bytes in the generated code + // that relates to the identified object. + optional int32 begin = 3; + + // Identifies the ending offset in bytes in the generated code that + // relates to the identified offset. The end offset should be one past + // the last relevant byte (so the length of the text = end - begin). + optional int32 end = 4; + } +} diff --git a/contrib/libs/protobuf_old/src/google/protobuf/descriptor_database.cc b/contrib/libs/protobuf_old/src/google/protobuf/descriptor_database.cc new file mode 100644 index 0000000000..4b05990240 --- /dev/null +++ b/contrib/libs/protobuf_old/src/google/protobuf/descriptor_database.cc @@ -0,0 +1,1031 @@ +// 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: kenton@google.com (Kenton Varda) +// Based on original Protocol Buffers design by +// Sanjay Ghemawat, Jeff Dean, and others. + +#include <google/protobuf/descriptor_database.h> + +#include <set> + +#include <google/protobuf/descriptor.pb.h> +#include <google/protobuf/stubs/map_util.h> +#include <google/protobuf/stubs/stl_util.h> + + +namespace google { +namespace protobuf { + +namespace { +void RecordMessageNames(const DescriptorProto& desc_proto, + const TProtoStringType& prefix, + std::set<TProtoStringType>* output) { + GOOGLE_CHECK(desc_proto.has_name()); + TProtoStringType full_name = prefix.empty() + ? desc_proto.name() + : StrCat(prefix, ".", desc_proto.name()); + output->insert(full_name); + + for (const auto& d : desc_proto.nested_type()) { + RecordMessageNames(d, full_name, output); + } +} + +void RecordMessageNames(const FileDescriptorProto& file_proto, + std::set<TProtoStringType>* output) { + for (const auto& d : file_proto.message_type()) { + RecordMessageNames(d, file_proto.package(), output); + } +} + +template <typename Fn> +bool ForAllFileProtos(DescriptorDatabase* db, Fn callback, + std::vector<TProtoStringType>* output) { + std::vector<TProtoStringType> file_names; + if (!db->FindAllFileNames(&file_names)) { + return false; + } + std::set<TProtoStringType> set; + FileDescriptorProto file_proto; + for (const auto& f : file_names) { + file_proto.Clear(); + if (!db->FindFileByName(f, &file_proto)) { + GOOGLE_LOG(ERROR) << "File not found in database (unexpected): " << f; + return false; + } + callback(file_proto, &set); + } + output->insert(output->end(), set.begin(), set.end()); + return true; +} +} // namespace + +DescriptorDatabase::~DescriptorDatabase() {} + +bool DescriptorDatabase::FindAllPackageNames(std::vector<TProtoStringType>* output) { + return ForAllFileProtos( + this, + [](const FileDescriptorProto& file_proto, std::set<TProtoStringType>* set) { + set->insert(file_proto.package()); + }, + output); +} + +bool DescriptorDatabase::FindAllMessageNames(std::vector<TProtoStringType>* output) { + return ForAllFileProtos( + this, + [](const FileDescriptorProto& file_proto, std::set<TProtoStringType>* set) { + RecordMessageNames(file_proto, set); + }, + output); +} + +// =================================================================== + +SimpleDescriptorDatabase::SimpleDescriptorDatabase() {} +SimpleDescriptorDatabase::~SimpleDescriptorDatabase() {} + +template <typename Value> +bool SimpleDescriptorDatabase::DescriptorIndex<Value>::AddFile( + const FileDescriptorProto& file, Value value) { + if (!InsertIfNotPresent(&by_name_, file.name(), value)) { + GOOGLE_LOG(ERROR) << "File already exists in database: " << file.name(); + return false; + } + + // We must be careful here -- calling file.package() if file.has_package() is + // false could access an uninitialized static-storage variable if we are being + // run at startup time. + TProtoStringType path = file.has_package() ? file.package() : TProtoStringType(); + if (!path.empty()) path += '.'; + + for (int i = 0; i < file.message_type_size(); i++) { + if (!AddSymbol(path + file.message_type(i).name(), value)) return false; + if (!AddNestedExtensions(file.name(), file.message_type(i), value)) + return false; + } + for (int i = 0; i < file.enum_type_size(); i++) { + if (!AddSymbol(path + file.enum_type(i).name(), value)) return false; + } + for (int i = 0; i < file.extension_size(); i++) { + if (!AddSymbol(path + file.extension(i).name(), value)) return false; + if (!AddExtension(file.name(), file.extension(i), value)) return false; + } + for (int i = 0; i < file.service_size(); i++) { + if (!AddSymbol(path + file.service(i).name(), value)) return false; + } + + return true; +} + +namespace { + +// Returns true if and only if all characters in the name are alphanumerics, +// underscores, or periods. +bool ValidateSymbolName(StringPiece name) { + for (char c : name) { + // I don't trust ctype.h due to locales. :( + if (c != '.' && c != '_' && (c < '0' || c > '9') && (c < 'A' || c > 'Z') && + (c < 'a' || c > 'z')) { + return false; + } + } + return true; +} + +// Find the last key in the container which sorts less than or equal to the +// symbol name. Since upper_bound() returns the *first* key that sorts +// *greater* than the input, we want the element immediately before that. +template <typename Container, typename Key> +typename Container::const_iterator FindLastLessOrEqual( + const Container* container, const Key& key) { + auto iter = container->upper_bound(key); + if (iter != container->begin()) --iter; + return iter; +} + +// As above, but using std::upper_bound instead. +template <typename Container, typename Key, typename Cmp> +typename Container::const_iterator FindLastLessOrEqual( + const Container* container, const Key& key, const Cmp& cmp) { + auto iter = std::upper_bound(container->begin(), container->end(), key, cmp); + if (iter != container->begin()) --iter; + return iter; +} + +// True if either the arguments are equal or super_symbol identifies a +// parent symbol of sub_symbol (e.g. "foo.bar" is a parent of +// "foo.bar.baz", but not a parent of "foo.barbaz"). +bool IsSubSymbol(StringPiece sub_symbol, StringPiece super_symbol) { + return sub_symbol == super_symbol || + (HasPrefixString(super_symbol, sub_symbol) && + super_symbol[sub_symbol.size()] == '.'); +} + +} // namespace + +template <typename Value> +bool SimpleDescriptorDatabase::DescriptorIndex<Value>::AddSymbol( + const TProtoStringType& name, Value value) { + // We need to make sure not to violate our map invariant. + + // If the symbol name is invalid it could break our lookup algorithm (which + // relies on the fact that '.' sorts before all other characters that are + // valid in symbol names). + if (!ValidateSymbolName(name)) { + GOOGLE_LOG(ERROR) << "Invalid symbol name: " << name; + return false; + } + + // Try to look up the symbol to make sure a super-symbol doesn't already + // exist. + auto iter = FindLastLessOrEqual(&by_symbol_, name); + + if (iter == by_symbol_.end()) { + // Apparently the map is currently empty. Just insert and be done with it. + by_symbol_.insert( + typename std::map<TProtoStringType, Value>::value_type(name, value)); + return true; + } + + if (IsSubSymbol(iter->first, name)) { + GOOGLE_LOG(ERROR) << "Symbol name \"" << name + << "\" conflicts with the existing " + "symbol \"" + << iter->first << "\"."; + return false; + } + + // OK, that worked. Now we have to make sure that no symbol in the map is + // a sub-symbol of the one we are inserting. The only symbol which could + // be so is the first symbol that is greater than the new symbol. Since + // |iter| points at the last symbol that is less than or equal, we just have + // to increment it. + ++iter; + + if (iter != by_symbol_.end() && IsSubSymbol(name, iter->first)) { + GOOGLE_LOG(ERROR) << "Symbol name \"" << name + << "\" conflicts with the existing " + "symbol \"" + << iter->first << "\"."; + return false; + } + + // OK, no conflicts. + + // Insert the new symbol using the iterator as a hint, the new entry will + // appear immediately before the one the iterator is pointing at. + by_symbol_.insert( + iter, typename std::map<TProtoStringType, Value>::value_type(name, value)); + + return true; +} + +template <typename Value> +bool SimpleDescriptorDatabase::DescriptorIndex<Value>::AddNestedExtensions( + const TProtoStringType& filename, const DescriptorProto& message_type, + Value value) { + for (int i = 0; i < message_type.nested_type_size(); i++) { + if (!AddNestedExtensions(filename, message_type.nested_type(i), value)) + return false; + } + for (int i = 0; i < message_type.extension_size(); i++) { + if (!AddExtension(filename, message_type.extension(i), value)) return false; + } + return true; +} + +template <typename Value> +bool SimpleDescriptorDatabase::DescriptorIndex<Value>::AddExtension( + const TProtoStringType& filename, const FieldDescriptorProto& field, + Value value) { + if (!field.extendee().empty() && field.extendee()[0] == '.') { + // The extension is fully-qualified. We can use it as a lookup key in + // the by_symbol_ table. + if (!InsertIfNotPresent( + &by_extension_, + std::make_pair(field.extendee().substr(1), field.number()), + value)) { + GOOGLE_LOG(ERROR) << "Extension conflicts with extension already in database: " + "extend " + << field.extendee() << " { " << field.name() << " = " + << field.number() << " } from:" << filename; + return false; + } + } else { + // Not fully-qualified. We can't really do anything here, unfortunately. + // We don't consider this an error, though, because the descriptor is + // valid. + } + return true; +} + +template <typename Value> +Value SimpleDescriptorDatabase::DescriptorIndex<Value>::FindFile( + const TProtoStringType& filename) { + return FindWithDefault(by_name_, filename, Value()); +} + +template <typename Value> +Value SimpleDescriptorDatabase::DescriptorIndex<Value>::FindSymbol( + const TProtoStringType& name) { + auto iter = FindLastLessOrEqual(&by_symbol_, name); + + return (iter != by_symbol_.end() && IsSubSymbol(iter->first, name)) + ? iter->second + : Value(); +} + +template <typename Value> +Value SimpleDescriptorDatabase::DescriptorIndex<Value>::FindExtension( + const TProtoStringType& containing_type, int field_number) { + return FindWithDefault( + by_extension_, std::make_pair(containing_type, field_number), Value()); +} + +template <typename Value> +bool SimpleDescriptorDatabase::DescriptorIndex<Value>::FindAllExtensionNumbers( + const TProtoStringType& containing_type, std::vector<int>* output) { + typename std::map<std::pair<TProtoStringType, int>, Value>::const_iterator it = + by_extension_.lower_bound(std::make_pair(containing_type, 0)); + bool success = false; + + for (; it != by_extension_.end() && it->first.first == containing_type; + ++it) { + output->push_back(it->first.second); + success = true; + } + + return success; +} + +template <typename Value> +void SimpleDescriptorDatabase::DescriptorIndex<Value>::FindAllFileNames( + std::vector<TProtoStringType>* output) { + output->resize(by_name_.size()); + int i = 0; + for (const auto& kv : by_name_) { + (*output)[i] = kv.first; + i++; + } +} + +// ------------------------------------------------------------------- + +bool SimpleDescriptorDatabase::Add(const FileDescriptorProto& file) { + FileDescriptorProto* new_file = new FileDescriptorProto; + new_file->CopyFrom(file); + return AddAndOwn(new_file); +} + +bool SimpleDescriptorDatabase::AddAndOwn(const FileDescriptorProto* file) { + files_to_delete_.emplace_back(file); + return index_.AddFile(*file, file); +} + +bool SimpleDescriptorDatabase::FindFileByName(const TProtoStringType& filename, + FileDescriptorProto* output) { + return MaybeCopy(index_.FindFile(filename), output); +} + +bool SimpleDescriptorDatabase::FindFileContainingSymbol( + const TProtoStringType& symbol_name, FileDescriptorProto* output) { + return MaybeCopy(index_.FindSymbol(symbol_name), output); +} + +bool SimpleDescriptorDatabase::FindFileContainingExtension( + const TProtoStringType& containing_type, int field_number, + FileDescriptorProto* output) { + return MaybeCopy(index_.FindExtension(containing_type, field_number), output); +} + +bool SimpleDescriptorDatabase::FindAllExtensionNumbers( + const TProtoStringType& extendee_type, std::vector<int>* output) { + return index_.FindAllExtensionNumbers(extendee_type, output); +} + + +bool SimpleDescriptorDatabase::FindAllFileNames( + std::vector<TProtoStringType>* output) { + index_.FindAllFileNames(output); + return true; +} + +bool SimpleDescriptorDatabase::MaybeCopy(const FileDescriptorProto* file, + FileDescriptorProto* output) { + if (file == nullptr) return false; + output->CopyFrom(*file); + return true; +} + +// ------------------------------------------------------------------- + +class EncodedDescriptorDatabase::DescriptorIndex { + public: + using Value = std::pair<const void*, int>; + // Helpers to recursively add particular descriptors and all their contents + // to the index. + template <typename FileProto> + bool AddFile(const FileProto& file, Value value); + + Value FindFile(StringPiece filename); + Value FindSymbol(StringPiece name); + Value FindSymbolOnlyFlat(StringPiece name) const; + Value FindExtension(StringPiece containing_type, int field_number); + bool FindAllExtensionNumbers(StringPiece containing_type, + std::vector<int>* output); + void FindAllFileNames(std::vector<TProtoStringType>* output) const; + + private: + friend class EncodedDescriptorDatabase; + + bool AddSymbol(StringPiece symbol); + + template <typename DescProto> + bool AddNestedExtensions(StringPiece filename, + const DescProto& message_type); + template <typename FieldProto> + bool AddExtension(StringPiece filename, const FieldProto& field); + + // All the maps below have two representations: + // - a std::set<> where we insert initially. + // - a std::vector<> where we flatten the structure on demand. + // The initial tree helps avoid O(N) behavior of inserting into a sorted + // vector, while the vector reduces the heap requirements of the data + // structure. + + void EnsureFlat(); + + using String = TProtoStringType; + + String EncodeString(StringPiece str) const { return String(str); } + StringPiece DecodeString(const String& str, int) const { return str; } + + struct EncodedEntry { + // Do not use `Value` here to avoid the padding of that object. + const void* data; + int size; + // Keep the package here instead of each SymbolEntry to save space. + String encoded_package; + + Value value() const { return {data, size}; } + }; + std::vector<EncodedEntry> all_values_; + + struct FileEntry { + int data_offset; + String encoded_name; + + StringPiece name(const DescriptorIndex& index) const { + return index.DecodeString(encoded_name, data_offset); + } + }; + struct FileCompare { + const DescriptorIndex& index; + + bool operator()(const FileEntry& a, const FileEntry& b) const { + return a.name(index) < b.name(index); + } + bool operator()(const FileEntry& a, StringPiece b) const { + return a.name(index) < b; + } + bool operator()(StringPiece a, const FileEntry& b) const { + return a < b.name(index); + } + }; + std::set<FileEntry, FileCompare> by_name_{FileCompare{*this}}; + std::vector<FileEntry> by_name_flat_; + + struct SymbolEntry { + int data_offset; + String encoded_symbol; + + StringPiece package(const DescriptorIndex& index) const { + return index.DecodeString(index.all_values_[data_offset].encoded_package, + data_offset); + } + StringPiece symbol(const DescriptorIndex& index) const { + return index.DecodeString(encoded_symbol, data_offset); + } + + TProtoStringType AsString(const DescriptorIndex& index) const { + auto p = package(index); + return StrCat(p, p.empty() ? "" : ".", symbol(index)); + } + }; + + struct SymbolCompare { + const DescriptorIndex& index; + + TProtoStringType AsString(const SymbolEntry& entry) const { + return entry.AsString(index); + } + static StringPiece AsString(StringPiece str) { return str; } + + std::pair<StringPiece, StringPiece> GetParts( + const SymbolEntry& entry) const { + auto package = entry.package(index); + if (package.empty()) return {entry.symbol(index), StringPiece{}}; + return {package, entry.symbol(index)}; + } + std::pair<StringPiece, StringPiece> GetParts( + StringPiece str) const { + return {str, {}}; + } + + template <typename T, typename U> + bool operator()(const T& lhs, const U& rhs) const { + auto lhs_parts = GetParts(lhs); + auto rhs_parts = GetParts(rhs); + + // Fast path to avoid making the whole string for common cases. + if (int res = + lhs_parts.first.substr(0, rhs_parts.first.size()) + .compare(rhs_parts.first.substr(0, lhs_parts.first.size()))) { + // If the packages already differ, exit early. + return res < 0; + } else if (lhs_parts.first.size() == rhs_parts.first.size()) { + return lhs_parts.second < rhs_parts.second; + } + return AsString(lhs) < AsString(rhs); + } + }; + std::set<SymbolEntry, SymbolCompare> by_symbol_{SymbolCompare{*this}}; + std::vector<SymbolEntry> by_symbol_flat_; + + struct ExtensionEntry { + int data_offset; + String encoded_extendee; + StringPiece extendee(const DescriptorIndex& index) const { + return index.DecodeString(encoded_extendee, data_offset).substr(1); + } + int extension_number; + }; + struct ExtensionCompare { + const DescriptorIndex& index; + + bool operator()(const ExtensionEntry& a, const ExtensionEntry& b) const { + return std::make_tuple(a.extendee(index), a.extension_number) < + std::make_tuple(b.extendee(index), b.extension_number); + } + bool operator()(const ExtensionEntry& a, + std::tuple<StringPiece, int> b) const { + return std::make_tuple(a.extendee(index), a.extension_number) < b; + } + bool operator()(std::tuple<StringPiece, int> a, + const ExtensionEntry& b) const { + return a < std::make_tuple(b.extendee(index), b.extension_number); + } + }; + std::set<ExtensionEntry, ExtensionCompare> by_extension_{ + ExtensionCompare{*this}}; + std::vector<ExtensionEntry> by_extension_flat_; +}; + +bool EncodedDescriptorDatabase::Add(const void* encoded_file_descriptor, + int size) { + FileDescriptorProto file; + if (file.ParseFromArray(encoded_file_descriptor, size)) { + return index_->AddFile(file, std::make_pair(encoded_file_descriptor, size)); + } else { + GOOGLE_LOG(ERROR) << "Invalid file descriptor data passed to " + "EncodedDescriptorDatabase::Add()."; + return false; + } +} + +bool EncodedDescriptorDatabase::AddCopy(const void* encoded_file_descriptor, + int size) { + void* copy = operator new(size); + memcpy(copy, encoded_file_descriptor, size); + files_to_delete_.push_back(copy); + return Add(copy, size); +} + +bool EncodedDescriptorDatabase::FindFileByName(const TProtoStringType& filename, + FileDescriptorProto* output) { + return MaybeParse(index_->FindFile(filename), output); +} + +bool EncodedDescriptorDatabase::FindFileContainingSymbol( + const TProtoStringType& symbol_name, FileDescriptorProto* output) { + return MaybeParse(index_->FindSymbol(symbol_name), output); +} + +bool EncodedDescriptorDatabase::FindNameOfFileContainingSymbol( + const TProtoStringType& symbol_name, TProtoStringType* output) { + auto encoded_file = index_->FindSymbol(symbol_name); + if (encoded_file.first == nullptr) return false; + + // Optimization: The name should be the first field in the encoded message. + // Try to just read it directly. + io::CodedInputStream input(static_cast<const uint8_t*>(encoded_file.first), + encoded_file.second); + + const arc_ui32 kNameTag = internal::WireFormatLite::MakeTag( + FileDescriptorProto::kNameFieldNumber, + internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED); + + if (input.ReadTagNoLastTag() == kNameTag) { + // Success! + return internal::WireFormatLite::ReadString(&input, output); + } else { + // Slow path. Parse whole message. + FileDescriptorProto file_proto; + if (!file_proto.ParseFromArray(encoded_file.first, encoded_file.second)) { + return false; + } + *output = file_proto.name(); + return true; + } +} + +bool EncodedDescriptorDatabase::FindFileContainingExtension( + const TProtoStringType& containing_type, int field_number, + FileDescriptorProto* output) { + return MaybeParse(index_->FindExtension(containing_type, field_number), + output); +} + +bool EncodedDescriptorDatabase::FindAllExtensionNumbers( + const TProtoStringType& extendee_type, std::vector<int>* output) { + return index_->FindAllExtensionNumbers(extendee_type, output); +} + +template <typename FileProto> +bool EncodedDescriptorDatabase::DescriptorIndex::AddFile(const FileProto& file, + Value value) { + // We push `value` into the array first. This is important because the AddXXX + // functions below will expect it to be there. + all_values_.push_back({value.first, value.second, {}}); + + if (!ValidateSymbolName(file.package())) { + GOOGLE_LOG(ERROR) << "Invalid package name: " << file.package(); + return false; + } + all_values_.back().encoded_package = EncodeString(file.package()); + + if (!InsertIfNotPresent( + &by_name_, FileEntry{static_cast<int>(all_values_.size() - 1), + EncodeString(file.name())}) || + std::binary_search(by_name_flat_.begin(), by_name_flat_.end(), + file.name(), by_name_.key_comp())) { + GOOGLE_LOG(ERROR) << "File already exists in database: " << file.name(); + return false; + } + + for (const auto& message_type : file.message_type()) { + if (!AddSymbol(message_type.name())) return false; + if (!AddNestedExtensions(file.name(), message_type)) return false; + } + for (const auto& enum_type : file.enum_type()) { + if (!AddSymbol(enum_type.name())) return false; + } + for (const auto& extension : file.extension()) { + if (!AddSymbol(extension.name())) return false; + if (!AddExtension(file.name(), extension)) return false; + } + for (const auto& service : file.service()) { + if (!AddSymbol(service.name())) return false; + } + + return true; +} + +template <typename Iter, typename Iter2, typename Index> +static bool CheckForMutualSubsymbols(StringPiece symbol_name, Iter* iter, + Iter2 end, const Index& index) { + if (*iter != end) { + if (IsSubSymbol((*iter)->AsString(index), symbol_name)) { + GOOGLE_LOG(ERROR) << "Symbol name \"" << symbol_name + << "\" conflicts with the existing symbol \"" + << (*iter)->AsString(index) << "\"."; + return false; + } + + // OK, that worked. Now we have to make sure that no symbol in the map is + // a sub-symbol of the one we are inserting. The only symbol which could + // be so is the first symbol that is greater than the new symbol. Since + // |iter| points at the last symbol that is less than or equal, we just have + // to increment it. + ++*iter; + + if (*iter != end && IsSubSymbol(symbol_name, (*iter)->AsString(index))) { + GOOGLE_LOG(ERROR) << "Symbol name \"" << symbol_name + << "\" conflicts with the existing symbol \"" + << (*iter)->AsString(index) << "\"."; + return false; + } + } + return true; +} + +bool EncodedDescriptorDatabase::DescriptorIndex::AddSymbol( + StringPiece symbol) { + SymbolEntry entry = {static_cast<int>(all_values_.size() - 1), + EncodeString(symbol)}; + TProtoStringType entry_as_string = entry.AsString(*this); + + // We need to make sure not to violate our map invariant. + + // If the symbol name is invalid it could break our lookup algorithm (which + // relies on the fact that '.' sorts before all other characters that are + // valid in symbol names). + if (!ValidateSymbolName(symbol)) { + GOOGLE_LOG(ERROR) << "Invalid symbol name: " << entry_as_string; + return false; + } + + auto iter = FindLastLessOrEqual(&by_symbol_, entry); + if (!CheckForMutualSubsymbols(entry_as_string, &iter, by_symbol_.end(), + *this)) { + return false; + } + + // Same, but on by_symbol_flat_ + auto flat_iter = + FindLastLessOrEqual(&by_symbol_flat_, entry, by_symbol_.key_comp()); + if (!CheckForMutualSubsymbols(entry_as_string, &flat_iter, + by_symbol_flat_.end(), *this)) { + return false; + } + + // OK, no conflicts. + + // Insert the new symbol using the iterator as a hint, the new entry will + // appear immediately before the one the iterator is pointing at. + by_symbol_.insert(iter, entry); + + return true; +} + +template <typename DescProto> +bool EncodedDescriptorDatabase::DescriptorIndex::AddNestedExtensions( + StringPiece filename, const DescProto& message_type) { + for (const auto& nested_type : message_type.nested_type()) { + if (!AddNestedExtensions(filename, nested_type)) return false; + } + for (const auto& extension : message_type.extension()) { + if (!AddExtension(filename, extension)) return false; + } + return true; +} + +template <typename FieldProto> +bool EncodedDescriptorDatabase::DescriptorIndex::AddExtension( + StringPiece filename, const FieldProto& field) { + if (!field.extendee().empty() && field.extendee()[0] == '.') { + // The extension is fully-qualified. We can use it as a lookup key in + // the by_symbol_ table. + if (!InsertIfNotPresent( + &by_extension_, + ExtensionEntry{static_cast<int>(all_values_.size() - 1), + EncodeString(field.extendee()), field.number()}) || + std::binary_search( + by_extension_flat_.begin(), by_extension_flat_.end(), + std::make_pair(field.extendee().substr(1), field.number()), + by_extension_.key_comp())) { + GOOGLE_LOG(ERROR) << "Extension conflicts with extension already in database: " + "extend " + << field.extendee() << " { " << field.name() << " = " + << field.number() << " } from:" << filename; + return false; + } + } else { + // Not fully-qualified. We can't really do anything here, unfortunately. + // We don't consider this an error, though, because the descriptor is + // valid. + } + return true; +} + +std::pair<const void*, int> +EncodedDescriptorDatabase::DescriptorIndex::FindSymbol(StringPiece name) { + EnsureFlat(); + return FindSymbolOnlyFlat(name); +} + +std::pair<const void*, int> +EncodedDescriptorDatabase::DescriptorIndex::FindSymbolOnlyFlat( + StringPiece name) const { + auto iter = + FindLastLessOrEqual(&by_symbol_flat_, name, by_symbol_.key_comp()); + + return iter != by_symbol_flat_.end() && + IsSubSymbol(iter->AsString(*this), name) + ? all_values_[iter->data_offset].value() + : Value(); +} + +std::pair<const void*, int> +EncodedDescriptorDatabase::DescriptorIndex::FindExtension( + StringPiece containing_type, int field_number) { + EnsureFlat(); + + auto it = std::lower_bound( + by_extension_flat_.begin(), by_extension_flat_.end(), + std::make_tuple(containing_type, field_number), by_extension_.key_comp()); + return it == by_extension_flat_.end() || + it->extendee(*this) != containing_type || + it->extension_number != field_number + ? std::make_pair(nullptr, 0) + : all_values_[it->data_offset].value(); +} + +template <typename T, typename Less> +static void MergeIntoFlat(std::set<T, Less>* s, std::vector<T>* flat) { + if (s->empty()) return; + std::vector<T> new_flat(s->size() + flat->size()); + std::merge(s->begin(), s->end(), flat->begin(), flat->end(), &new_flat[0], + s->key_comp()); + *flat = std::move(new_flat); + s->clear(); +} + +void EncodedDescriptorDatabase::DescriptorIndex::EnsureFlat() { + all_values_.shrink_to_fit(); + // Merge each of the sets into their flat counterpart. + MergeIntoFlat(&by_name_, &by_name_flat_); + MergeIntoFlat(&by_symbol_, &by_symbol_flat_); + MergeIntoFlat(&by_extension_, &by_extension_flat_); +} + +bool EncodedDescriptorDatabase::DescriptorIndex::FindAllExtensionNumbers( + StringPiece containing_type, std::vector<int>* output) { + EnsureFlat(); + + bool success = false; + auto it = std::lower_bound( + by_extension_flat_.begin(), by_extension_flat_.end(), + std::make_tuple(containing_type, 0), by_extension_.key_comp()); + for (; + it != by_extension_flat_.end() && it->extendee(*this) == containing_type; + ++it) { + output->push_back(it->extension_number); + success = true; + } + + return success; +} + +void EncodedDescriptorDatabase::DescriptorIndex::FindAllFileNames( + std::vector<TProtoStringType>* output) const { + output->resize(by_name_.size() + by_name_flat_.size()); + int i = 0; + for (const auto& entry : by_name_) { + (*output)[i] = TProtoStringType(entry.name(*this)); + i++; + } + for (const auto& entry : by_name_flat_) { + (*output)[i] = TProtoStringType(entry.name(*this)); + i++; + } +} + +std::pair<const void*, int> +EncodedDescriptorDatabase::DescriptorIndex::FindFile( + StringPiece filename) { + EnsureFlat(); + + auto it = std::lower_bound(by_name_flat_.begin(), by_name_flat_.end(), + filename, by_name_.key_comp()); + return it == by_name_flat_.end() || it->name(*this) != filename + ? std::make_pair(nullptr, 0) + : all_values_[it->data_offset].value(); +} + + +bool EncodedDescriptorDatabase::FindAllFileNames( + std::vector<TProtoStringType>* output) { + index_->FindAllFileNames(output); + return true; +} + +bool EncodedDescriptorDatabase::MaybeParse( + std::pair<const void*, int> encoded_file, FileDescriptorProto* output) { + if (encoded_file.first == nullptr) return false; + return output->ParseFromArray(encoded_file.first, encoded_file.second); +} + +EncodedDescriptorDatabase::EncodedDescriptorDatabase() + : index_(new DescriptorIndex()) {} + +EncodedDescriptorDatabase::~EncodedDescriptorDatabase() { + for (void* p : files_to_delete_) { + operator delete(p); + } +} + +// =================================================================== + +DescriptorPoolDatabase::DescriptorPoolDatabase(const DescriptorPool& pool) + : pool_(pool) {} +DescriptorPoolDatabase::~DescriptorPoolDatabase() {} + +bool DescriptorPoolDatabase::FindFileByName(const TProtoStringType& filename, + FileDescriptorProto* output) { + const FileDescriptor* file = pool_.FindFileByName(filename); + if (file == nullptr) return false; + output->Clear(); + file->CopyTo(output); + return true; +} + +bool DescriptorPoolDatabase::FindFileContainingSymbol( + const TProtoStringType& symbol_name, FileDescriptorProto* output) { + const FileDescriptor* file = pool_.FindFileContainingSymbol(symbol_name); + if (file == nullptr) return false; + output->Clear(); + file->CopyTo(output); + return true; +} + +bool DescriptorPoolDatabase::FindFileContainingExtension( + const TProtoStringType& containing_type, int field_number, + FileDescriptorProto* output) { + const Descriptor* extendee = pool_.FindMessageTypeByName(containing_type); + if (extendee == nullptr) return false; + + const FieldDescriptor* extension = + pool_.FindExtensionByNumber(extendee, field_number); + if (extension == nullptr) return false; + + output->Clear(); + extension->file()->CopyTo(output); + return true; +} + +bool DescriptorPoolDatabase::FindAllExtensionNumbers( + const TProtoStringType& extendee_type, std::vector<int>* output) { + const Descriptor* extendee = pool_.FindMessageTypeByName(extendee_type); + if (extendee == nullptr) return false; + + std::vector<const FieldDescriptor*> extensions; + pool_.FindAllExtensions(extendee, &extensions); + + for (const FieldDescriptor* extension : extensions) { + output->push_back(extension->number()); + } + + return true; +} + +// =================================================================== + +MergedDescriptorDatabase::MergedDescriptorDatabase( + DescriptorDatabase* source1, DescriptorDatabase* source2) { + sources_.push_back(source1); + sources_.push_back(source2); +} +MergedDescriptorDatabase::MergedDescriptorDatabase( + const std::vector<DescriptorDatabase*>& sources) + : sources_(sources) {} +MergedDescriptorDatabase::~MergedDescriptorDatabase() {} + +bool MergedDescriptorDatabase::FindFileByName(const TProtoStringType& filename, + FileDescriptorProto* output) { + for (DescriptorDatabase* source : sources_) { + if (source->FindFileByName(filename, output)) { + return true; + } + } + return false; +} + +bool MergedDescriptorDatabase::FindFileContainingSymbol( + const TProtoStringType& symbol_name, FileDescriptorProto* output) { + for (size_t i = 0; i < sources_.size(); i++) { + if (sources_[i]->FindFileContainingSymbol(symbol_name, output)) { + // The symbol was found in source i. However, if one of the previous + // sources defines a file with the same name (which presumably doesn't + // contain the symbol, since it wasn't found in that source), then we + // must hide it from the caller. + FileDescriptorProto temp; + for (size_t j = 0; j < i; j++) { + if (sources_[j]->FindFileByName(output->name(), &temp)) { + // Found conflicting file in a previous source. + return false; + } + } + return true; + } + } + return false; +} + +bool MergedDescriptorDatabase::FindFileContainingExtension( + const TProtoStringType& containing_type, int field_number, + FileDescriptorProto* output) { + for (size_t i = 0; i < sources_.size(); i++) { + if (sources_[i]->FindFileContainingExtension(containing_type, field_number, + output)) { + // The symbol was found in source i. However, if one of the previous + // sources defines a file with the same name (which presumably doesn't + // contain the symbol, since it wasn't found in that source), then we + // must hide it from the caller. + FileDescriptorProto temp; + for (size_t j = 0; j < i; j++) { + if (sources_[j]->FindFileByName(output->name(), &temp)) { + // Found conflicting file in a previous source. + return false; + } + } + return true; + } + } + return false; +} + +bool MergedDescriptorDatabase::FindAllExtensionNumbers( + const TProtoStringType& extendee_type, std::vector<int>* output) { + std::set<int> merged_results; + std::vector<int> results; + bool success = false; + + for (DescriptorDatabase* source : sources_) { + if (source->FindAllExtensionNumbers(extendee_type, &results)) { + std::copy(results.begin(), results.end(), + std::insert_iterator<std::set<int> >(merged_results, + merged_results.begin())); + success = true; + } + results.clear(); + } + + std::copy(merged_results.begin(), merged_results.end(), + std::insert_iterator<std::vector<int> >(*output, output->end())); + + return success; +} + + +} // namespace protobuf +} // namespace google diff --git a/contrib/libs/protobuf_old/src/google/protobuf/descriptor_database.h b/contrib/libs/protobuf_old/src/google/protobuf/descriptor_database.h new file mode 100644 index 0000000000..9c9941031d --- /dev/null +++ b/contrib/libs/protobuf_old/src/google/protobuf/descriptor_database.h @@ -0,0 +1,391 @@ +// 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: kenton@google.com (Kenton Varda) +// Based on original Protocol Buffers design by +// Sanjay Ghemawat, Jeff Dean, and others. +// +// Interface for manipulating databases of descriptors. + +#ifndef GOOGLE_PROTOBUF_DESCRIPTOR_DATABASE_H__ +#define GOOGLE_PROTOBUF_DESCRIPTOR_DATABASE_H__ + +#include <map> +#include <string> +#include <utility> +#include <vector> +#include <google/protobuf/stubs/common.h> +#include <google/protobuf/descriptor.h> + +#include <google/protobuf/port_def.inc> + +#ifdef SWIG +#error "You cannot SWIG proto headers" +#endif + +namespace google { +namespace protobuf { + +// Defined in this file. +class DescriptorDatabase; +class SimpleDescriptorDatabase; +class EncodedDescriptorDatabase; +class DescriptorPoolDatabase; +class MergedDescriptorDatabase; + +// Abstract interface for a database of descriptors. +// +// This is useful if you want to create a DescriptorPool which loads +// descriptors on-demand from some sort of large database. If the database +// is large, it may be inefficient to enumerate every .proto file inside it +// calling DescriptorPool::BuildFile() for each one. Instead, a DescriptorPool +// can be created which wraps a DescriptorDatabase and only builds particular +// descriptors when they are needed. +class PROTOBUF_EXPORT DescriptorDatabase { + public: + inline DescriptorDatabase() {} + virtual ~DescriptorDatabase(); + + // Find a file by file name. Fills in in *output and returns true if found. + // Otherwise, returns false, leaving the contents of *output undefined. + virtual bool FindFileByName(const TProtoStringType& filename, + FileDescriptorProto* output) = 0; + + // Find the file that declares the given fully-qualified symbol name. + // If found, fills in *output and returns true, otherwise returns false + // and leaves *output undefined. + virtual bool FindFileContainingSymbol(const TProtoStringType& symbol_name, + FileDescriptorProto* output) = 0; + + // Find the file which defines an extension extending the given message type + // with the given field number. If found, fills in *output and returns true, + // otherwise returns false and leaves *output undefined. containing_type + // must be a fully-qualified type name. + virtual bool FindFileContainingExtension(const TProtoStringType& containing_type, + int field_number, + FileDescriptorProto* output) = 0; + + // Finds the tag numbers used by all known extensions of + // extendee_type, and appends them to output in an undefined + // order. This method is best-effort: it's not guaranteed that the + // database will find all extensions, and it's not guaranteed that + // FindFileContainingExtension will return true on all of the found + // numbers. Returns true if the search was successful, otherwise + // returns false and leaves output unchanged. + // + // This method has a default implementation that always returns + // false. + virtual bool FindAllExtensionNumbers(const TProtoStringType& /* extendee_type */, + std::vector<int>* /* output */) { + return false; + } + + + // Finds the file names and appends them to the output in an + // undefined order. This method is best-effort: it's not guaranteed that the + // database will find all files. Returns true if the database supports + // searching all file names, otherwise returns false and leaves output + // unchanged. + // + // This method has a default implementation that always returns + // false. + virtual bool FindAllFileNames(std::vector<TProtoStringType>* /*output*/) { + return false; + } + + // Finds the package names and appends them to the output in an + // undefined order. This method is best-effort: it's not guaranteed that the + // database will find all packages. Returns true if the database supports + // searching all package names, otherwise returns false and leaves output + // unchanged. + bool FindAllPackageNames(std::vector<TProtoStringType>* output); + + // Finds the message names and appends them to the output in an + // undefined order. This method is best-effort: it's not guaranteed that the + // database will find all messages. Returns true if the database supports + // searching all message names, otherwise returns false and leaves output + // unchanged. + bool FindAllMessageNames(std::vector<TProtoStringType>* output); + + private: + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(DescriptorDatabase); +}; + +// A DescriptorDatabase into which you can insert files manually. +// +// FindFileContainingSymbol() is fully-implemented. When you add a file, its +// symbols will be indexed for this purpose. Note that the implementation +// may return false positives, but only if it isn't possible for the symbol +// to be defined in any other file. In particular, if a file defines a symbol +// "Foo", then searching for "Foo.[anything]" will match that file. This way, +// the database does not need to aggressively index all children of a symbol. +// +// FindFileContainingExtension() is mostly-implemented. It works if and only +// if the original FieldDescriptorProto defining the extension has a +// fully-qualified type name in its "extendee" field (i.e. starts with a '.'). +// If the extendee is a relative name, SimpleDescriptorDatabase will not +// attempt to resolve the type, so it will not know what type the extension is +// extending. Therefore, calling FindFileContainingExtension() with the +// extension's containing type will never actually find that extension. Note +// that this is an unlikely problem, as all FileDescriptorProtos created by the +// protocol compiler (as well as ones created by calling +// FileDescriptor::CopyTo()) will always use fully-qualified names for all +// types. You only need to worry if you are constructing FileDescriptorProtos +// yourself, or are calling compiler::Parser directly. +class PROTOBUF_EXPORT SimpleDescriptorDatabase : public DescriptorDatabase { + public: + SimpleDescriptorDatabase(); + ~SimpleDescriptorDatabase() override; + + // Adds the FileDescriptorProto to the database, making a copy. The object + // can be deleted after Add() returns. Returns false if the file conflicted + // with a file already in the database, in which case an error will have + // been written to GOOGLE_LOG(ERROR). + bool Add(const FileDescriptorProto& file); + + // Adds the FileDescriptorProto to the database and takes ownership of it. + bool AddAndOwn(const FileDescriptorProto* file); + + // implements DescriptorDatabase ----------------------------------- + bool FindFileByName(const TProtoStringType& filename, + FileDescriptorProto* output) override; + bool FindFileContainingSymbol(const TProtoStringType& symbol_name, + FileDescriptorProto* output) override; + bool FindFileContainingExtension(const TProtoStringType& containing_type, + int field_number, + FileDescriptorProto* output) override; + bool FindAllExtensionNumbers(const TProtoStringType& extendee_type, + std::vector<int>* output) override; + + bool FindAllFileNames(std::vector<TProtoStringType>* output) override; + + private: + // An index mapping file names, symbol names, and extension numbers to + // some sort of values. + template <typename Value> + class DescriptorIndex { + public: + // Helpers to recursively add particular descriptors and all their contents + // to the index. + bool AddFile(const FileDescriptorProto& file, Value value); + bool AddSymbol(const TProtoStringType& name, Value value); + bool AddNestedExtensions(const TProtoStringType& filename, + const DescriptorProto& message_type, Value value); + bool AddExtension(const TProtoStringType& filename, + const FieldDescriptorProto& field, Value value); + + Value FindFile(const TProtoStringType& filename); + Value FindSymbol(const TProtoStringType& name); + Value FindExtension(const TProtoStringType& containing_type, int field_number); + bool FindAllExtensionNumbers(const TProtoStringType& containing_type, + std::vector<int>* output); + void FindAllFileNames(std::vector<TProtoStringType>* output); + + private: + std::map<TProtoStringType, Value> by_name_; + std::map<TProtoStringType, Value> by_symbol_; + std::map<std::pair<TProtoStringType, int>, Value> by_extension_; + + // Invariant: The by_symbol_ map does not contain any symbols which are + // prefixes of other symbols in the map. For example, "foo.bar" is a + // prefix of "foo.bar.baz" (but is not a prefix of "foo.barbaz"). + // + // This invariant is important because it means that given a symbol name, + // we can find a key in the map which is a prefix of the symbol in O(lg n) + // time, and we know that there is at most one such key. + // + // The prefix lookup algorithm works like so: + // 1) Find the last key in the map which is less than or equal to the + // search key. + // 2) If the found key is a prefix of the search key, then return it. + // Otherwise, there is no match. + // + // I am sure this algorithm has been described elsewhere, but since I + // wasn't able to find it quickly I will instead prove that it works + // myself. The key to the algorithm is that if a match exists, step (1) + // will find it. Proof: + // 1) Define the "search key" to be the key we are looking for, the "found + // key" to be the key found in step (1), and the "match key" to be the + // key which actually matches the search key (i.e. the key we're trying + // to find). + // 2) The found key must be less than or equal to the search key by + // definition. + // 3) The match key must also be less than or equal to the search key + // (because it is a prefix). + // 4) The match key cannot be greater than the found key, because if it + // were, then step (1) of the algorithm would have returned the match + // key instead (since it finds the *greatest* key which is less than or + // equal to the search key). + // 5) Therefore, the found key must be between the match key and the search + // key, inclusive. + // 6) Since the search key must be a sub-symbol of the match key, if it is + // not equal to the match key, then search_key[match_key.size()] must + // be '.'. + // 7) Since '.' sorts before any other character that is valid in a symbol + // name, then if the found key is not equal to the match key, then + // found_key[match_key.size()] must also be '.', because any other value + // would make it sort after the search key. + // 8) Therefore, if the found key is not equal to the match key, then the + // found key must be a sub-symbol of the match key. However, this would + // contradict our map invariant which says that no symbol in the map is + // a sub-symbol of any other. + // 9) Therefore, the found key must match the match key. + // + // The above proof assumes the match key exists. In the case that the + // match key does not exist, then step (1) will return some other symbol. + // That symbol cannot be a super-symbol of the search key since if it were, + // then it would be a match, and we're assuming the match key doesn't exist. + // Therefore, step 2 will correctly return no match. + }; + + DescriptorIndex<const FileDescriptorProto*> index_; + std::vector<std::unique_ptr<const FileDescriptorProto>> files_to_delete_; + + // If file is non-nullptr, copy it into *output and return true, otherwise + // return false. + bool MaybeCopy(const FileDescriptorProto* file, FileDescriptorProto* output); + + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(SimpleDescriptorDatabase); +}; + +// Very similar to SimpleDescriptorDatabase, but stores all the descriptors +// as raw bytes and generally tries to use as little memory as possible. +// +// The same caveats regarding FindFileContainingExtension() apply as with +// SimpleDescriptorDatabase. +class PROTOBUF_EXPORT EncodedDescriptorDatabase : public DescriptorDatabase { + public: + EncodedDescriptorDatabase(); + ~EncodedDescriptorDatabase() override; + + // Adds the FileDescriptorProto to the database. The descriptor is provided + // in encoded form. The database does not make a copy of the bytes, nor + // does it take ownership; it's up to the caller to make sure the bytes + // remain valid for the life of the database. Returns false and logs an error + // if the bytes are not a valid FileDescriptorProto or if the file conflicted + // with a file already in the database. + bool Add(const void* encoded_file_descriptor, int size); + + // Like Add(), but makes a copy of the data, so that the caller does not + // need to keep it around. + bool AddCopy(const void* encoded_file_descriptor, int size); + + // Like FindFileContainingSymbol but returns only the name of the file. + bool FindNameOfFileContainingSymbol(const TProtoStringType& symbol_name, + TProtoStringType* output); + + // implements DescriptorDatabase ----------------------------------- + bool FindFileByName(const TProtoStringType& filename, + FileDescriptorProto* output) override; + bool FindFileContainingSymbol(const TProtoStringType& symbol_name, + FileDescriptorProto* output) override; + bool FindFileContainingExtension(const TProtoStringType& containing_type, + int field_number, + FileDescriptorProto* output) override; + bool FindAllExtensionNumbers(const TProtoStringType& extendee_type, + std::vector<int>* output) override; + bool FindAllFileNames(std::vector<TProtoStringType>* output) override; + + private: + class DescriptorIndex; + // Keep DescriptorIndex by pointer to hide the implementation to keep a + // cleaner header. + std::unique_ptr<DescriptorIndex> index_; + std::vector<void*> files_to_delete_; + + // If encoded_file.first is non-nullptr, parse the data into *output and + // return true, otherwise return false. + bool MaybeParse(std::pair<const void*, int> encoded_file, + FileDescriptorProto* output); + + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(EncodedDescriptorDatabase); +}; + +// A DescriptorDatabase that fetches files from a given pool. +class PROTOBUF_EXPORT DescriptorPoolDatabase : public DescriptorDatabase { + public: + explicit DescriptorPoolDatabase(const DescriptorPool& pool); + ~DescriptorPoolDatabase() override; + + // implements DescriptorDatabase ----------------------------------- + bool FindFileByName(const TProtoStringType& filename, + FileDescriptorProto* output) override; + bool FindFileContainingSymbol(const TProtoStringType& symbol_name, + FileDescriptorProto* output) override; + bool FindFileContainingExtension(const TProtoStringType& containing_type, + int field_number, + FileDescriptorProto* output) override; + bool FindAllExtensionNumbers(const TProtoStringType& extendee_type, + std::vector<int>* output) override; + + private: + const DescriptorPool& pool_; + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(DescriptorPoolDatabase); +}; + +// A DescriptorDatabase that wraps two or more others. It first searches the +// first database and, if that fails, tries the second, and so on. +class PROTOBUF_EXPORT MergedDescriptorDatabase : public DescriptorDatabase { + public: + // Merge just two databases. The sources remain property of the caller. + MergedDescriptorDatabase(DescriptorDatabase* source1, + DescriptorDatabase* source2); + // Merge more than two databases. The sources remain property of the caller. + // The vector may be deleted after the constructor returns but the + // DescriptorDatabases need to stick around. + explicit MergedDescriptorDatabase( + const std::vector<DescriptorDatabase*>& sources); + ~MergedDescriptorDatabase() override; + + // implements DescriptorDatabase ----------------------------------- + bool FindFileByName(const TProtoStringType& filename, + FileDescriptorProto* output) override; + bool FindFileContainingSymbol(const TProtoStringType& symbol_name, + FileDescriptorProto* output) override; + bool FindFileContainingExtension(const TProtoStringType& containing_type, + int field_number, + FileDescriptorProto* output) override; + // Merges the results of calling all databases. Returns true iff any + // of the databases returned true. + bool FindAllExtensionNumbers(const TProtoStringType& extendee_type, + std::vector<int>* output) override; + + + private: + std::vector<DescriptorDatabase*> sources_; + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(MergedDescriptorDatabase); +}; + +} // namespace protobuf +} // namespace google + +#include <google/protobuf/port_undef.inc> + +#endif // GOOGLE_PROTOBUF_DESCRIPTOR_DATABASE_H__ diff --git a/contrib/libs/protobuf_old/src/google/protobuf/duration.pb.cc b/contrib/libs/protobuf_old/src/google/protobuf/duration.pb.cc new file mode 100644 index 0000000000..a88ff6686d --- /dev/null +++ b/contrib/libs/protobuf_old/src/google/protobuf/duration.pb.cc @@ -0,0 +1,300 @@ +// Generated by the protocol buffer compiler. DO NOT EDIT! +// source: google/protobuf/duration.proto + +#include <google/protobuf/duration.pb.h> + +#include <algorithm> + +#include <google/protobuf/io/coded_stream.h> +#include <google/protobuf/extension_set.h> +#include <google/protobuf/wire_format_lite.h> +#include <google/protobuf/descriptor.h> +#include <google/protobuf/generated_message_reflection.h> +#include <google/protobuf/reflection_ops.h> +#include <google/protobuf/wire_format.h> +// @@protoc_insertion_point(includes) +#include <google/protobuf/port_def.inc> + +PROTOBUF_PRAGMA_INIT_SEG +PROTOBUF_NAMESPACE_OPEN +constexpr Duration::Duration( + ::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized) + : seconds_(arc_i64{0}) + , nanos_(0){} +struct DurationDefaultTypeInternal { + constexpr DurationDefaultTypeInternal() + : _instance(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized{}) {} + ~DurationDefaultTypeInternal() {} + union { + Duration _instance; + }; +}; +PROTOBUF_ATTRIBUTE_NO_DESTROY PROTOBUF_CONSTINIT DurationDefaultTypeInternal _Duration_default_instance_; +PROTOBUF_NAMESPACE_CLOSE +static ::PROTOBUF_NAMESPACE_ID::Metadata file_level_metadata_google_2fprotobuf_2fduration_2eproto[1]; +static constexpr ::PROTOBUF_NAMESPACE_ID::EnumDescriptor const** file_level_enum_descriptors_google_2fprotobuf_2fduration_2eproto = nullptr; +static constexpr ::PROTOBUF_NAMESPACE_ID::ServiceDescriptor const** file_level_service_descriptors_google_2fprotobuf_2fduration_2eproto = nullptr; + +const arc_ui32 TableStruct_google_2fprotobuf_2fduration_2eproto::offsets[] PROTOBUF_SECTION_VARIABLE(protodesc_cold) = { + ~0u, // no _has_bits_ + PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::Duration, _internal_metadata_), + ~0u, // no _extensions_ + ~0u, // no _oneof_case_ + ~0u, // no _weak_field_map_ + ~0u, // no _inlined_string_donated_ + PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::Duration, seconds_), + PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::Duration, nanos_), +}; +static const ::PROTOBUF_NAMESPACE_ID::internal::MigrationSchema schemas[] PROTOBUF_SECTION_VARIABLE(protodesc_cold) = { + { 0, -1, -1, sizeof(::PROTOBUF_NAMESPACE_ID::Duration)}, +}; + +static ::PROTOBUF_NAMESPACE_ID::Message const * const file_default_instances[] = { + reinterpret_cast<const ::PROTOBUF_NAMESPACE_ID::Message*>(&::PROTOBUF_NAMESPACE_ID::_Duration_default_instance_), +}; + +const char descriptor_table_protodef_google_2fprotobuf_2fduration_2eproto[] PROTOBUF_SECTION_VARIABLE(protodesc_cold) = + "\n\036google/protobuf/duration.proto\022\017google" + ".protobuf\"*\n\010Duration\022\017\n\007seconds\030\001 \001(\003\022\r" + "\n\005nanos\030\002 \001(\005B\203\001\n\023com.google.protobufB\rD" + "urationProtoP\001Z1google.golang.org/protob" + "uf/types/known/durationpb\370\001\001\242\002\003GPB\252\002\036Goo" + "gle.Protobuf.WellKnownTypesb\006proto3" + ; +static ::PROTOBUF_NAMESPACE_ID::internal::once_flag descriptor_table_google_2fprotobuf_2fduration_2eproto_once; +const ::PROTOBUF_NAMESPACE_ID::internal::DescriptorTable descriptor_table_google_2fprotobuf_2fduration_2eproto = { + false, false, 235, descriptor_table_protodef_google_2fprotobuf_2fduration_2eproto, "google/protobuf/duration.proto", + &descriptor_table_google_2fprotobuf_2fduration_2eproto_once, nullptr, 0, 1, + schemas, file_default_instances, TableStruct_google_2fprotobuf_2fduration_2eproto::offsets, + file_level_metadata_google_2fprotobuf_2fduration_2eproto, file_level_enum_descriptors_google_2fprotobuf_2fduration_2eproto, file_level_service_descriptors_google_2fprotobuf_2fduration_2eproto, +}; +PROTOBUF_ATTRIBUTE_WEAK const ::PROTOBUF_NAMESPACE_ID::internal::DescriptorTable* descriptor_table_google_2fprotobuf_2fduration_2eproto_getter() { + return &descriptor_table_google_2fprotobuf_2fduration_2eproto; +} + +// Force running AddDescriptors() at dynamic initialization time. +PROTOBUF_ATTRIBUTE_INIT_PRIORITY static ::PROTOBUF_NAMESPACE_ID::internal::AddDescriptorsRunner dynamic_init_dummy_google_2fprotobuf_2fduration_2eproto(&descriptor_table_google_2fprotobuf_2fduration_2eproto); +PROTOBUF_NAMESPACE_OPEN + +// =================================================================== + +class Duration::_Internal { + public: +}; + +Duration::Duration(::PROTOBUF_NAMESPACE_ID::Arena* arena, + bool is_message_owned) + : ::PROTOBUF_NAMESPACE_ID::Message(arena, is_message_owned) { + SharedCtor(); + if (!is_message_owned) { + RegisterArenaDtor(arena); + } + // @@protoc_insertion_point(arena_constructor:google.protobuf.Duration) +} +Duration::Duration(const Duration& from) + : ::PROTOBUF_NAMESPACE_ID::Message() { + _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_); + ::memcpy(&seconds_, &from.seconds_, + static_cast<size_t>(reinterpret_cast<char*>(&nanos_) - + reinterpret_cast<char*>(&seconds_)) + sizeof(nanos_)); + // @@protoc_insertion_point(copy_constructor:google.protobuf.Duration) +} + +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_) - + reinterpret_cast<char*>(&seconds_)) + sizeof(nanos_)); +} + +Duration::~Duration() { + // @@protoc_insertion_point(destructor:google.protobuf.Duration) + if (GetArenaForAllocation() != nullptr) return; + SharedDtor(); + _internal_metadata_.Delete<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(); +} + +inline void Duration::SharedDtor() { + GOOGLE_DCHECK(GetArenaForAllocation() == nullptr); +} + +void Duration::ArenaDtor(void* object) { + Duration* _this = reinterpret_cast< Duration* >(object); + (void)_this; +} +void Duration::RegisterArenaDtor(::PROTOBUF_NAMESPACE_ID::Arena*) { +} +void Duration::SetCachedSize(int size) const { + _cached_size_.Set(size); +} + +void Duration::Clear() { +// @@protoc_insertion_point(message_clear_start:google.protobuf.Duration) + arc_ui32 cached_has_bits = 0; + // Prevent compiler warnings about cached_has_bits being unused + (void) cached_has_bits; + + ::memset(&seconds_, 0, static_cast<size_t>( + reinterpret_cast<char*>(&nanos_) - + reinterpret_cast<char*>(&seconds_)) + sizeof(nanos_)); + _internal_metadata_.Clear<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(); +} + +const char* Duration::_InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) { +#define CHK_(x) if (PROTOBUF_PREDICT_FALSE(!(x))) goto failure + while (!ctx->Done(&ptr)) { + arc_ui32 tag; + ptr = ::PROTOBUF_NAMESPACE_ID::internal::ReadTag(ptr, &tag); + switch (tag >> 3) { + // int64 seconds = 1; + case 1: + if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 8)) { + seconds_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint64(&ptr); + CHK_(ptr); + } else + goto handle_unusual; + continue; + // int32 nanos = 2; + case 2: + if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 16)) { + nanos_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint32(&ptr); + CHK_(ptr); + } else + goto handle_unusual; + continue; + default: + goto handle_unusual; + } // switch + handle_unusual: + if ((tag == 0) || ((tag & 7) == 4)) { + CHK_(ptr); + ctx->SetLastTag(tag); + goto message_done; + } + ptr = UnknownFieldParse( + tag, + _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(), + ptr, ctx); + CHK_(ptr != nullptr); + } // while +message_done: + return ptr; +failure: + ptr = nullptr; + goto message_done; +#undef CHK_ +} + +uint8_t* Duration::_InternalSerialize( + uint8_t* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const { + // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.Duration) + arc_ui32 cached_has_bits = 0; + (void) cached_has_bits; + + // int64 seconds = 1; + if (this->_internal_seconds() != 0) { + target = stream->EnsureSpace(target); + target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteInt64ToArray(1, this->_internal_seconds(), target); + } + + // int32 nanos = 2; + if (this->_internal_nanos() != 0) { + target = stream->EnsureSpace(target); + target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteInt32ToArray(2, this->_internal_nanos(), target); + } + + if (PROTOBUF_PREDICT_FALSE(_internal_metadata_.have_unknown_fields())) { + target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::InternalSerializeUnknownFieldsToArray( + _internal_metadata_.unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(::PROTOBUF_NAMESPACE_ID::UnknownFieldSet::default_instance), target, stream); + } + // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.Duration) + return target; +} + +size_t Duration::ByteSizeLong() const { +// @@protoc_insertion_point(message_byte_size_start:google.protobuf.Duration) + size_t total_size = 0; + + arc_ui32 cached_has_bits = 0; + // Prevent compiler warnings about cached_has_bits being unused + (void) cached_has_bits; + + // int64 seconds = 1; + if (this->_internal_seconds() != 0) { + total_size += ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::Int64SizePlusOne(this->_internal_seconds()); + } + + // int32 nanos = 2; + if (this->_internal_nanos() != 0) { + total_size += ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::Int32SizePlusOne(this->_internal_nanos()); + } + + return MaybeComputeUnknownFieldsSize(total_size, &_cached_size_); +} + +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); + arc_ui32 cached_has_bits = 0; + (void) cached_has_bits; + + if (from._internal_seconds() != 0) { + _internal_set_seconds(from._internal_seconds()); + } + if (from._internal_nanos() != 0) { + _internal_set_nanos(from._internal_nanos()); + } + _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_); +} + +void Duration::CopyFrom(const Duration& from) { +// @@protoc_insertion_point(class_specific_copy_from_start:google.protobuf.Duration) + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool Duration::IsInitialized() const { + return true; +} + +void Duration::InternalSwap(Duration* other) { + using std::swap; + _internal_metadata_.InternalSwap(&other->_internal_metadata_); + ::PROTOBUF_NAMESPACE_ID::internal::memswap< + PROTOBUF_FIELD_OFFSET(Duration, nanos_) + + sizeof(Duration::nanos_) + - PROTOBUF_FIELD_OFFSET(Duration, seconds_)>( + reinterpret_cast<char*>(&seconds_), + reinterpret_cast<char*>(&other->seconds_)); +} + +::PROTOBUF_NAMESPACE_ID::Metadata Duration::GetMetadata() const { + return ::PROTOBUF_NAMESPACE_ID::internal::AssignDescriptors( + &descriptor_table_google_2fprotobuf_2fduration_2eproto_getter, &descriptor_table_google_2fprotobuf_2fduration_2eproto_once, + file_level_metadata_google_2fprotobuf_2fduration_2eproto[0]); +} + +// @@protoc_insertion_point(namespace_scope) +PROTOBUF_NAMESPACE_CLOSE +PROTOBUF_NAMESPACE_OPEN +template<> PROTOBUF_NOINLINE ::PROTOBUF_NAMESPACE_ID::Duration* Arena::CreateMaybeMessage< ::PROTOBUF_NAMESPACE_ID::Duration >(Arena* arena) { + return Arena::CreateMessageInternal< ::PROTOBUF_NAMESPACE_ID::Duration >(arena); +} +PROTOBUF_NAMESPACE_CLOSE + +// @@protoc_insertion_point(global_scope) +#include <google/protobuf/port_undef.inc> diff --git a/contrib/libs/protobuf_old/src/google/protobuf/duration.pb.h b/contrib/libs/protobuf_old/src/google/protobuf/duration.pb.h new file mode 100644 index 0000000000..a306c7c946 --- /dev/null +++ b/contrib/libs/protobuf_old/src/google/protobuf/duration.pb.h @@ -0,0 +1,285 @@ +// Generated by the protocol buffer compiler. DO NOT EDIT! +// source: google/protobuf/duration.proto + +#ifndef GOOGLE_PROTOBUF_INCLUDED_google_2fprotobuf_2fduration_2eproto +#define GOOGLE_PROTOBUF_INCLUDED_google_2fprotobuf_2fduration_2eproto + +#include <limits> +#include <string> + +#include <google/protobuf/port_def.inc> +#if PROTOBUF_VERSION < 3019000 +#error This file was generated by a newer version of protoc which is +#error incompatible with your Protocol Buffer headers. Please update +#error your headers. +#endif +#if 3019000 < PROTOBUF_MIN_PROTOC_VERSION +#error This file was generated by an older version of protoc which is +#error incompatible with your Protocol Buffer headers. Please +#error regenerate this file with a newer version of protoc. +#endif + +#include <google/protobuf/port_undef.inc> +#include <google/protobuf/io/coded_stream.h> +#include <google/protobuf/arena.h> +#include <google/protobuf/arenastring.h> +#include <google/protobuf/generated_message_table_driven.h> +#include <google/protobuf/generated_message_util.h> +#include <google/protobuf/metadata_lite.h> +#include <google/protobuf/generated_message_reflection.h> +#include <google/protobuf/message.h> +#include <google/protobuf/repeated_field.h> // IWYU pragma: export +#include <google/protobuf/extension_set.h> // IWYU pragma: export +#include <google/protobuf/unknown_field_set.h> +// @@protoc_insertion_point(includes) +#include <google/protobuf/port_def.inc> +#define PROTOBUF_INTERNAL_EXPORT_google_2fprotobuf_2fduration_2eproto PROTOBUF_EXPORT +PROTOBUF_NAMESPACE_OPEN +namespace internal { +class AnyMetadata; +} // namespace internal +PROTOBUF_NAMESPACE_CLOSE + +// Internal implementation detail -- do not use these members. +struct PROTOBUF_EXPORT TableStruct_google_2fprotobuf_2fduration_2eproto { + static const ::PROTOBUF_NAMESPACE_ID::internal::ParseTableField entries[] + PROTOBUF_SECTION_VARIABLE(protodesc_cold); + static const ::PROTOBUF_NAMESPACE_ID::internal::AuxiliaryParseTableField aux[] + PROTOBUF_SECTION_VARIABLE(protodesc_cold); + static const ::PROTOBUF_NAMESPACE_ID::internal::ParseTable schema[1] + PROTOBUF_SECTION_VARIABLE(protodesc_cold); + static const ::PROTOBUF_NAMESPACE_ID::internal::FieldMetadata field_metadata[]; + static const ::PROTOBUF_NAMESPACE_ID::internal::SerializationTable serialization_table[]; + static const arc_ui32 offsets[]; +}; +PROTOBUF_EXPORT extern const ::PROTOBUF_NAMESPACE_ID::internal::DescriptorTable descriptor_table_google_2fprotobuf_2fduration_2eproto; +PROTOBUF_NAMESPACE_OPEN +class Duration; +struct DurationDefaultTypeInternal; +PROTOBUF_EXPORT extern DurationDefaultTypeInternal _Duration_default_instance_; +PROTOBUF_NAMESPACE_CLOSE +PROTOBUF_NAMESPACE_OPEN +template<> PROTOBUF_EXPORT ::PROTOBUF_NAMESPACE_ID::Duration* Arena::CreateMaybeMessage<::PROTOBUF_NAMESPACE_ID::Duration>(Arena*); +PROTOBUF_NAMESPACE_CLOSE +PROTOBUF_NAMESPACE_OPEN + +// =================================================================== + +class PROTOBUF_EXPORT Duration final : + public ::PROTOBUF_NAMESPACE_ID::Message /* @@protoc_insertion_point(class_definition:google.protobuf.Duration) */ { + public: + inline Duration() : Duration(nullptr) {} + ~Duration() override; + explicit constexpr Duration(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized); + + Duration(const Duration& from); + Duration(Duration&& from) noexcept + : Duration() { + *this = ::std::move(from); + } + + inline Duration& operator=(const Duration& from) { + CopyFrom(from); + return *this; + } + inline Duration& operator=(Duration&& from) noexcept { + if (this == &from) return *this; + if (GetOwningArena() == from.GetOwningArena() + #ifdef PROTOBUF_FORCE_COPY_IN_MOVE + && GetOwningArena() != nullptr + #endif // !PROTOBUF_FORCE_COPY_IN_MOVE + ) { + InternalSwap(&from); + } else { + CopyFrom(from); + } + return *this; + } + + static const ::PROTOBUF_NAMESPACE_ID::Descriptor* descriptor() { + return GetDescriptor(); + } + static const ::PROTOBUF_NAMESPACE_ID::Descriptor* GetDescriptor() { + return default_instance().GetMetadata().descriptor; + } + static const ::PROTOBUF_NAMESPACE_ID::Reflection* GetReflection() { + return default_instance().GetMetadata().reflection; + } + static const Duration& default_instance() { + return *internal_default_instance(); + } + static inline const Duration* internal_default_instance() { + return reinterpret_cast<const Duration*>( + &_Duration_default_instance_); + } + static constexpr int kIndexInFileMessages = + 0; + + friend void swap(Duration& a, Duration& b) { + a.Swap(&b); + } + inline void Swap(Duration* other) { + if (other == this) return; + #ifdef PROTOBUF_FORCE_COPY_IN_SWAP + if (GetOwningArena() != nullptr && + GetOwningArena() == other->GetOwningArena()) { + #else // PROTOBUF_FORCE_COPY_IN_SWAP + if (GetOwningArena() == other->GetOwningArena()) { + #endif // !PROTOBUF_FORCE_COPY_IN_SWAP + InternalSwap(other); + } else { + ::PROTOBUF_NAMESPACE_ID::internal::GenericSwap(this, other); + } + } + void UnsafeArenaSwap(Duration* other) { + if (other == this) return; + GOOGLE_DCHECK(GetOwningArena() == other->GetOwningArena()); + InternalSwap(other); + } + + // implements Message ---------------------------------------------- + + Duration* New(::PROTOBUF_NAMESPACE_ID::Arena* arena = nullptr) const final { + return CreateMaybeMessage<Duration>(arena); + } + 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; + + size_t ByteSizeLong() const final; + const char* _InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) final; + uint8_t* _InternalSerialize( + uint8_t* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const final; + int GetCachedSize() const final { return _cached_size_.Get(); } + + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const final; + void InternalSwap(Duration* other); + + private: + friend class ::PROTOBUF_NAMESPACE_ID::internal::AnyMetadata; + static ::PROTOBUF_NAMESPACE_ID::StringPiece FullMessageName() { + return "google.protobuf.Duration"; + } + protected: + 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 ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + enum : int { + kSecondsFieldNumber = 1, + kNanosFieldNumber = 2, + }; + // int64 seconds = 1; + void clear_seconds(); + arc_i64 seconds() const; + void set_seconds(arc_i64 value); + private: + arc_i64 _internal_seconds() const; + void _internal_set_seconds(arc_i64 value); + public: + + // int32 nanos = 2; + void clear_nanos(); + arc_i32 nanos() const; + void set_nanos(arc_i32 value); + private: + arc_i32 _internal_nanos() const; + void _internal_set_nanos(arc_i32 value); + public: + + // @@protoc_insertion_point(class_scope:google.protobuf.Duration) + private: + class _Internal; + + template <typename T> friend class ::PROTOBUF_NAMESPACE_ID::Arena::InternalHelper; + typedef void InternalArenaConstructable_; + typedef void DestructorSkippable_; + arc_i64 seconds_; + arc_i32 nanos_; + mutable ::PROTOBUF_NAMESPACE_ID::internal::CachedSize _cached_size_; + friend struct ::TableStruct_google_2fprotobuf_2fduration_2eproto; +}; +// =================================================================== + + +// =================================================================== + +#ifdef __GNUC__ + #pragma GCC diagnostic push + #pragma GCC diagnostic ignored "-Wstrict-aliasing" +#endif // __GNUC__ +// Duration + +// int64 seconds = 1; +inline void Duration::clear_seconds() { + seconds_ = arc_i64{0}; +} +inline arc_i64 Duration::_internal_seconds() const { + return seconds_; +} +inline arc_i64 Duration::seconds() const { + // @@protoc_insertion_point(field_get:google.protobuf.Duration.seconds) + return _internal_seconds(); +} +inline void Duration::_internal_set_seconds(arc_i64 value) { + + seconds_ = value; +} +inline void Duration::set_seconds(arc_i64 value) { + _internal_set_seconds(value); + // @@protoc_insertion_point(field_set:google.protobuf.Duration.seconds) +} + +// int32 nanos = 2; +inline void Duration::clear_nanos() { + nanos_ = 0; +} +inline arc_i32 Duration::_internal_nanos() const { + return nanos_; +} +inline arc_i32 Duration::nanos() const { + // @@protoc_insertion_point(field_get:google.protobuf.Duration.nanos) + return _internal_nanos(); +} +inline void Duration::_internal_set_nanos(arc_i32 value) { + + nanos_ = value; +} +inline void Duration::set_nanos(arc_i32 value) { + _internal_set_nanos(value); + // @@protoc_insertion_point(field_set:google.protobuf.Duration.nanos) +} + +#ifdef __GNUC__ + #pragma GCC diagnostic pop +#endif // __GNUC__ + +// @@protoc_insertion_point(namespace_scope) + +PROTOBUF_NAMESPACE_CLOSE + +// @@protoc_insertion_point(global_scope) + +#include <google/protobuf/port_undef.inc> +#endif // GOOGLE_PROTOBUF_INCLUDED_GOOGLE_PROTOBUF_INCLUDED_google_2fprotobuf_2fduration_2eproto diff --git a/contrib/libs/protobuf_old/src/google/protobuf/duration.proto b/contrib/libs/protobuf_old/src/google/protobuf/duration.proto new file mode 100644 index 0000000000..81c3e369fd --- /dev/null +++ b/contrib/libs/protobuf_old/src/google/protobuf/duration.proto @@ -0,0 +1,116 @@ +// 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 google.protobuf; + +option csharp_namespace = "Google.Protobuf.WellKnownTypes"; +option cc_enable_arenas = true; +option go_package = "google.golang.org/protobuf/types/known/durationpb"; +option java_package = "com.google.protobuf"; +option java_outer_classname = "DurationProto"; +option java_multiple_files = true; +option objc_class_prefix = "GPB"; + +// A Duration represents a signed, fixed-length span of time represented +// as a count of seconds and fractions of seconds at nanosecond +// resolution. It is independent of any calendar and concepts like "day" +// or "month". It is related to Timestamp in that the difference between +// two Timestamp values is a Duration and it can be added or subtracted +// from a Timestamp. Range is approximately +-10,000 years. +// +// # Examples +// +// Example 1: Compute Duration from two Timestamps in pseudo code. +// +// Timestamp start = ...; +// Timestamp end = ...; +// Duration duration = ...; +// +// duration.seconds = end.seconds - start.seconds; +// duration.nanos = end.nanos - start.nanos; +// +// if (duration.seconds < 0 && duration.nanos > 0) { +// duration.seconds += 1; +// duration.nanos -= 1000000000; +// } else if (duration.seconds > 0 && duration.nanos < 0) { +// duration.seconds -= 1; +// duration.nanos += 1000000000; +// } +// +// Example 2: Compute Timestamp from Timestamp + Duration in pseudo code. +// +// Timestamp start = ...; +// Duration duration = ...; +// Timestamp end = ...; +// +// end.seconds = start.seconds + duration.seconds; +// end.nanos = start.nanos + duration.nanos; +// +// if (end.nanos < 0) { +// end.seconds -= 1; +// end.nanos += 1000000000; +// } else if (end.nanos >= 1000000000) { +// end.seconds += 1; +// end.nanos -= 1000000000; +// } +// +// Example 3: Compute Duration from datetime.timedelta in Python. +// +// td = datetime.timedelta(days=3, minutes=10) +// duration = Duration() +// duration.FromTimedelta(td) +// +// # JSON Mapping +// +// In JSON format, the Duration type is encoded as a string rather than an +// object, where the string ends in the suffix "s" (indicating seconds) and +// is preceded by the number of seconds, with nanoseconds expressed as +// fractional seconds. For example, 3 seconds with 0 nanoseconds should be +// encoded in JSON format as "3s", while 3 seconds and 1 nanosecond should +// be expressed in JSON format as "3.000000001s", and 3 seconds and 1 +// microsecond should be expressed in JSON format as "3.000001s". +// +// +message Duration { + // Signed seconds of the span of time. Must be from -315,576,000,000 + // to +315,576,000,000 inclusive. Note: these bounds are computed from: + // 60 sec/min * 60 min/hr * 24 hr/day * 365.25 days/year * 10000 years + int64 seconds = 1; + + // Signed fractions of a second at nanosecond resolution of the span + // of time. Durations less than one second are represented with a 0 + // `seconds` field and a positive or negative `nanos` field. For durations + // of one second or more, a non-zero value for the `nanos` field must be + // of the same sign as the `seconds` field. Must be from -999,999,999 + // to +999,999,999 inclusive. + int32 nanos = 2; +} diff --git a/contrib/libs/protobuf_old/src/google/protobuf/dynamic_message.cc b/contrib/libs/protobuf_old/src/google/protobuf/dynamic_message.cc new file mode 100644 index 0000000000..b68ecc8d9b --- /dev/null +++ b/contrib/libs/protobuf_old/src/google/protobuf/dynamic_message.cc @@ -0,0 +1,859 @@ +// 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: kenton@google.com (Kenton Varda) +// Based on original Protocol Buffers design by +// Sanjay Ghemawat, Jeff Dean, and others. +// +// DynamicMessage is implemented by constructing a data structure which +// has roughly the same memory layout as a generated message would have. +// Then, we use Reflection to implement our reflection interface. All +// the other operations we need to implement (e.g. parsing, copying, +// etc.) are already implemented in terms of Reflection, so the rest is +// easy. +// +// The up side of this strategy is that it's very efficient. We don't +// need to use hash_maps or generic representations of fields. The +// down side is that this is a low-level memory management hack which +// can be tricky to get right. +// +// As mentioned in the header, we only expose a DynamicMessageFactory +// publicly, not the DynamicMessage class itself. This is because +// GenericMessageReflection wants to have a pointer to a "default" +// copy of the class, with all fields initialized to their default +// values. We only want to construct one of these per message type, +// so DynamicMessageFactory stores a cache of default messages for +// each type it sees (each unique Descriptor pointer). The code +// refers to the "default" copy of the class as the "prototype". +// +// Note on memory allocation: This module often calls "operator new()" +// to allocate untyped memory, rather than calling something like +// "new uint8_t[]". This is because "operator new()" means "Give me some +// space which I can use as I please." while "new uint8_t[]" means "Give +// me an array of 8-bit integers.". In practice, the later may return +// a pointer that is not aligned correctly for general use. I believe +// Item 8 of "More Effective C++" discusses this in more detail, though +// I don't have the book on me right now so I'm not sure. + +#include <google/protobuf/dynamic_message.h> + +#include <algorithm> +#include <cstddef> +#include <memory> +#include <new> +#include <unordered_map> + +#include <google/protobuf/descriptor.pb.h> +#include <google/protobuf/descriptor.h> +#include <google/protobuf/generated_message_reflection.h> +#include <google/protobuf/generated_message_util.h> +#include <google/protobuf/unknown_field_set.h> +#include <google/protobuf/stubs/hash.h> +#include <google/protobuf/arenastring.h> +#include <google/protobuf/extension_set.h> +#include <google/protobuf/map_field.h> +#include <google/protobuf/map_field_inl.h> +#include <google/protobuf/map_type_handler.h> +#include <google/protobuf/reflection_ops.h> +#include <google/protobuf/repeated_field.h> +#include <google/protobuf/wire_format.h> + +#include <google/protobuf/port_def.inc> // NOLINT + +namespace google { +namespace protobuf { + +using internal::DynamicMapField; +using internal::ExtensionSet; +using internal::MapField; + + +using internal::ArenaStringPtr; + +// =================================================================== +// Some helper tables and functions... + +class DynamicMessageReflectionHelper { + public: + static bool IsLazyField(const Reflection* reflection, + const FieldDescriptor* field) { + return reflection->IsLazyField(field); + } +}; + +namespace { + +bool IsMapFieldInApi(const FieldDescriptor* field) { return field->is_map(); } + +// Sync with helpers.h. +inline bool HasHasbit(const FieldDescriptor* field) { + // This predicate includes proto3 message fields only if they have "optional". + // Foo submsg1 = 1; // HasHasbit() == false + // optional Foo submsg2 = 2; // HasHasbit() == true + // This is slightly odd, as adding "optional" to a singular proto3 field does + // not change the semantics or API. However whenever any field in a message + // has a hasbit, it forces reflection to include hasbit offsets for *all* + // fields, even if almost all of them are set to -1 (no hasbit). So to avoid + // causing a sudden size regression for ~all proto3 messages, we give proto3 + // message fields a hasbit only if "optional" is present. If the user is + // explicitly writing "optional", it is likely they are writing it on + // primitive fields also. + return (field->has_optional_keyword() || field->is_required()) && + !field->options().weak(); +} + +inline bool InRealOneof(const FieldDescriptor* field) { + return field->containing_oneof() && + !field->containing_oneof()->is_synthetic(); +} + +// Compute the byte size of the in-memory representation of the field. +int FieldSpaceUsed(const FieldDescriptor* field) { + typedef FieldDescriptor FD; // avoid line wrapping + if (field->label() == FD::LABEL_REPEATED) { + switch (field->cpp_type()) { + case FD::CPPTYPE_INT32: + return sizeof(RepeatedField<arc_i32>); + case FD::CPPTYPE_INT64: + return sizeof(RepeatedField<arc_i64>); + case FD::CPPTYPE_UINT32: + return sizeof(RepeatedField<arc_ui32>); + case FD::CPPTYPE_UINT64: + return sizeof(RepeatedField<arc_ui64>); + case FD::CPPTYPE_DOUBLE: + return sizeof(RepeatedField<double>); + case FD::CPPTYPE_FLOAT: + return sizeof(RepeatedField<float>); + case FD::CPPTYPE_BOOL: + return sizeof(RepeatedField<bool>); + case FD::CPPTYPE_ENUM: + return sizeof(RepeatedField<int>); + case FD::CPPTYPE_MESSAGE: + if (IsMapFieldInApi(field)) { + return sizeof(DynamicMapField); + } else { + return sizeof(RepeatedPtrField<Message>); + } + + case FD::CPPTYPE_STRING: + switch (field->options().ctype()) { + default: // TODO(kenton): Support other string reps. + case FieldOptions::STRING: + return sizeof(RepeatedPtrField<TProtoStringType>); + } + break; + } + } else { + switch (field->cpp_type()) { + case FD::CPPTYPE_INT32: + return sizeof(arc_i32); + case FD::CPPTYPE_INT64: + return sizeof(arc_i64); + case FD::CPPTYPE_UINT32: + return sizeof(arc_ui32); + case FD::CPPTYPE_UINT64: + return sizeof(arc_ui64); + case FD::CPPTYPE_DOUBLE: + return sizeof(double); + case FD::CPPTYPE_FLOAT: + return sizeof(float); + case FD::CPPTYPE_BOOL: + return sizeof(bool); + case FD::CPPTYPE_ENUM: + return sizeof(int); + + case FD::CPPTYPE_MESSAGE: + return sizeof(Message*); + + case FD::CPPTYPE_STRING: + switch (field->options().ctype()) { + default: // TODO(kenton): Support other string reps. + case FieldOptions::STRING: + return sizeof(ArenaStringPtr); + } + break; + } + } + + GOOGLE_LOG(DFATAL) << "Can't get here."; + return 0; +} + +inline int DivideRoundingUp(int i, int j) { return (i + (j - 1)) / j; } + +static const int kSafeAlignment = sizeof(arc_ui64); +static const int kMaxOneofUnionSize = sizeof(arc_ui64); + +inline int AlignTo(int offset, int alignment) { + return DivideRoundingUp(offset, alignment) * alignment; +} + +// Rounds the given byte offset up to the next offset aligned such that any +// type may be stored at it. +inline int AlignOffset(int offset) { return AlignTo(offset, kSafeAlignment); } + +#define bitsizeof(T) (sizeof(T) * 8) + +} // namespace + +// =================================================================== + +class DynamicMessage : public Message { + public: + explicit DynamicMessage(const DynamicMessageFactory::TypeInfo* type_info); + + // This should only be used by GetPrototypeNoLock() to avoid dead lock. + DynamicMessage(DynamicMessageFactory::TypeInfo* type_info, bool lock_factory); + + ~DynamicMessage(); + + // Called on the prototype after construction to initialize message fields. + // Cross linking the default instances allows for fast reflection access of + // unset message fields. Without it we would have to go to the MessageFactory + // to get the prototype, which is a much more expensive operation. + // + // Generated messages do not cross-link to avoid dynamic initialization of the + // global instances. + // Instead, they keep the default instances in the FieldDescriptor objects. + void CrossLinkPrototypes(); + + // implements Message ---------------------------------------------- + + Message* New(Arena* arena) const override; + + int GetCachedSize() const override; + void SetCachedSize(int size) const override; + + Metadata GetMetadata() const override; + +#if defined(__cpp_lib_destroying_delete) && defined(__cpp_sized_deallocation) + static void operator delete(DynamicMessage* msg, std::destroying_delete_t); +#else + // We actually allocate more memory than sizeof(*this) when this + // class's memory is allocated via the global operator new. Thus, we need to + // manually call the global operator delete. Calling the destructor is taken + // care of for us. This makes DynamicMessage compatible with -fsized-delete. + // It doesn't work for MSVC though. +#ifndef _MSC_VER + static void operator delete(void* ptr) { ::operator delete(ptr); } +#endif // !_MSC_VER +#endif + + private: + DynamicMessage(const DynamicMessageFactory::TypeInfo* type_info, + Arena* arena); + + void SharedCtor(bool lock_factory); + + // Needed to get the offset of the internal metadata member. + friend class DynamicMessageFactory; + + bool is_prototype() const; + + inline int OffsetValue(int v, FieldDescriptor::Type type) const { + if (type == FieldDescriptor::TYPE_MESSAGE) { + return v & ~0x1u; + } + return v; + } + + inline void* OffsetToPointer(int offset) { + return reinterpret_cast<uint8_t*>(this) + offset; + } + inline const void* OffsetToPointer(int offset) const { + return reinterpret_cast<const uint8_t*>(this) + offset; + } + + void* MutableRaw(int i); + void* MutableExtensionsRaw(); + void* MutableWeakFieldMapRaw(); + void* MutableOneofCaseRaw(int i); + void* MutableOneofFieldRaw(const FieldDescriptor* f); + + const DynamicMessageFactory::TypeInfo* type_info_; + mutable std::atomic<int> cached_byte_size_; + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(DynamicMessage); +}; + +struct DynamicMessageFactory::TypeInfo { + int size; + int has_bits_offset; + int oneof_case_offset; + int extensions_offset; + + // Not owned by the TypeInfo. + DynamicMessageFactory* factory; // The factory that created this object. + const DescriptorPool* pool; // The factory's DescriptorPool. + const Descriptor* type; // Type of this DynamicMessage. + + // Warning: The order in which the following pointers are defined is + // important (the prototype must be deleted *before* the offsets). + std::unique_ptr<arc_ui32[]> offsets; + std::unique_ptr<arc_ui32[]> has_bits_indices; + std::unique_ptr<const Reflection> reflection; + // Don't use a unique_ptr to hold the prototype: the destructor for + // DynamicMessage needs to know whether it is the prototype, and does so by + // looking back at this field. This would assume details about the + // implementation of unique_ptr. + const DynamicMessage* prototype; + int weak_field_map_offset; // The offset for the weak_field_map; + + TypeInfo() : prototype(nullptr) {} + + ~TypeInfo() { delete prototype; } +}; + +DynamicMessage::DynamicMessage(const DynamicMessageFactory::TypeInfo* type_info) + : type_info_(type_info), cached_byte_size_(0) { + SharedCtor(true); +} + +DynamicMessage::DynamicMessage(const DynamicMessageFactory::TypeInfo* type_info, + Arena* arena) + : Message(arena), type_info_(type_info), cached_byte_size_(0) { + SharedCtor(true); +} + +DynamicMessage::DynamicMessage(DynamicMessageFactory::TypeInfo* type_info, + bool lock_factory) + : type_info_(type_info), cached_byte_size_(0) { + // The prototype in type_info has to be set before creating the prototype + // instance on memory. e.g., message Foo { map<arc_i32, Foo> a = 1; }. When + // creating prototype for Foo, prototype of the map entry will also be + // created, which needs the address of the prototype of Foo (the value in + // map). To break the cyclic dependency, we have to assign the address of + // prototype into type_info first. + type_info->prototype = this; + SharedCtor(lock_factory); +} + +inline void* DynamicMessage::MutableRaw(int i) { + return OffsetToPointer( + OffsetValue(type_info_->offsets[i], type_info_->type->field(i)->type())); +} +void* DynamicMessage::MutableExtensionsRaw() { + return OffsetToPointer(type_info_->extensions_offset); +} +void* DynamicMessage::MutableWeakFieldMapRaw() { + return OffsetToPointer(type_info_->weak_field_map_offset); +} +void* DynamicMessage::MutableOneofCaseRaw(int i) { + return OffsetToPointer(type_info_->oneof_case_offset + sizeof(arc_ui32) * i); +} +void* DynamicMessage::MutableOneofFieldRaw(const FieldDescriptor* f) { + return OffsetToPointer( + OffsetValue(type_info_->offsets[type_info_->type->field_count() + + f->containing_oneof()->index()], + f->type())); +} + +void DynamicMessage::SharedCtor(bool lock_factory) { + // We need to call constructors for various fields manually and set + // default values where appropriate. We use placement new to call + // constructors. If you haven't heard of placement new, I suggest Googling + // it now. We use placement new even for primitive types that don't have + // constructors for consistency. (In theory, placement new should be used + // any time you are trying to convert untyped memory to typed memory, though + // in practice that's not strictly necessary for types that don't have a + // constructor.) + + const Descriptor* descriptor = type_info_->type; + // Initialize oneof cases. + int oneof_count = 0; + for (int i = 0; i < descriptor->oneof_decl_count(); ++i) { + if (descriptor->oneof_decl(i)->is_synthetic()) continue; + new (MutableOneofCaseRaw(oneof_count++)) arc_ui32{0}; + } + + if (type_info_->extensions_offset != -1) { + new (MutableExtensionsRaw()) ExtensionSet(GetArenaForAllocation()); + } + for (int i = 0; i < descriptor->field_count(); i++) { + const FieldDescriptor* field = descriptor->field(i); + void* field_ptr = MutableRaw(i); + if (InRealOneof(field)) { + continue; + } + switch (field->cpp_type()) { +#define HANDLE_TYPE(CPPTYPE, TYPE) \ + case FieldDescriptor::CPPTYPE_##CPPTYPE: \ + if (!field->is_repeated()) { \ + new (field_ptr) TYPE(field->default_value_##TYPE()); \ + } else { \ + new (field_ptr) RepeatedField<TYPE>(GetArenaForAllocation()); \ + } \ + break; + + HANDLE_TYPE(INT32, arc_i32); + HANDLE_TYPE(INT64, arc_i64); + HANDLE_TYPE(UINT32, arc_ui32); + HANDLE_TYPE(UINT64, arc_ui64); + HANDLE_TYPE(DOUBLE, double); + HANDLE_TYPE(FLOAT, float); + HANDLE_TYPE(BOOL, bool); +#undef HANDLE_TYPE + + case FieldDescriptor::CPPTYPE_ENUM: + if (!field->is_repeated()) { + new (field_ptr) int{field->default_value_enum()->number()}; + } else { + new (field_ptr) RepeatedField<int>(GetArenaForAllocation()); + } + break; + + case FieldDescriptor::CPPTYPE_STRING: + switch (field->options().ctype()) { + default: // TODO(kenton): Support other string reps. + case FieldOptions::STRING: + if (!field->is_repeated()) { + const TProtoStringType* default_value = + field->default_value_string().empty() + ? &internal::GetEmptyStringAlreadyInited() + : nullptr; + ArenaStringPtr* asp = new (field_ptr) ArenaStringPtr(); + asp->UnsafeSetDefault(default_value); + } else { + new (field_ptr) + RepeatedPtrField<TProtoStringType>(GetArenaForAllocation()); + } + break; + } + break; + + case FieldDescriptor::CPPTYPE_MESSAGE: { + if (!field->is_repeated()) { + new (field_ptr) Message*(nullptr); + } else { + if (IsMapFieldInApi(field)) { + // We need to lock in most cases to avoid data racing. Only not lock + // when the constructor is called inside GetPrototype(), in which + // case we have already locked the factory. + if (lock_factory) { + if (GetArenaForAllocation() != nullptr) { + new (field_ptr) DynamicMapField( + type_info_->factory->GetPrototype(field->message_type()), + GetArenaForAllocation()); + if (GetOwningArena() != nullptr) { + // Needs to destroy the mutex member. + GetOwningArena()->OwnDestructor( + static_cast<DynamicMapField*>(field_ptr)); + } + } else { + new (field_ptr) DynamicMapField( + type_info_->factory->GetPrototype(field->message_type())); + } + } else { + if (GetArenaForAllocation() != nullptr) { + new (field_ptr) + DynamicMapField(type_info_->factory->GetPrototypeNoLock( + field->message_type()), + GetArenaForAllocation()); + if (GetOwningArena() != nullptr) { + // Needs to destroy the mutex member. + GetOwningArena()->OwnDestructor( + static_cast<DynamicMapField*>(field_ptr)); + } + } else { + new (field_ptr) + DynamicMapField(type_info_->factory->GetPrototypeNoLock( + field->message_type())); + } + } + } else { + new (field_ptr) RepeatedPtrField<Message>(GetArenaForAllocation()); + } + } + break; + } + } + } +} + +bool DynamicMessage::is_prototype() const { + return type_info_->prototype == this || + // If type_info_->prototype is nullptr, then we must be constructing + // the prototype now, which means we must be the prototype. + type_info_->prototype == nullptr; +} + +#if defined(__cpp_lib_destroying_delete) && defined(__cpp_sized_deallocation) +void DynamicMessage::operator delete(DynamicMessage* msg, + std::destroying_delete_t) { + const size_t size = msg->type_info_->size; + msg->~DynamicMessage(); + ::operator delete(msg, size); +} +#endif + +DynamicMessage::~DynamicMessage() { + const Descriptor* descriptor = type_info_->type; + + _internal_metadata_.Delete<UnknownFieldSet>(); + + if (type_info_->extensions_offset != -1) { + reinterpret_cast<ExtensionSet*>(MutableExtensionsRaw())->~ExtensionSet(); + } + + // We need to manually run the destructors for repeated fields and strings, + // just as we ran their constructors in the DynamicMessage constructor. + // We also need to manually delete oneof fields if it is set and is string + // or message. + // Additionally, if any singular embedded messages have been allocated, we + // need to delete them, UNLESS we are the prototype message of this type, + // in which case any embedded messages are other prototypes and shouldn't + // be touched. + for (int i = 0; i < descriptor->field_count(); i++) { + const FieldDescriptor* field = descriptor->field(i); + if (InRealOneof(field)) { + void* field_ptr = MutableOneofCaseRaw(field->containing_oneof()->index()); + if (*(reinterpret_cast<const arc_i32*>(field_ptr)) == field->number()) { + field_ptr = MutableOneofFieldRaw(field); + if (field->cpp_type() == FieldDescriptor::CPPTYPE_STRING) { + switch (field->options().ctype()) { + default: + case FieldOptions::STRING: { + // Oneof string fields are never set as a default instance. + // We just need to pass some arbitrary default string to make it + // work. This allows us to not have the real default accessible + // from reflection. + const TProtoStringType* default_value = nullptr; + reinterpret_cast<ArenaStringPtr*>(field_ptr)->Destroy( + default_value, nullptr); + break; + } + } + } else if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) { + delete *reinterpret_cast<Message**>(field_ptr); + } + } + continue; + } + void* field_ptr = MutableRaw(i); + + if (field->is_repeated()) { + switch (field->cpp_type()) { +#define HANDLE_TYPE(UPPERCASE, LOWERCASE) \ + case FieldDescriptor::CPPTYPE_##UPPERCASE: \ + reinterpret_cast<RepeatedField<LOWERCASE>*>(field_ptr) \ + ->~RepeatedField<LOWERCASE>(); \ + break + + HANDLE_TYPE(INT32, arc_i32); + HANDLE_TYPE(INT64, arc_i64); + HANDLE_TYPE(UINT32, arc_ui32); + HANDLE_TYPE(UINT64, arc_ui64); + HANDLE_TYPE(DOUBLE, double); + HANDLE_TYPE(FLOAT, float); + HANDLE_TYPE(BOOL, bool); + HANDLE_TYPE(ENUM, int); +#undef HANDLE_TYPE + + case FieldDescriptor::CPPTYPE_STRING: + switch (field->options().ctype()) { + default: // TODO(kenton): Support other string reps. + case FieldOptions::STRING: + reinterpret_cast<RepeatedPtrField<TProtoStringType>*>(field_ptr) + ->~RepeatedPtrField<TProtoStringType>(); + break; + } + break; + + case FieldDescriptor::CPPTYPE_MESSAGE: + if (IsMapFieldInApi(field)) { + reinterpret_cast<DynamicMapField*>(field_ptr)->~DynamicMapField(); + } else { + reinterpret_cast<RepeatedPtrField<Message>*>(field_ptr) + ->~RepeatedPtrField<Message>(); + } + break; + } + + } else if (field->cpp_type() == FieldDescriptor::CPPTYPE_STRING) { + switch (field->options().ctype()) { + default: // TODO(kenton): Support other string reps. + case FieldOptions::STRING: { + const TProtoStringType* default_value = + reinterpret_cast<const ArenaStringPtr*>( + type_info_->prototype->OffsetToPointer( + type_info_->offsets[i])) + ->GetPointer(); + reinterpret_cast<ArenaStringPtr*>(field_ptr)->Destroy(default_value, + nullptr); + break; + } + } + } else if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) { + if (!is_prototype()) { + Message* message = *reinterpret_cast<Message**>(field_ptr); + if (message != nullptr) { + delete message; + } + } + } + } +} + +void DynamicMessage::CrossLinkPrototypes() { + // This should only be called on the prototype message. + GOOGLE_CHECK(is_prototype()); + + DynamicMessageFactory* factory = type_info_->factory; + const Descriptor* descriptor = type_info_->type; + + // Cross-link default messages. + for (int i = 0; i < descriptor->field_count(); i++) { + const FieldDescriptor* field = descriptor->field(i); + if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE && + !field->options().weak() && !InRealOneof(field) && + !field->is_repeated()) { + void* field_ptr = MutableRaw(i); + // For fields with message types, we need to cross-link with the + // prototype for the field's type. + // For singular fields, the field is just a pointer which should + // point to the prototype. + *reinterpret_cast<const Message**>(field_ptr) = + factory->GetPrototypeNoLock(field->message_type()); + } + } +} + +Message* DynamicMessage::New(Arena* arena) const { + if (arena != nullptr) { + void* new_base = Arena::CreateArray<char>(arena, type_info_->size); + memset(new_base, 0, type_info_->size); + return new (new_base) DynamicMessage(type_info_, arena); + } else { + void* new_base = operator new(type_info_->size); + memset(new_base, 0, type_info_->size); + return new (new_base) DynamicMessage(type_info_); + } +} + +int DynamicMessage::GetCachedSize() const { + return cached_byte_size_.load(std::memory_order_relaxed); +} + +void DynamicMessage::SetCachedSize(int size) const { + cached_byte_size_.store(size, std::memory_order_relaxed); +} + +Metadata DynamicMessage::GetMetadata() const { + Metadata metadata; + metadata.descriptor = type_info_->type; + metadata.reflection = type_info_->reflection.get(); + return metadata; +} + +// =================================================================== + +DynamicMessageFactory::DynamicMessageFactory() + : pool_(nullptr), delegate_to_generated_factory_(false) {} + +DynamicMessageFactory::DynamicMessageFactory(const DescriptorPool* pool) + : pool_(pool), delegate_to_generated_factory_(false) {} + +DynamicMessageFactory::~DynamicMessageFactory() { + for (auto iter = prototypes_.begin(); iter != prototypes_.end(); ++iter) { + delete iter->second; + } +} + +const Message* DynamicMessageFactory::GetPrototype(const Descriptor* type) { + MutexLock lock(&prototypes_mutex_); + return GetPrototypeNoLock(type); +} + +const Message* DynamicMessageFactory::GetPrototypeNoLock( + const Descriptor* type) { + if (delegate_to_generated_factory_ && + type->file()->pool() == DescriptorPool::generated_pool()) { + return MessageFactory::generated_factory()->GetPrototype(type); + } + + const TypeInfo** target = &prototypes_[type]; + if (*target != nullptr) { + // Already exists. + return (*target)->prototype; + } + + TypeInfo* type_info = new TypeInfo; + *target = type_info; + + type_info->type = type; + type_info->pool = (pool_ == nullptr) ? type->file()->pool() : pool_; + type_info->factory = this; + + // We need to construct all the structures passed to Reflection's constructor. + // This includes: + // - A block of memory that contains space for all the message's fields. + // - An array of integers indicating the byte offset of each field within + // this block. + // - A big bitfield containing a bit for each field indicating whether + // or not that field is set. + int real_oneof_count = 0; + for (int i = 0; i < type->oneof_decl_count(); i++) { + if (!type->oneof_decl(i)->is_synthetic()) { + real_oneof_count++; + } + } + + // Compute size and offsets. + arc_ui32* offsets = new arc_ui32[type->field_count() + real_oneof_count]; + type_info->offsets.reset(offsets); + + // Decide all field offsets by packing in order. + // We place the DynamicMessage object itself at the beginning of the allocated + // space. + int size = sizeof(DynamicMessage); + size = AlignOffset(size); + + // Next the has_bits, which is an array of uint32s. + type_info->has_bits_offset = -1; + int max_hasbit = 0; + for (int i = 0; i < type->field_count(); i++) { + if (HasHasbit(type->field(i))) { + if (type_info->has_bits_offset == -1) { + // At least one field in the message requires a hasbit, so allocate + // hasbits. + type_info->has_bits_offset = size; + arc_ui32* has_bits_indices = new arc_ui32[type->field_count()]; + for (int j = 0; j < type->field_count(); j++) { + // Initialize to -1, fields that need a hasbit will overwrite. + has_bits_indices[j] = static_cast<arc_ui32>(-1); + } + type_info->has_bits_indices.reset(has_bits_indices); + } + type_info->has_bits_indices[i] = max_hasbit++; + } + } + + if (max_hasbit > 0) { + int has_bits_array_size = DivideRoundingUp(max_hasbit, bitsizeof(arc_ui32)); + size += has_bits_array_size * sizeof(arc_ui32); + size = AlignOffset(size); + } + + // The oneof_case, if any. It is an array of uint32s. + if (real_oneof_count > 0) { + type_info->oneof_case_offset = size; + size += real_oneof_count * sizeof(arc_ui32); + size = AlignOffset(size); + } + + // The ExtensionSet, if any. + if (type->extension_range_count() > 0) { + type_info->extensions_offset = size; + size += sizeof(ExtensionSet); + size = AlignOffset(size); + } else { + // No extensions. + type_info->extensions_offset = -1; + } + + // All the fields. + // + // TODO(b/31226269): Optimize the order of fields to minimize padding. + for (int i = 0; i < type->field_count(); i++) { + // Make sure field is aligned to avoid bus errors. + // Oneof fields do not use any space. + if (!InRealOneof(type->field(i))) { + int field_size = FieldSpaceUsed(type->field(i)); + size = AlignTo(size, std::min(kSafeAlignment, field_size)); + offsets[i] = size; + size += field_size; + } + } + + // The oneofs. + for (int i = 0; i < type->oneof_decl_count(); i++) { + if (!type->oneof_decl(i)->is_synthetic()) { + size = AlignTo(size, kSafeAlignment); + offsets[type->field_count() + i] = size; + size += kMaxOneofUnionSize; + } + } + + type_info->weak_field_map_offset = -1; + + // Align the final size to make sure no clever allocators think that + // alignment is not necessary. + type_info->size = size; + + // Construct the reflection object. + + // Compute the size of default oneof instance and offsets of default + // oneof fields. + for (int i = 0; i < type->oneof_decl_count(); i++) { + if (type->oneof_decl(i)->is_synthetic()) continue; + for (int j = 0; j < type->oneof_decl(i)->field_count(); j++) { + const FieldDescriptor* field = type->oneof_decl(i)->field(j); + // oneof fields are not accessed through offsets, but we still have the + // entry from a legacy implementation. This should be removed at some + // point. + // Mark the field to prevent unintentional access through reflection. + // Don't use the top bit because that is for unused fields. + offsets[field->index()] = internal::kInvalidFieldOffsetTag; + } + } + + // Allocate the prototype fields. + void* base = operator new(size); + memset(base, 0, size); + + // We have already locked the factory so we should not lock in the constructor + // of dynamic message to avoid dead lock. + DynamicMessage* prototype = new (base) DynamicMessage(type_info, false); + + internal::ReflectionSchema schema = { + type_info->prototype, + type_info->offsets.get(), + type_info->has_bits_indices.get(), + type_info->has_bits_offset, + PROTOBUF_FIELD_OFFSET(DynamicMessage, _internal_metadata_), + type_info->extensions_offset, + type_info->oneof_case_offset, + type_info->size, + type_info->weak_field_map_offset, + nullptr /* inlined_string_indices_ */, + 0 /* inlined_string_donated_offset_ */}; + + type_info->reflection.reset( + new Reflection(type_info->type, schema, type_info->pool, this)); + + // Cross link prototypes. + prototype->CrossLinkPrototypes(); + + return prototype; +} + +} // namespace protobuf +} // namespace google + +#include <google/protobuf/port_undef.inc> // NOLINT diff --git a/contrib/libs/protobuf_old/src/google/protobuf/dynamic_message.h b/contrib/libs/protobuf_old/src/google/protobuf/dynamic_message.h new file mode 100644 index 0000000000..fa188aaf87 --- /dev/null +++ b/contrib/libs/protobuf_old/src/google/protobuf/dynamic_message.h @@ -0,0 +1,225 @@ +// 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: kenton@google.com (Kenton Varda) +// Based on original Protocol Buffers design by +// Sanjay Ghemawat, Jeff Dean, and others. +// +// Defines an implementation of Message which can emulate types which are not +// known at compile-time. + +#ifndef GOOGLE_PROTOBUF_DYNAMIC_MESSAGE_H__ +#define GOOGLE_PROTOBUF_DYNAMIC_MESSAGE_H__ + +#include <algorithm> +#include <memory> +#include <unordered_map> +#include <vector> + +#include <google/protobuf/stubs/common.h> +#include <google/protobuf/message.h> +#include <google/protobuf/stubs/mutex.h> +#include <google/protobuf/reflection.h> +#include <google/protobuf/repeated_field.h> + +#ifdef SWIG +#error "You cannot SWIG proto headers" +#endif + +#include <google/protobuf/port_def.inc> + +namespace google { +namespace protobuf { + +// Defined in other files. +class Descriptor; // descriptor.h +class DescriptorPool; // descriptor.h + +// Constructs implementations of Message which can emulate types which are not +// known at compile-time. +// +// Sometimes you want to be able to manipulate protocol types that you don't +// know about at compile time. It would be nice to be able to construct +// a Message object which implements the message type given by any arbitrary +// Descriptor. DynamicMessage provides this. +// +// As it turns out, a DynamicMessage needs to construct extra +// information about its type in order to operate. Most of this information +// can be shared between all DynamicMessages of the same type. But, caching +// this information in some sort of global map would be a bad idea, since +// the cached information for a particular descriptor could outlive the +// descriptor itself. To avoid this problem, DynamicMessageFactory +// encapsulates this "cache". All DynamicMessages of the same type created +// from the same factory will share the same support data. Any Descriptors +// used with a particular factory must outlive the factory. +class PROTOBUF_EXPORT DynamicMessageFactory : public MessageFactory { + public: + // Construct a DynamicMessageFactory that will search for extensions in + // the DescriptorPool in which the extendee is defined. + DynamicMessageFactory(); + + // Construct a DynamicMessageFactory that will search for extensions in + // the given DescriptorPool. + // + // DEPRECATED: Use CodedInputStream::SetExtensionRegistry() to tell the + // parser to look for extensions in an alternate pool. However, note that + // this is almost never what you want to do. Almost all users should use + // the zero-arg constructor. + DynamicMessageFactory(const DescriptorPool* pool); + + ~DynamicMessageFactory(); + + // Call this to tell the DynamicMessageFactory that if it is given a + // Descriptor d for which: + // d->file()->pool() == DescriptorPool::generated_pool(), + // then it should delegate to MessageFactory::generated_factory() instead + // of constructing a dynamic implementation of the message. In theory there + // is no down side to doing this, so it may become the default in the future. + void SetDelegateToGeneratedFactory(bool enable) { + delegate_to_generated_factory_ = enable; + } + + // implements MessageFactory --------------------------------------- + + // Given a Descriptor, constructs the default (prototype) Message of that + // type. You can then call that message's New() method to construct a + // mutable message of that type. + // + // Calling this method twice with the same Descriptor returns the same + // object. The returned object remains property of the factory and will + // be destroyed when the factory is destroyed. Also, any objects created + // by calling the prototype's New() method share some data with the + // prototype, so these must be destroyed before the DynamicMessageFactory + // is destroyed. + // + // The given descriptor must outlive the returned message, and hence must + // outlive the DynamicMessageFactory. + // + // The method is thread-safe. + const Message* GetPrototype(const Descriptor* type) override; + + private: + const DescriptorPool* pool_; + bool delegate_to_generated_factory_; + + struct TypeInfo; + std::unordered_map<const Descriptor*, const TypeInfo*> prototypes_; + mutable internal::WrappedMutex prototypes_mutex_; + + friend class DynamicMessage; + const Message* GetPrototypeNoLock(const Descriptor* type); + + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(DynamicMessageFactory); +}; + +// Helper for computing a sorted list of map entries via reflection. +class PROTOBUF_EXPORT DynamicMapSorter { + public: + static std::vector<const Message*> Sort(const Message& message, int map_size, + const Reflection* reflection, + const FieldDescriptor* field) { + std::vector<const Message*> result; + result.reserve(map_size); + RepeatedFieldRef<Message> map_field = + reflection->GetRepeatedFieldRef<Message>(message, field); + for (auto it = map_field.begin(); it != map_field.end(); ++it) { + result.push_back(&*it); + } + MapEntryMessageComparator comparator(field->message_type()); + std::stable_sort(result.begin(), result.end(), comparator); + // Complain if the keys aren't in ascending order. +#ifndef NDEBUG + for (size_t j = 1; j < static_cast<size_t>(map_size); j++) { + if (!comparator(result[j - 1], result[j])) { + GOOGLE_LOG(ERROR) << (comparator(result[j], result[j - 1]) + ? "internal error in map key sorting" + : "map keys are not unique"); + } + } +#endif + return result; + } + + private: + class PROTOBUF_EXPORT MapEntryMessageComparator { + public: + explicit MapEntryMessageComparator(const Descriptor* descriptor) + : field_(descriptor->field(0)) {} + + bool operator()(const Message* a, const Message* b) { + const Reflection* reflection = a->GetReflection(); + switch (field_->cpp_type()) { + case FieldDescriptor::CPPTYPE_BOOL: { + bool first = reflection->GetBool(*a, field_); + bool second = reflection->GetBool(*b, field_); + return first < second; + } + case FieldDescriptor::CPPTYPE_INT32: { + arc_i32 first = reflection->GetInt32(*a, field_); + arc_i32 second = reflection->GetInt32(*b, field_); + return first < second; + } + case FieldDescriptor::CPPTYPE_INT64: { + arc_i64 first = reflection->GetInt64(*a, field_); + arc_i64 second = reflection->GetInt64(*b, field_); + return first < second; + } + case FieldDescriptor::CPPTYPE_UINT32: { + arc_ui32 first = reflection->GetUInt32(*a, field_); + arc_ui32 second = reflection->GetUInt32(*b, field_); + return first < second; + } + case FieldDescriptor::CPPTYPE_UINT64: { + arc_ui64 first = reflection->GetUInt64(*a, field_); + arc_ui64 second = reflection->GetUInt64(*b, field_); + return first < second; + } + case FieldDescriptor::CPPTYPE_STRING: { + TProtoStringType first = reflection->GetString(*a, field_); + TProtoStringType second = reflection->GetString(*b, field_); + return first < second; + } + default: + GOOGLE_LOG(DFATAL) << "Invalid key for map field."; + return true; + } + } + + private: + const FieldDescriptor* field_; + }; +}; + +} // namespace protobuf +} // namespace google + +#include <google/protobuf/port_undef.inc> + +#endif // GOOGLE_PROTOBUF_DYNAMIC_MESSAGE_H__ diff --git a/contrib/libs/protobuf_old/src/google/protobuf/empty.pb.cc b/contrib/libs/protobuf_old/src/google/protobuf/empty.pb.cc new file mode 100644 index 0000000000..841e143a1d --- /dev/null +++ b/contrib/libs/protobuf_old/src/google/protobuf/empty.pb.cc @@ -0,0 +1,122 @@ +// Generated by the protocol buffer compiler. DO NOT EDIT! +// source: google/protobuf/empty.proto + +#include <google/protobuf/empty.pb.h> + +#include <algorithm> + +#include <google/protobuf/io/coded_stream.h> +#include <google/protobuf/extension_set.h> +#include <google/protobuf/wire_format_lite.h> +#include <google/protobuf/descriptor.h> +#include <google/protobuf/generated_message_reflection.h> +#include <google/protobuf/reflection_ops.h> +#include <google/protobuf/wire_format.h> +// @@protoc_insertion_point(includes) +#include <google/protobuf/port_def.inc> + +PROTOBUF_PRAGMA_INIT_SEG +PROTOBUF_NAMESPACE_OPEN +constexpr Empty::Empty( + ::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized){} +struct EmptyDefaultTypeInternal { + constexpr EmptyDefaultTypeInternal() + : _instance(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized{}) {} + ~EmptyDefaultTypeInternal() {} + union { + Empty _instance; + }; +}; +PROTOBUF_ATTRIBUTE_NO_DESTROY PROTOBUF_CONSTINIT EmptyDefaultTypeInternal _Empty_default_instance_; +PROTOBUF_NAMESPACE_CLOSE +static ::PROTOBUF_NAMESPACE_ID::Metadata file_level_metadata_google_2fprotobuf_2fempty_2eproto[1]; +static constexpr ::PROTOBUF_NAMESPACE_ID::EnumDescriptor const** file_level_enum_descriptors_google_2fprotobuf_2fempty_2eproto = nullptr; +static constexpr ::PROTOBUF_NAMESPACE_ID::ServiceDescriptor const** file_level_service_descriptors_google_2fprotobuf_2fempty_2eproto = nullptr; + +const arc_ui32 TableStruct_google_2fprotobuf_2fempty_2eproto::offsets[] PROTOBUF_SECTION_VARIABLE(protodesc_cold) = { + ~0u, // no _has_bits_ + PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::Empty, _internal_metadata_), + ~0u, // no _extensions_ + ~0u, // no _oneof_case_ + ~0u, // no _weak_field_map_ + ~0u, // no _inlined_string_donated_ +}; +static const ::PROTOBUF_NAMESPACE_ID::internal::MigrationSchema schemas[] PROTOBUF_SECTION_VARIABLE(protodesc_cold) = { + { 0, -1, -1, sizeof(::PROTOBUF_NAMESPACE_ID::Empty)}, +}; + +static ::PROTOBUF_NAMESPACE_ID::Message const * const file_default_instances[] = { + reinterpret_cast<const ::PROTOBUF_NAMESPACE_ID::Message*>(&::PROTOBUF_NAMESPACE_ID::_Empty_default_instance_), +}; + +const char descriptor_table_protodef_google_2fprotobuf_2fempty_2eproto[] PROTOBUF_SECTION_VARIABLE(protodesc_cold) = + "\n\033google/protobuf/empty.proto\022\017google.pr" + "otobuf\"\007\n\005EmptyB}\n\023com.google.protobufB\n" + "EmptyProtoP\001Z.google.golang.org/protobuf" + "/types/known/emptypb\370\001\001\242\002\003GPB\252\002\036Google.P" + "rotobuf.WellKnownTypesb\006proto3" + ; +static ::PROTOBUF_NAMESPACE_ID::internal::once_flag descriptor_table_google_2fprotobuf_2fempty_2eproto_once; +const ::PROTOBUF_NAMESPACE_ID::internal::DescriptorTable descriptor_table_google_2fprotobuf_2fempty_2eproto = { + false, false, 190, descriptor_table_protodef_google_2fprotobuf_2fempty_2eproto, "google/protobuf/empty.proto", + &descriptor_table_google_2fprotobuf_2fempty_2eproto_once, nullptr, 0, 1, + schemas, file_default_instances, TableStruct_google_2fprotobuf_2fempty_2eproto::offsets, + file_level_metadata_google_2fprotobuf_2fempty_2eproto, file_level_enum_descriptors_google_2fprotobuf_2fempty_2eproto, file_level_service_descriptors_google_2fprotobuf_2fempty_2eproto, +}; +PROTOBUF_ATTRIBUTE_WEAK const ::PROTOBUF_NAMESPACE_ID::internal::DescriptorTable* descriptor_table_google_2fprotobuf_2fempty_2eproto_getter() { + return &descriptor_table_google_2fprotobuf_2fempty_2eproto; +} + +// Force running AddDescriptors() at dynamic initialization time. +PROTOBUF_ATTRIBUTE_INIT_PRIORITY static ::PROTOBUF_NAMESPACE_ID::internal::AddDescriptorsRunner dynamic_init_dummy_google_2fprotobuf_2fempty_2eproto(&descriptor_table_google_2fprotobuf_2fempty_2eproto); +PROTOBUF_NAMESPACE_OPEN + +// =================================================================== + +class Empty::_Internal { + public: +}; + +Empty::Empty(::PROTOBUF_NAMESPACE_ID::Arena* arena, + bool is_message_owned) + : ::PROTOBUF_NAMESPACE_ID::internal::ZeroFieldsBase(arena, is_message_owned) { + // @@protoc_insertion_point(arena_constructor:google.protobuf.Empty) +} +Empty::Empty(const Empty& from) + : ::PROTOBUF_NAMESPACE_ID::internal::ZeroFieldsBase() { + _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_); + // @@protoc_insertion_point(copy_constructor:google.protobuf.Empty) +} + + + + + +const ::PROTOBUF_NAMESPACE_ID::Message::ClassData Empty::_class_data_ = { + ::PROTOBUF_NAMESPACE_ID::internal::ZeroFieldsBase::CopyImpl, + ::PROTOBUF_NAMESPACE_ID::internal::ZeroFieldsBase::MergeImpl, +}; +const ::PROTOBUF_NAMESPACE_ID::Message::ClassData*Empty::GetClassData() const { return &_class_data_; } + + + + + + + +::PROTOBUF_NAMESPACE_ID::Metadata Empty::GetMetadata() const { + return ::PROTOBUF_NAMESPACE_ID::internal::AssignDescriptors( + &descriptor_table_google_2fprotobuf_2fempty_2eproto_getter, &descriptor_table_google_2fprotobuf_2fempty_2eproto_once, + file_level_metadata_google_2fprotobuf_2fempty_2eproto[0]); +} + +// @@protoc_insertion_point(namespace_scope) +PROTOBUF_NAMESPACE_CLOSE +PROTOBUF_NAMESPACE_OPEN +template<> PROTOBUF_NOINLINE ::PROTOBUF_NAMESPACE_ID::Empty* Arena::CreateMaybeMessage< ::PROTOBUF_NAMESPACE_ID::Empty >(Arena* arena) { + return Arena::CreateMessageInternal< ::PROTOBUF_NAMESPACE_ID::Empty >(arena); +} +PROTOBUF_NAMESPACE_CLOSE + +// @@protoc_insertion_point(global_scope) +#include <google/protobuf/port_undef.inc> diff --git a/contrib/libs/protobuf_old/src/google/protobuf/empty.pb.h b/contrib/libs/protobuf_old/src/google/protobuf/empty.pb.h new file mode 100644 index 0000000000..5e81d7e9ef --- /dev/null +++ b/contrib/libs/protobuf_old/src/google/protobuf/empty.pb.h @@ -0,0 +1,207 @@ +// Generated by the protocol buffer compiler. DO NOT EDIT! +// source: google/protobuf/empty.proto + +#ifndef GOOGLE_PROTOBUF_INCLUDED_google_2fprotobuf_2fempty_2eproto +#define GOOGLE_PROTOBUF_INCLUDED_google_2fprotobuf_2fempty_2eproto + +#include <limits> +#include <string> + +#include <google/protobuf/port_def.inc> +#if PROTOBUF_VERSION < 3019000 +#error This file was generated by a newer version of protoc which is +#error incompatible with your Protocol Buffer headers. Please update +#error your headers. +#endif +#if 3019000 < PROTOBUF_MIN_PROTOC_VERSION +#error This file was generated by an older version of protoc which is +#error incompatible with your Protocol Buffer headers. Please +#error regenerate this file with a newer version of protoc. +#endif + +#include <google/protobuf/port_undef.inc> +#include <google/protobuf/io/coded_stream.h> +#include <google/protobuf/arena.h> +#include <google/protobuf/arenastring.h> +#include <google/protobuf/generated_message_bases.h> +#include <google/protobuf/generated_message_table_driven.h> +#include <google/protobuf/generated_message_util.h> +#include <google/protobuf/metadata_lite.h> +#include <google/protobuf/generated_message_reflection.h> +#include <google/protobuf/message.h> +#include <google/protobuf/repeated_field.h> // IWYU pragma: export +#include <google/protobuf/extension_set.h> // IWYU pragma: export +#include <google/protobuf/unknown_field_set.h> +// @@protoc_insertion_point(includes) +#include <google/protobuf/port_def.inc> +#define PROTOBUF_INTERNAL_EXPORT_google_2fprotobuf_2fempty_2eproto PROTOBUF_EXPORT +PROTOBUF_NAMESPACE_OPEN +namespace internal { +class AnyMetadata; +} // namespace internal +PROTOBUF_NAMESPACE_CLOSE + +// Internal implementation detail -- do not use these members. +struct PROTOBUF_EXPORT TableStruct_google_2fprotobuf_2fempty_2eproto { + static const ::PROTOBUF_NAMESPACE_ID::internal::ParseTableField entries[] + PROTOBUF_SECTION_VARIABLE(protodesc_cold); + static const ::PROTOBUF_NAMESPACE_ID::internal::AuxiliaryParseTableField aux[] + PROTOBUF_SECTION_VARIABLE(protodesc_cold); + static const ::PROTOBUF_NAMESPACE_ID::internal::ParseTable schema[1] + PROTOBUF_SECTION_VARIABLE(protodesc_cold); + static const ::PROTOBUF_NAMESPACE_ID::internal::FieldMetadata field_metadata[]; + static const ::PROTOBUF_NAMESPACE_ID::internal::SerializationTable serialization_table[]; + static const arc_ui32 offsets[]; +}; +PROTOBUF_EXPORT extern const ::PROTOBUF_NAMESPACE_ID::internal::DescriptorTable descriptor_table_google_2fprotobuf_2fempty_2eproto; +PROTOBUF_NAMESPACE_OPEN +class Empty; +struct EmptyDefaultTypeInternal; +PROTOBUF_EXPORT extern EmptyDefaultTypeInternal _Empty_default_instance_; +PROTOBUF_NAMESPACE_CLOSE +PROTOBUF_NAMESPACE_OPEN +template<> PROTOBUF_EXPORT ::PROTOBUF_NAMESPACE_ID::Empty* Arena::CreateMaybeMessage<::PROTOBUF_NAMESPACE_ID::Empty>(Arena*); +PROTOBUF_NAMESPACE_CLOSE +PROTOBUF_NAMESPACE_OPEN + +// =================================================================== + +class PROTOBUF_EXPORT Empty final : + public ::PROTOBUF_NAMESPACE_ID::internal::ZeroFieldsBase /* @@protoc_insertion_point(class_definition:google.protobuf.Empty) */ { + public: + inline Empty() : Empty(nullptr) {} + explicit constexpr Empty(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized); + + Empty(const Empty& from); + Empty(Empty&& from) noexcept + : Empty() { + *this = ::std::move(from); + } + + inline Empty& operator=(const Empty& from) { + CopyFrom(from); + return *this; + } + inline Empty& operator=(Empty&& from) noexcept { + if (this == &from) return *this; + if (GetOwningArena() == from.GetOwningArena() + #ifdef PROTOBUF_FORCE_COPY_IN_MOVE + && GetOwningArena() != nullptr + #endif // !PROTOBUF_FORCE_COPY_IN_MOVE + ) { + InternalSwap(&from); + } else { + CopyFrom(from); + } + return *this; + } + + static const ::PROTOBUF_NAMESPACE_ID::Descriptor* descriptor() { + return GetDescriptor(); + } + static const ::PROTOBUF_NAMESPACE_ID::Descriptor* GetDescriptor() { + return default_instance().GetMetadata().descriptor; + } + static const ::PROTOBUF_NAMESPACE_ID::Reflection* GetReflection() { + return default_instance().GetMetadata().reflection; + } + static const Empty& default_instance() { + return *internal_default_instance(); + } + static inline const Empty* internal_default_instance() { + return reinterpret_cast<const Empty*>( + &_Empty_default_instance_); + } + static constexpr int kIndexInFileMessages = + 0; + + friend void swap(Empty& a, Empty& b) { + a.Swap(&b); + } + inline void Swap(Empty* other) { + if (other == this) return; + #ifdef PROTOBUF_FORCE_COPY_IN_SWAP + if (GetOwningArena() != nullptr && + GetOwningArena() == other->GetOwningArena()) { + #else // PROTOBUF_FORCE_COPY_IN_SWAP + if (GetOwningArena() == other->GetOwningArena()) { + #endif // !PROTOBUF_FORCE_COPY_IN_SWAP + InternalSwap(other); + } else { + ::PROTOBUF_NAMESPACE_ID::internal::GenericSwap(this, other); + } + } + void UnsafeArenaSwap(Empty* other) { + if (other == this) return; + GOOGLE_DCHECK(GetOwningArena() == other->GetOwningArena()); + InternalSwap(other); + } + + // implements Message ---------------------------------------------- + + Empty* New(::PROTOBUF_NAMESPACE_ID::Arena* arena = nullptr) const final { + return CreateMaybeMessage<Empty>(arena); + } + using ::PROTOBUF_NAMESPACE_ID::internal::ZeroFieldsBase::CopyFrom; + inline void CopyFrom(const Empty& from) { + ::PROTOBUF_NAMESPACE_ID::internal::ZeroFieldsBase::CopyImpl(this, from); + } + using ::PROTOBUF_NAMESPACE_ID::internal::ZeroFieldsBase::MergeFrom; + void MergeFrom(const Empty& from) { + ::PROTOBUF_NAMESPACE_ID::internal::ZeroFieldsBase::MergeImpl(this, from); + } + public: + + private: + friend class ::PROTOBUF_NAMESPACE_ID::internal::AnyMetadata; + static ::PROTOBUF_NAMESPACE_ID::StringPiece FullMessageName() { + return "google.protobuf.Empty"; + } + protected: + explicit Empty(::PROTOBUF_NAMESPACE_ID::Arena* arena, + bool is_message_owned = false); + private: + public: + + static const ClassData _class_data_; + const ::PROTOBUF_NAMESPACE_ID::Message::ClassData*GetClassData() const final; + + ::PROTOBUF_NAMESPACE_ID::Metadata GetMetadata() const final; + + // nested types ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + // @@protoc_insertion_point(class_scope:google.protobuf.Empty) + private: + class _Internal; + + template <typename T> friend class ::PROTOBUF_NAMESPACE_ID::Arena::InternalHelper; + typedef void InternalArenaConstructable_; + typedef void DestructorSkippable_; + mutable ::PROTOBUF_NAMESPACE_ID::internal::CachedSize _cached_size_; + friend struct ::TableStruct_google_2fprotobuf_2fempty_2eproto; +}; +// =================================================================== + + +// =================================================================== + +#ifdef __GNUC__ + #pragma GCC diagnostic push + #pragma GCC diagnostic ignored "-Wstrict-aliasing" +#endif // __GNUC__ +// Empty + +#ifdef __GNUC__ + #pragma GCC diagnostic pop +#endif // __GNUC__ + +// @@protoc_insertion_point(namespace_scope) + +PROTOBUF_NAMESPACE_CLOSE + +// @@protoc_insertion_point(global_scope) + +#include <google/protobuf/port_undef.inc> +#endif // GOOGLE_PROTOBUF_INCLUDED_GOOGLE_PROTOBUF_INCLUDED_google_2fprotobuf_2fempty_2eproto diff --git a/contrib/libs/protobuf_old/src/google/protobuf/empty.proto b/contrib/libs/protobuf_old/src/google/protobuf/empty.proto new file mode 100644 index 0000000000..5f992de94a --- /dev/null +++ b/contrib/libs/protobuf_old/src/google/protobuf/empty.proto @@ -0,0 +1,52 @@ +// 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 google.protobuf; + +option csharp_namespace = "Google.Protobuf.WellKnownTypes"; +option go_package = "google.golang.org/protobuf/types/known/emptypb"; +option java_package = "com.google.protobuf"; +option java_outer_classname = "EmptyProto"; +option java_multiple_files = true; +option objc_class_prefix = "GPB"; +option cc_enable_arenas = true; + +// A generic empty message that you can re-use to avoid defining duplicated +// empty messages in your APIs. A typical example is to use it as the request +// or the response type of an API method. For instance: +// +// service Foo { +// rpc Bar(google.protobuf.Empty) returns (google.protobuf.Empty); +// } +// +// The JSON representation for `Empty` is empty JSON object `{}`. +message Empty {} diff --git a/contrib/libs/protobuf_old/src/google/protobuf/explicitly_constructed.h b/contrib/libs/protobuf_old/src/google/protobuf/explicitly_constructed.h new file mode 100644 index 0000000000..69de60f76d --- /dev/null +++ b/contrib/libs/protobuf_old/src/google/protobuf/explicitly_constructed.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. + +#ifndef GOOGLE_PROTOBUF_EXPLICITLY_CONSTRUCTED_H__ +#define GOOGLE_PROTOBUF_EXPLICITLY_CONSTRUCTED_H__ + +#include <stdint.h> + +#include <utility> + +#include <google/protobuf/stubs/logging.h> +#include <google/protobuf/stubs/common.h> + +// clang-format off +#include <google/protobuf/port_def.inc> +// clang-format on + +namespace google { +namespace protobuf { +namespace internal { + +// Wraps a variable whose constructor and destructor are explicitly +// called. It is particularly useful for a global variable, without its +// constructor and destructor run on start and end of the program lifetime. +// This circumvents the initial construction order fiasco, while keeping +// the address of the empty string a compile time constant. +// +// Pay special attention to the initialization state of the object. +// 1. The object is "uninitialized" to begin with. +// 2. Call Construct() or DefaultConstruct() only if the object is +// uninitialized. After the call, the object becomes "initialized". +// 3. Call get() and get_mutable() only if the object is initialized. +// 4. Call Destruct() only if the object is initialized. +// After the call, the object becomes uninitialized. +template <typename T> +class ExplicitlyConstructed { + public: + void DefaultConstruct() { new (&union_) T(); } + + template <typename... Args> + void Construct(Args&&... args) { + new (&union_) T(std::forward<Args>(args)...); + } + + void Destruct() { get_mutable()->~T(); } + + constexpr const T& get() const { return reinterpret_cast<const T&>(union_); } + T* get_mutable() { return reinterpret_cast<T*>(&union_); } + + private: + union AlignedUnion { + alignas(T) char space[sizeof(T)]; + arc_i64 align_to_int64; + void* align_to_ptr; + } union_; +}; + +} // namespace internal +} // namespace protobuf +} // namespace google + +#include <google/protobuf/port_undef.inc> + +#endif // GOOGLE_PROTOBUF_EXPLICITLY_CONSTRUCTED_H__ diff --git a/contrib/libs/protobuf_old/src/google/protobuf/extension_set.cc b/contrib/libs/protobuf_old/src/google/protobuf/extension_set.cc new file mode 100644 index 0000000000..af851b2a45 --- /dev/null +++ b/contrib/libs/protobuf_old/src/google/protobuf/extension_set.cc @@ -0,0 +1,2255 @@ +// 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: kenton@google.com (Kenton Varda) +// Based on original Protocol Buffers design by +// Sanjay Ghemawat, Jeff Dean, and others. + +#include <google/protobuf/extension_set.h> + +#include <tuple> +#include <unordered_set> +#include <utility> + +#include <google/protobuf/stubs/common.h> +#include <google/protobuf/extension_set_inl.h> +#include <google/protobuf/parse_context.h> +#include <google/protobuf/io/coded_stream.h> +#include <google/protobuf/io/zero_copy_stream_impl_lite.h> +#include <google/protobuf/arena.h> +#include <google/protobuf/message_lite.h> +#include <google/protobuf/metadata_lite.h> +#include <google/protobuf/repeated_field.h> +#include <google/protobuf/stubs/map_util.h> +#include <google/protobuf/stubs/hash.h> + +// clang-format off +#include <google/protobuf/port_def.inc> // must be last. +// clang-format on +namespace google { +namespace protobuf { +namespace internal { + +namespace { + +inline WireFormatLite::FieldType real_type(FieldType type) { + GOOGLE_DCHECK(type > 0 && type <= WireFormatLite::MAX_FIELD_TYPE); + return static_cast<WireFormatLite::FieldType>(type); +} + +inline WireFormatLite::CppType cpp_type(FieldType type) { + return WireFormatLite::FieldTypeToCppType(real_type(type)); +} + +inline bool is_packable(WireFormatLite::WireType type) { + switch (type) { + case WireFormatLite::WIRETYPE_VARINT: + case WireFormatLite::WIRETYPE_FIXED64: + case WireFormatLite::WIRETYPE_FIXED32: + return true; + case WireFormatLite::WIRETYPE_LENGTH_DELIMITED: + case WireFormatLite::WIRETYPE_START_GROUP: + case WireFormatLite::WIRETYPE_END_GROUP: + return false; + + // Do not add a default statement. Let the compiler complain when someone + // adds a new wire type. + } + GOOGLE_LOG(FATAL) << "can't reach here."; + return false; +} + +// Registry stuff. + +// Note that we cannot use hetererogeneous lookup for std containers since we +// need to support C++11. +struct ExtensionEq { + bool operator()(const ExtensionInfo& lhs, const ExtensionInfo& rhs) const { + return lhs.message == rhs.message && lhs.number == rhs.number; + } +}; + +struct ExtensionHasher { + std::size_t operator()(const ExtensionInfo& info) const { + return std::hash<const MessageLite*>{}(info.message) ^ + std::hash<int>{}(info.number); + } +}; + +using ExtensionRegistry = + std::unordered_set<ExtensionInfo, ExtensionHasher, ExtensionEq>; + +static const ExtensionRegistry* global_registry = nullptr; + +// This function is only called at startup, so there is no need for thread- +// safety. +void Register(const ExtensionInfo& info) { + static auto local_static_registry = OnShutdownDelete(new ExtensionRegistry); + global_registry = local_static_registry; + if (!InsertIfNotPresent(local_static_registry, info)) { + GOOGLE_LOG(FATAL) << "Multiple extension registrations for type \"" + << info.message->GetTypeName() << "\", field number " + << info.number << "."; + } +} + +const ExtensionInfo* FindRegisteredExtension(const MessageLite* extendee, + int number) { + if (!global_registry) return nullptr; + + ExtensionInfo info; + info.message = extendee; + info.number = number; + + auto it = global_registry->find(info); + if (it == global_registry->end()) { + return nullptr; + } else { + return &*it; + } +} + +} // namespace + +ExtensionFinder::~ExtensionFinder() {} + +bool GeneratedExtensionFinder::Find(int number, ExtensionInfo* output) { + const ExtensionInfo* extension = FindRegisteredExtension(extendee_, number); + if (extension == nullptr) { + return false; + } else { + *output = *extension; + return true; + } +} + +void ExtensionSet::RegisterExtension(const MessageLite* extendee, int number, + FieldType type, bool is_repeated, + bool is_packed) { + GOOGLE_CHECK_NE(type, WireFormatLite::TYPE_ENUM); + GOOGLE_CHECK_NE(type, WireFormatLite::TYPE_MESSAGE); + GOOGLE_CHECK_NE(type, WireFormatLite::TYPE_GROUP); + ExtensionInfo info(extendee, number, type, is_repeated, is_packed); + Register(info); +} + +static bool CallNoArgValidityFunc(const void* arg, int number) { + // Note: Must use C-style cast here rather than reinterpret_cast because + // the C++ standard at one point did not allow casts between function and + // data pointers and some compilers enforce this for C++-style casts. No + // compiler enforces it for C-style casts since lots of C-style code has + // relied on these kinds of casts for a long time, despite being + // technically undefined. See: + // http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#195 + // Also note: Some compilers do not allow function pointers to be "const". + // Which makes sense, I suppose, because it's meaningless. + return ((EnumValidityFunc*)arg)(number); +} + +void ExtensionSet::RegisterEnumExtension(const MessageLite* extendee, + int number, FieldType type, + bool is_repeated, bool is_packed, + EnumValidityFunc* is_valid) { + GOOGLE_CHECK_EQ(type, WireFormatLite::TYPE_ENUM); + ExtensionInfo info(extendee, number, type, is_repeated, is_packed); + info.enum_validity_check.func = CallNoArgValidityFunc; + // See comment in CallNoArgValidityFunc() about why we use a c-style cast. + info.enum_validity_check.arg = (void*)is_valid; + Register(info); +} + +void ExtensionSet::RegisterMessageExtension(const MessageLite* extendee, + int number, FieldType type, + bool is_repeated, bool is_packed, + const MessageLite* prototype) { + GOOGLE_CHECK(type == WireFormatLite::TYPE_MESSAGE || + type == WireFormatLite::TYPE_GROUP); + ExtensionInfo info(extendee, number, type, is_repeated, is_packed); + info.message_info = {prototype}; + Register(info); +} + +// =================================================================== +// Constructors and basic methods. + +ExtensionSet::ExtensionSet(Arena* arena) + : arena_(arena), + flat_capacity_(0), + flat_size_(0), + map_{flat_capacity_ == 0 + ? nullptr + : Arena::CreateArray<KeyValue>(arena_, flat_capacity_)} {} + +ExtensionSet::~ExtensionSet() { + // Deletes all allocated extensions. + if (arena_ == nullptr) { + ForEach([](int /* number */, Extension& ext) { ext.Free(); }); + if (PROTOBUF_PREDICT_FALSE(is_large())) { + delete map_.large; + } else { + DeleteFlatMap(map_.flat, flat_capacity_); + } + } +} + +void ExtensionSet::DeleteFlatMap(const ExtensionSet::KeyValue* flat, + uint16_t flat_capacity) { +#ifdef __cpp_sized_deallocation + // Arena::CreateArray already requires a trivially destructible type, but + // ensure this constraint is not violated in the future. + static_assert(std::is_trivially_destructible<KeyValue>::value, + "CreateArray requires a trivially destructible type"); + // A const-cast is needed, but this is safe as we are about to deallocate the + // array. + ::operator delete[](const_cast<ExtensionSet::KeyValue*>(flat), + sizeof(*flat) * flat_capacity); +#else // !__cpp_sized_deallocation + delete[] flat; +#endif // !__cpp_sized_deallocation +} + +// Defined in extension_set_heavy.cc. +// void ExtensionSet::AppendToList(const Descriptor* extendee, +// const DescriptorPool* pool, +// vector<const FieldDescriptor*>* output) const + +bool ExtensionSet::Has(int number) const { + const Extension* ext = FindOrNull(number); + if (ext == nullptr) return false; + GOOGLE_DCHECK(!ext->is_repeated); + return !ext->is_cleared; +} + +bool ExtensionSet::HasLazy(int number) const { + return Has(number) && FindOrNull(number)->is_lazy; +} + +int ExtensionSet::NumExtensions() const { + int result = 0; + ForEach([&result](int /* number */, const Extension& ext) { + if (!ext.is_cleared) { + ++result; + } + }); + return result; +} + +int ExtensionSet::ExtensionSize(int number) const { + const Extension* ext = FindOrNull(number); + return ext == nullptr ? 0 : ext->GetSize(); +} + +FieldType ExtensionSet::ExtensionType(int number) const { + const Extension* ext = FindOrNull(number); + if (ext == nullptr) { + GOOGLE_LOG(DFATAL) << "Don't lookup extension types if they aren't present (1). "; + return 0; + } + if (ext->is_cleared) { + GOOGLE_LOG(DFATAL) << "Don't lookup extension types if they aren't present (2). "; + } + return ext->type; +} + +void ExtensionSet::ClearExtension(int number) { + Extension* ext = FindOrNull(number); + if (ext == nullptr) return; + ext->Clear(); +} + +// =================================================================== +// Field accessors + +namespace { + +enum { REPEATED_FIELD, OPTIONAL_FIELD }; + +} // namespace + +#define GOOGLE_DCHECK_TYPE(EXTENSION, LABEL, CPPTYPE) \ + GOOGLE_DCHECK_EQ((EXTENSION).is_repeated ? REPEATED_FIELD : OPTIONAL_FIELD, LABEL); \ + GOOGLE_DCHECK_EQ(cpp_type((EXTENSION).type), WireFormatLite::CPPTYPE_##CPPTYPE) + +// ------------------------------------------------------------------- +// Primitives + +#define PRIMITIVE_ACCESSORS(UPPERCASE, LOWERCASE, CAMELCASE) \ + \ + LOWERCASE ExtensionSet::Get##CAMELCASE(int number, LOWERCASE default_value) \ + const { \ + const Extension* extension = FindOrNull(number); \ + if (extension == nullptr || extension->is_cleared) { \ + return default_value; \ + } else { \ + GOOGLE_DCHECK_TYPE(*extension, OPTIONAL_FIELD, UPPERCASE); \ + return extension->LOWERCASE##_value; \ + } \ + } \ + \ + const LOWERCASE& ExtensionSet::GetRef##CAMELCASE( \ + int number, const LOWERCASE& default_value) const { \ + const Extension* extension = FindOrNull(number); \ + if (extension == nullptr || extension->is_cleared) { \ + return default_value; \ + } else { \ + GOOGLE_DCHECK_TYPE(*extension, OPTIONAL_FIELD, UPPERCASE); \ + return extension->LOWERCASE##_value; \ + } \ + } \ + \ + void ExtensionSet::Set##CAMELCASE(int number, FieldType type, \ + LOWERCASE value, \ + const FieldDescriptor* descriptor) { \ + Extension* extension; \ + if (MaybeNewExtension(number, descriptor, &extension)) { \ + extension->type = type; \ + GOOGLE_DCHECK_EQ(cpp_type(extension->type), \ + WireFormatLite::CPPTYPE_##UPPERCASE); \ + extension->is_repeated = false; \ + } else { \ + GOOGLE_DCHECK_TYPE(*extension, OPTIONAL_FIELD, UPPERCASE); \ + } \ + extension->is_cleared = false; \ + extension->LOWERCASE##_value = value; \ + } \ + \ + LOWERCASE ExtensionSet::GetRepeated##CAMELCASE(int number, int index) \ + const { \ + const Extension* extension = FindOrNull(number); \ + GOOGLE_CHECK(extension != nullptr) << "Index out-of-bounds (field is empty)."; \ + GOOGLE_DCHECK_TYPE(*extension, REPEATED_FIELD, UPPERCASE); \ + return extension->repeated_##LOWERCASE##_value->Get(index); \ + } \ + \ + const LOWERCASE& ExtensionSet::GetRefRepeated##CAMELCASE(int number, \ + int index) const { \ + const Extension* extension = FindOrNull(number); \ + GOOGLE_CHECK(extension != nullptr) << "Index out-of-bounds (field is empty)."; \ + GOOGLE_DCHECK_TYPE(*extension, REPEATED_FIELD, UPPERCASE); \ + return extension->repeated_##LOWERCASE##_value->Get(index); \ + } \ + \ + void ExtensionSet::SetRepeated##CAMELCASE(int number, int index, \ + LOWERCASE value) { \ + Extension* extension = FindOrNull(number); \ + GOOGLE_CHECK(extension != nullptr) << "Index out-of-bounds (field is empty)."; \ + GOOGLE_DCHECK_TYPE(*extension, REPEATED_FIELD, UPPERCASE); \ + extension->repeated_##LOWERCASE##_value->Set(index, value); \ + } \ + \ + void ExtensionSet::Add##CAMELCASE(int number, FieldType type, bool packed, \ + LOWERCASE value, \ + const FieldDescriptor* descriptor) { \ + Extension* extension; \ + if (MaybeNewExtension(number, descriptor, &extension)) { \ + extension->type = type; \ + GOOGLE_DCHECK_EQ(cpp_type(extension->type), \ + WireFormatLite::CPPTYPE_##UPPERCASE); \ + extension->is_repeated = true; \ + extension->is_packed = packed; \ + extension->repeated_##LOWERCASE##_value = \ + Arena::CreateMessage<RepeatedField<LOWERCASE>>(arena_); \ + } else { \ + GOOGLE_DCHECK_TYPE(*extension, REPEATED_FIELD, UPPERCASE); \ + GOOGLE_DCHECK_EQ(extension->is_packed, packed); \ + } \ + extension->repeated_##LOWERCASE##_value->Add(value); \ + } + +PRIMITIVE_ACCESSORS(INT32, arc_i32, Int32) +PRIMITIVE_ACCESSORS(INT64, arc_i64, Int64) +PRIMITIVE_ACCESSORS(UINT32, arc_ui32, UInt32) +PRIMITIVE_ACCESSORS(UINT64, arc_ui64, UInt64) +PRIMITIVE_ACCESSORS(FLOAT, float, Float) +PRIMITIVE_ACCESSORS(DOUBLE, double, Double) +PRIMITIVE_ACCESSORS(BOOL, bool, Bool) + +#undef PRIMITIVE_ACCESSORS + +const void* ExtensionSet::GetRawRepeatedField(int number, + const void* default_value) const { + const Extension* extension = FindOrNull(number); + if (extension == nullptr) { + return default_value; + } + // We assume that all the RepeatedField<>* pointers have the same + // size and alignment within the anonymous union in Extension. + return extension->repeated_arc_i32_value; +} + +void* ExtensionSet::MutableRawRepeatedField(int number, FieldType field_type, + bool packed, + const FieldDescriptor* desc) { + Extension* extension; + + // We instantiate an empty Repeated{,Ptr}Field if one doesn't exist for this + // extension. + if (MaybeNewExtension(number, desc, &extension)) { + extension->is_repeated = true; + extension->type = field_type; + extension->is_packed = packed; + + switch (WireFormatLite::FieldTypeToCppType( + static_cast<WireFormatLite::FieldType>(field_type))) { + case WireFormatLite::CPPTYPE_INT32: + extension->repeated_arc_i32_value = + Arena::CreateMessage<RepeatedField<arc_i32>>(arena_); + break; + case WireFormatLite::CPPTYPE_INT64: + extension->repeated_arc_i64_value = + Arena::CreateMessage<RepeatedField<arc_i64>>(arena_); + break; + case WireFormatLite::CPPTYPE_UINT32: + extension->repeated_arc_ui32_value = + Arena::CreateMessage<RepeatedField<arc_ui32>>(arena_); + break; + case WireFormatLite::CPPTYPE_UINT64: + extension->repeated_arc_ui64_value = + Arena::CreateMessage<RepeatedField<arc_ui64>>(arena_); + break; + case WireFormatLite::CPPTYPE_DOUBLE: + extension->repeated_double_value = + Arena::CreateMessage<RepeatedField<double>>(arena_); + break; + case WireFormatLite::CPPTYPE_FLOAT: + extension->repeated_float_value = + Arena::CreateMessage<RepeatedField<float>>(arena_); + break; + case WireFormatLite::CPPTYPE_BOOL: + extension->repeated_bool_value = + Arena::CreateMessage<RepeatedField<bool>>(arena_); + break; + case WireFormatLite::CPPTYPE_ENUM: + extension->repeated_enum_value = + Arena::CreateMessage<RepeatedField<int>>(arena_); + break; + case WireFormatLite::CPPTYPE_STRING: + extension->repeated_string_value = + Arena::CreateMessage<RepeatedPtrField<TProtoStringType>>(arena_); + break; + case WireFormatLite::CPPTYPE_MESSAGE: + extension->repeated_message_value = + Arena::CreateMessage<RepeatedPtrField<MessageLite>>(arena_); + break; + } + } + + // We assume that all the RepeatedField<>* pointers have the same + // size and alignment within the anonymous union in Extension. + return extension->repeated_arc_i32_value; +} + +// Compatible version using old call signature. Does not create extensions when +// the don't already exist; instead, just GOOGLE_CHECK-fails. +void* ExtensionSet::MutableRawRepeatedField(int number) { + Extension* extension = FindOrNull(number); + GOOGLE_CHECK(extension != nullptr) << "Extension not found."; + // We assume that all the RepeatedField<>* pointers have the same + // size and alignment within the anonymous union in Extension. + return extension->repeated_arc_i32_value; +} + +// ------------------------------------------------------------------- +// Enums + +int ExtensionSet::GetEnum(int number, int default_value) const { + const Extension* extension = FindOrNull(number); + if (extension == nullptr || extension->is_cleared) { + // Not present. Return the default value. + return default_value; + } else { + GOOGLE_DCHECK_TYPE(*extension, OPTIONAL_FIELD, ENUM); + return extension->enum_value; + } +} + +const int& ExtensionSet::GetRefEnum(int number, + const int& default_value) const { + const Extension* extension = FindOrNull(number); + if (extension == nullptr || extension->is_cleared) { + // Not present. Return the default value. + return default_value; + } else { + GOOGLE_DCHECK_TYPE(*extension, OPTIONAL_FIELD, ENUM); + return extension->enum_value; + } +} + +void ExtensionSet::SetEnum(int number, FieldType type, int value, + const FieldDescriptor* descriptor) { + Extension* extension; + if (MaybeNewExtension(number, descriptor, &extension)) { + extension->type = type; + GOOGLE_DCHECK_EQ(cpp_type(extension->type), WireFormatLite::CPPTYPE_ENUM); + extension->is_repeated = false; + } else { + GOOGLE_DCHECK_TYPE(*extension, OPTIONAL_FIELD, ENUM); + } + extension->is_cleared = false; + extension->enum_value = value; +} + +int ExtensionSet::GetRepeatedEnum(int number, int index) const { + const Extension* extension = FindOrNull(number); + GOOGLE_CHECK(extension != nullptr) << "Index out-of-bounds (field is empty)."; + GOOGLE_DCHECK_TYPE(*extension, REPEATED_FIELD, ENUM); + return extension->repeated_enum_value->Get(index); +} + +const int& ExtensionSet::GetRefRepeatedEnum(int number, int index) const { + const Extension* extension = FindOrNull(number); + GOOGLE_CHECK(extension != nullptr) << "Index out-of-bounds (field is empty)."; + GOOGLE_DCHECK_TYPE(*extension, REPEATED_FIELD, ENUM); + return extension->repeated_enum_value->Get(index); +} + +void ExtensionSet::SetRepeatedEnum(int number, int index, int value) { + Extension* extension = FindOrNull(number); + GOOGLE_CHECK(extension != nullptr) << "Index out-of-bounds (field is empty)."; + GOOGLE_DCHECK_TYPE(*extension, REPEATED_FIELD, ENUM); + extension->repeated_enum_value->Set(index, value); +} + +void ExtensionSet::AddEnum(int number, FieldType type, bool packed, int value, + const FieldDescriptor* descriptor) { + Extension* extension; + if (MaybeNewExtension(number, descriptor, &extension)) { + extension->type = type; + GOOGLE_DCHECK_EQ(cpp_type(extension->type), WireFormatLite::CPPTYPE_ENUM); + extension->is_repeated = true; + extension->is_packed = packed; + extension->repeated_enum_value = + Arena::CreateMessage<RepeatedField<int>>(arena_); + } else { + GOOGLE_DCHECK_TYPE(*extension, REPEATED_FIELD, ENUM); + GOOGLE_DCHECK_EQ(extension->is_packed, packed); + } + extension->repeated_enum_value->Add(value); +} + +// ------------------------------------------------------------------- +// Strings + +const TProtoStringType& ExtensionSet::GetString( + int number, const TProtoStringType& default_value) const { + const Extension* extension = FindOrNull(number); + if (extension == nullptr || extension->is_cleared) { + // Not present. Return the default value. + return default_value; + } else { + GOOGLE_DCHECK_TYPE(*extension, OPTIONAL_FIELD, STRING); + return *extension->string_value; + } +} + +TProtoStringType* ExtensionSet::MutableString(int number, FieldType type, + const FieldDescriptor* descriptor) { + Extension* extension; + if (MaybeNewExtension(number, descriptor, &extension)) { + extension->type = type; + GOOGLE_DCHECK_EQ(cpp_type(extension->type), WireFormatLite::CPPTYPE_STRING); + extension->is_repeated = false; + extension->string_value = Arena::Create<TProtoStringType>(arena_); + } else { + GOOGLE_DCHECK_TYPE(*extension, OPTIONAL_FIELD, STRING); + } + extension->is_cleared = false; + return extension->string_value; +} + +const TProtoStringType& ExtensionSet::GetRepeatedString(int number, + int index) const { + const Extension* extension = FindOrNull(number); + GOOGLE_CHECK(extension != nullptr) << "Index out-of-bounds (field is empty)."; + GOOGLE_DCHECK_TYPE(*extension, REPEATED_FIELD, STRING); + return extension->repeated_string_value->Get(index); +} + +TProtoStringType* ExtensionSet::MutableRepeatedString(int number, int index) { + Extension* extension = FindOrNull(number); + GOOGLE_CHECK(extension != nullptr) << "Index out-of-bounds (field is empty)."; + GOOGLE_DCHECK_TYPE(*extension, REPEATED_FIELD, STRING); + return extension->repeated_string_value->Mutable(index); +} + +TProtoStringType* ExtensionSet::AddString(int number, FieldType type, + const FieldDescriptor* descriptor) { + Extension* extension; + if (MaybeNewExtension(number, descriptor, &extension)) { + extension->type = type; + GOOGLE_DCHECK_EQ(cpp_type(extension->type), WireFormatLite::CPPTYPE_STRING); + extension->is_repeated = true; + extension->is_packed = false; + extension->repeated_string_value = + Arena::CreateMessage<RepeatedPtrField<TProtoStringType>>(arena_); + } else { + GOOGLE_DCHECK_TYPE(*extension, REPEATED_FIELD, STRING); + } + return extension->repeated_string_value->Add(); +} + +// ------------------------------------------------------------------- +// Messages + +const MessageLite& ExtensionSet::GetMessage( + int number, const MessageLite& default_value) const { + const Extension* extension = FindOrNull(number); + if (extension == nullptr) { + // Not present. Return the default value. + return default_value; + } else { + GOOGLE_DCHECK_TYPE(*extension, OPTIONAL_FIELD, MESSAGE); + if (extension->is_lazy) { + return extension->lazymessage_value->GetMessage(default_value, arena_); + } else { + return *extension->message_value; + } + } +} + +// Defined in extension_set_heavy.cc. +// const MessageLite& ExtensionSet::GetMessage(int number, +// const Descriptor* message_type, +// MessageFactory* factory) const + +MessageLite* ExtensionSet::MutableMessage(int number, FieldType type, + const MessageLite& prototype, + const FieldDescriptor* descriptor) { + Extension* extension; + if (MaybeNewExtension(number, descriptor, &extension)) { + extension->type = type; + GOOGLE_DCHECK_EQ(cpp_type(extension->type), WireFormatLite::CPPTYPE_MESSAGE); + extension->is_repeated = false; + extension->is_lazy = false; + extension->message_value = prototype.New(arena_); + extension->is_cleared = false; + return extension->message_value; + } else { + GOOGLE_DCHECK_TYPE(*extension, OPTIONAL_FIELD, MESSAGE); + extension->is_cleared = false; + if (extension->is_lazy) { + return extension->lazymessage_value->MutableMessage(prototype, arena_); + } else { + return extension->message_value; + } + } +} + +// Defined in extension_set_heavy.cc. +// MessageLite* ExtensionSet::MutableMessage(int number, FieldType type, +// const Descriptor* message_type, +// MessageFactory* factory) + +void ExtensionSet::SetAllocatedMessage(int number, FieldType type, + const FieldDescriptor* descriptor, + MessageLite* message) { + if (message == nullptr) { + ClearExtension(number); + return; + } + GOOGLE_DCHECK(message->GetOwningArena() == nullptr || + message->GetOwningArena() == arena_); + Arena* message_arena = message->GetOwningArena(); + Extension* extension; + if (MaybeNewExtension(number, descriptor, &extension)) { + extension->type = type; + GOOGLE_DCHECK_EQ(cpp_type(extension->type), WireFormatLite::CPPTYPE_MESSAGE); + extension->is_repeated = false; + extension->is_lazy = false; + if (message_arena == arena_) { + extension->message_value = message; + } else if (message_arena == nullptr) { + extension->message_value = message; + arena_->Own(message); // not nullptr because not equal to message_arena + } else { + extension->message_value = message->New(arena_); + extension->message_value->CheckTypeAndMergeFrom(*message); + } + } else { + GOOGLE_DCHECK_TYPE(*extension, OPTIONAL_FIELD, MESSAGE); + if (extension->is_lazy) { + extension->lazymessage_value->SetAllocatedMessage(message, arena_); + } else { + if (arena_ == nullptr) { + delete extension->message_value; + } + if (message_arena == arena_) { + extension->message_value = message; + } else if (message_arena == nullptr) { + extension->message_value = message; + arena_->Own(message); // not nullptr because not equal to message_arena + } else { + extension->message_value = message->New(arena_); + extension->message_value->CheckTypeAndMergeFrom(*message); + } + } + } + extension->is_cleared = false; +} + +void ExtensionSet::UnsafeArenaSetAllocatedMessage( + int number, FieldType type, const FieldDescriptor* descriptor, + MessageLite* message) { + if (message == nullptr) { + ClearExtension(number); + return; + } + Extension* extension; + if (MaybeNewExtension(number, descriptor, &extension)) { + extension->type = type; + GOOGLE_DCHECK_EQ(cpp_type(extension->type), WireFormatLite::CPPTYPE_MESSAGE); + extension->is_repeated = false; + extension->is_lazy = false; + extension->message_value = message; + } else { + GOOGLE_DCHECK_TYPE(*extension, OPTIONAL_FIELD, MESSAGE); + if (extension->is_lazy) { + extension->lazymessage_value->UnsafeArenaSetAllocatedMessage(message, + arena_); + } else { + if (arena_ == nullptr) { + delete extension->message_value; + } + extension->message_value = message; + } + } + extension->is_cleared = false; +} + +MessageLite* ExtensionSet::ReleaseMessage(int number, + const MessageLite& prototype) { + Extension* extension = FindOrNull(number); + if (extension == nullptr) { + // Not present. Return nullptr. + return nullptr; + } else { + GOOGLE_DCHECK_TYPE(*extension, OPTIONAL_FIELD, MESSAGE); + MessageLite* ret = nullptr; + if (extension->is_lazy) { + ret = extension->lazymessage_value->ReleaseMessage(prototype, arena_); + if (arena_ == nullptr) { + delete extension->lazymessage_value; + } + } else { + if (arena_ == nullptr) { + ret = extension->message_value; + } else { + // ReleaseMessage() always returns a heap-allocated message, and we are + // on an arena, so we need to make a copy of this message to return. + ret = extension->message_value->New(); + ret->CheckTypeAndMergeFrom(*extension->message_value); + } + } + Erase(number); + return ret; + } +} + +MessageLite* ExtensionSet::UnsafeArenaReleaseMessage( + int number, const MessageLite& prototype) { + Extension* extension = FindOrNull(number); + if (extension == nullptr) { + // Not present. Return nullptr. + return nullptr; + } else { + GOOGLE_DCHECK_TYPE(*extension, OPTIONAL_FIELD, MESSAGE); + MessageLite* ret = nullptr; + if (extension->is_lazy) { + ret = extension->lazymessage_value->UnsafeArenaReleaseMessage(prototype, + arena_); + if (arena_ == nullptr) { + delete extension->lazymessage_value; + } + } else { + ret = extension->message_value; + } + Erase(number); + return ret; + } +} + +// Defined in extension_set_heavy.cc. +// MessageLite* ExtensionSet::ReleaseMessage(const FieldDescriptor* descriptor, +// MessageFactory* factory); + +const MessageLite& ExtensionSet::GetRepeatedMessage(int number, + int index) const { + const Extension* extension = FindOrNull(number); + GOOGLE_CHECK(extension != nullptr) << "Index out-of-bounds (field is empty)."; + GOOGLE_DCHECK_TYPE(*extension, REPEATED_FIELD, MESSAGE); + return extension->repeated_message_value->Get(index); +} + +MessageLite* ExtensionSet::MutableRepeatedMessage(int number, int index) { + Extension* extension = FindOrNull(number); + GOOGLE_CHECK(extension != nullptr) << "Index out-of-bounds (field is empty)."; + GOOGLE_DCHECK_TYPE(*extension, REPEATED_FIELD, MESSAGE); + return extension->repeated_message_value->Mutable(index); +} + +MessageLite* ExtensionSet::AddMessage(int number, FieldType type, + const MessageLite& prototype, + const FieldDescriptor* descriptor) { + Extension* extension; + if (MaybeNewExtension(number, descriptor, &extension)) { + extension->type = type; + GOOGLE_DCHECK_EQ(cpp_type(extension->type), WireFormatLite::CPPTYPE_MESSAGE); + extension->is_repeated = true; + extension->repeated_message_value = + Arena::CreateMessage<RepeatedPtrField<MessageLite>>(arena_); + } else { + GOOGLE_DCHECK_TYPE(*extension, REPEATED_FIELD, MESSAGE); + } + + // RepeatedPtrField<MessageLite> does not know how to Add() since it cannot + // allocate an abstract object, so we have to be tricky. + MessageLite* result = reinterpret_cast<internal::RepeatedPtrFieldBase*>( + extension->repeated_message_value) + ->AddFromCleared<GenericTypeHandler<MessageLite>>(); + if (result == nullptr) { + result = prototype.New(arena_); + extension->repeated_message_value->AddAllocated(result); + } + return result; +} + +// Defined in extension_set_heavy.cc. +// MessageLite* ExtensionSet::AddMessage(int number, FieldType type, +// const Descriptor* message_type, +// MessageFactory* factory) + +#undef GOOGLE_DCHECK_TYPE + +void ExtensionSet::RemoveLast(int number) { + Extension* extension = FindOrNull(number); + GOOGLE_CHECK(extension != nullptr) << "Index out-of-bounds (field is empty)."; + GOOGLE_DCHECK(extension->is_repeated); + + switch (cpp_type(extension->type)) { + case WireFormatLite::CPPTYPE_INT32: + extension->repeated_arc_i32_value->RemoveLast(); + break; + case WireFormatLite::CPPTYPE_INT64: + extension->repeated_arc_i64_value->RemoveLast(); + break; + case WireFormatLite::CPPTYPE_UINT32: + extension->repeated_arc_ui32_value->RemoveLast(); + break; + case WireFormatLite::CPPTYPE_UINT64: + extension->repeated_arc_ui64_value->RemoveLast(); + break; + case WireFormatLite::CPPTYPE_FLOAT: + extension->repeated_float_value->RemoveLast(); + break; + case WireFormatLite::CPPTYPE_DOUBLE: + extension->repeated_double_value->RemoveLast(); + break; + case WireFormatLite::CPPTYPE_BOOL: + extension->repeated_bool_value->RemoveLast(); + break; + case WireFormatLite::CPPTYPE_ENUM: + extension->repeated_enum_value->RemoveLast(); + break; + case WireFormatLite::CPPTYPE_STRING: + extension->repeated_string_value->RemoveLast(); + break; + case WireFormatLite::CPPTYPE_MESSAGE: + extension->repeated_message_value->RemoveLast(); + break; + } +} + +MessageLite* ExtensionSet::ReleaseLast(int number) { + Extension* extension = FindOrNull(number); + GOOGLE_CHECK(extension != nullptr) << "Index out-of-bounds (field is empty)."; + GOOGLE_DCHECK(extension->is_repeated); + GOOGLE_DCHECK(cpp_type(extension->type) == WireFormatLite::CPPTYPE_MESSAGE); + return extension->repeated_message_value->ReleaseLast(); +} + +MessageLite* ExtensionSet::UnsafeArenaReleaseLast(int number) { + Extension* extension = FindOrNull(number); + GOOGLE_CHECK(extension != nullptr) << "Index out-of-bounds (field is empty)."; + GOOGLE_DCHECK(extension->is_repeated); + GOOGLE_DCHECK(cpp_type(extension->type) == WireFormatLite::CPPTYPE_MESSAGE); + return extension->repeated_message_value->UnsafeArenaReleaseLast(); +} + +void ExtensionSet::SwapElements(int number, int index1, int index2) { + Extension* extension = FindOrNull(number); + GOOGLE_CHECK(extension != nullptr) << "Index out-of-bounds (field is empty)."; + GOOGLE_DCHECK(extension->is_repeated); + + switch (cpp_type(extension->type)) { + case WireFormatLite::CPPTYPE_INT32: + extension->repeated_arc_i32_value->SwapElements(index1, index2); + break; + case WireFormatLite::CPPTYPE_INT64: + extension->repeated_arc_i64_value->SwapElements(index1, index2); + break; + case WireFormatLite::CPPTYPE_UINT32: + extension->repeated_arc_ui32_value->SwapElements(index1, index2); + break; + case WireFormatLite::CPPTYPE_UINT64: + extension->repeated_arc_ui64_value->SwapElements(index1, index2); + break; + case WireFormatLite::CPPTYPE_FLOAT: + extension->repeated_float_value->SwapElements(index1, index2); + break; + case WireFormatLite::CPPTYPE_DOUBLE: + extension->repeated_double_value->SwapElements(index1, index2); + break; + case WireFormatLite::CPPTYPE_BOOL: + extension->repeated_bool_value->SwapElements(index1, index2); + break; + case WireFormatLite::CPPTYPE_ENUM: + extension->repeated_enum_value->SwapElements(index1, index2); + break; + case WireFormatLite::CPPTYPE_STRING: + extension->repeated_string_value->SwapElements(index1, index2); + break; + case WireFormatLite::CPPTYPE_MESSAGE: + extension->repeated_message_value->SwapElements(index1, index2); + break; + } +} + +// =================================================================== + +void ExtensionSet::Clear() { + ForEach([](int /* number */, Extension& ext) { ext.Clear(); }); +} + +namespace { +// Computes the size of a std::set_union without constructing the union. +template <typename ItX, typename ItY> +size_t SizeOfUnion(ItX it_xs, ItX end_xs, ItY it_ys, ItY end_ys) { + size_t result = 0; + while (it_xs != end_xs && it_ys != end_ys) { + ++result; + if (it_xs->first < it_ys->first) { + ++it_xs; + } else if (it_xs->first == it_ys->first) { + ++it_xs; + ++it_ys; + } else { + ++it_ys; + } + } + result += std::distance(it_xs, end_xs); + result += std::distance(it_ys, end_ys); + return result; +} +} // namespace + +void ExtensionSet::MergeFrom(const MessageLite* extendee, + const ExtensionSet& other) { + if (PROTOBUF_PREDICT_TRUE(!is_large())) { + if (PROTOBUF_PREDICT_TRUE(!other.is_large())) { + GrowCapacity(SizeOfUnion(flat_begin(), flat_end(), other.flat_begin(), + other.flat_end())); + } else { + GrowCapacity(SizeOfUnion(flat_begin(), flat_end(), + other.map_.large->begin(), + other.map_.large->end())); + } + } + other.ForEach([extendee, this, &other](int number, const Extension& ext) { + this->InternalExtensionMergeFrom(extendee, number, ext, other.arena_); + }); +} + +void ExtensionSet::InternalExtensionMergeFrom(const MessageLite* extendee, + int number, + const Extension& other_extension, + Arena* other_arena) { + if (other_extension.is_repeated) { + Extension* extension; + bool is_new = + MaybeNewExtension(number, other_extension.descriptor, &extension); + if (is_new) { + // Extension did not already exist in set. + extension->type = other_extension.type; + extension->is_packed = other_extension.is_packed; + extension->is_repeated = true; + } else { + GOOGLE_DCHECK_EQ(extension->type, other_extension.type); + GOOGLE_DCHECK_EQ(extension->is_packed, other_extension.is_packed); + GOOGLE_DCHECK(extension->is_repeated); + } + + switch (cpp_type(other_extension.type)) { +#define HANDLE_TYPE(UPPERCASE, LOWERCASE, REPEATED_TYPE) \ + case WireFormatLite::CPPTYPE_##UPPERCASE: \ + if (is_new) { \ + extension->repeated_##LOWERCASE##_value = \ + Arena::CreateMessage<REPEATED_TYPE>(arena_); \ + } \ + extension->repeated_##LOWERCASE##_value->MergeFrom( \ + *other_extension.repeated_##LOWERCASE##_value); \ + break; + + HANDLE_TYPE(INT32, arc_i32, RepeatedField<arc_i32>); + HANDLE_TYPE(INT64, arc_i64, RepeatedField<arc_i64>); + HANDLE_TYPE(UINT32, arc_ui32, RepeatedField<arc_ui32>); + HANDLE_TYPE(UINT64, arc_ui64, RepeatedField<arc_ui64>); + HANDLE_TYPE(FLOAT, float, RepeatedField<float>); + HANDLE_TYPE(DOUBLE, double, RepeatedField<double>); + HANDLE_TYPE(BOOL, bool, RepeatedField<bool>); + HANDLE_TYPE(ENUM, enum, RepeatedField<int>); + HANDLE_TYPE(STRING, string, RepeatedPtrField<TProtoStringType>); +#undef HANDLE_TYPE + + case WireFormatLite::CPPTYPE_MESSAGE: + if (is_new) { + extension->repeated_message_value = + Arena::CreateMessage<RepeatedPtrField<MessageLite>>(arena_); + } + // We can't call RepeatedPtrField<MessageLite>::MergeFrom() because + // it would attempt to allocate new objects. + RepeatedPtrField<MessageLite>* other_repeated_message = + other_extension.repeated_message_value; + for (int i = 0; i < other_repeated_message->size(); i++) { + const MessageLite& other_message = other_repeated_message->Get(i); + MessageLite* target = + reinterpret_cast<internal::RepeatedPtrFieldBase*>( + extension->repeated_message_value) + ->AddFromCleared<GenericTypeHandler<MessageLite>>(); + if (target == nullptr) { + target = other_message.New(arena_); + extension->repeated_message_value->AddAllocated(target); + } + target->CheckTypeAndMergeFrom(other_message); + } + break; + } + } else { + if (!other_extension.is_cleared) { + switch (cpp_type(other_extension.type)) { +#define HANDLE_TYPE(UPPERCASE, LOWERCASE, CAMELCASE) \ + case WireFormatLite::CPPTYPE_##UPPERCASE: \ + Set##CAMELCASE(number, other_extension.type, \ + other_extension.LOWERCASE##_value, \ + other_extension.descriptor); \ + break; + + HANDLE_TYPE(INT32, arc_i32, Int32); + HANDLE_TYPE(INT64, arc_i64, Int64); + HANDLE_TYPE(UINT32, arc_ui32, UInt32); + HANDLE_TYPE(UINT64, arc_ui64, UInt64); + HANDLE_TYPE(FLOAT, float, Float); + HANDLE_TYPE(DOUBLE, double, Double); + HANDLE_TYPE(BOOL, bool, Bool); + HANDLE_TYPE(ENUM, enum, Enum); +#undef HANDLE_TYPE + case WireFormatLite::CPPTYPE_STRING: + SetString(number, other_extension.type, *other_extension.string_value, + other_extension.descriptor); + break; + case WireFormatLite::CPPTYPE_MESSAGE: { + Extension* extension; + bool is_new = + MaybeNewExtension(number, other_extension.descriptor, &extension); + if (is_new) { + extension->type = other_extension.type; + extension->is_packed = other_extension.is_packed; + extension->is_repeated = false; + if (other_extension.is_lazy) { + extension->is_lazy = true; + extension->lazymessage_value = + other_extension.lazymessage_value->New(arena_); + extension->lazymessage_value->MergeFrom( + GetPrototypeForLazyMessage(extendee, number), + *other_extension.lazymessage_value, arena_); + } else { + extension->is_lazy = false; + extension->message_value = + other_extension.message_value->New(arena_); + extension->message_value->CheckTypeAndMergeFrom( + *other_extension.message_value); + } + } else { + GOOGLE_DCHECK_EQ(extension->type, other_extension.type); + GOOGLE_DCHECK_EQ(extension->is_packed, other_extension.is_packed); + GOOGLE_DCHECK(!extension->is_repeated); + if (other_extension.is_lazy) { + if (extension->is_lazy) { + extension->lazymessage_value->MergeFrom( + GetPrototypeForLazyMessage(extendee, number), + *other_extension.lazymessage_value, arena_); + } else { + extension->message_value->CheckTypeAndMergeFrom( + other_extension.lazymessage_value->GetMessage( + *extension->message_value, other_arena)); + } + } else { + if (extension->is_lazy) { + extension->lazymessage_value + ->MutableMessage(*other_extension.message_value, arena_) + ->CheckTypeAndMergeFrom(*other_extension.message_value); + } else { + extension->message_value->CheckTypeAndMergeFrom( + *other_extension.message_value); + } + } + } + extension->is_cleared = false; + break; + } + } + } + } +} + +void ExtensionSet::Swap(const MessageLite* extendee, ExtensionSet* other) { +#ifdef PROTOBUF_FORCE_COPY_IN_SWAP + if (GetArena() != nullptr && GetArena() == other->GetArena()) { +#else // PROTOBUF_FORCE_COPY_IN_SWAP + if (GetArena() == other->GetArena()) { +#endif // !PROTOBUF_FORCE_COPY_IN_SWAP + InternalSwap(other); + } else { + // TODO(cfallin, rohananil): We maybe able to optimize a case where we are + // swapping from heap to arena-allocated extension set, by just Own()'ing + // the extensions. + ExtensionSet extension_set; + extension_set.MergeFrom(extendee, *other); + other->Clear(); + other->MergeFrom(extendee, *this); + Clear(); + MergeFrom(extendee, extension_set); + } +} + +void ExtensionSet::InternalSwap(ExtensionSet* other) { + using std::swap; + swap(arena_, other->arena_); + swap(flat_capacity_, other->flat_capacity_); + swap(flat_size_, other->flat_size_); + swap(map_, other->map_); +} + +void ExtensionSet::SwapExtension(const MessageLite* extendee, + ExtensionSet* other, int number) { + if (this == other) return; + + if (GetArena() == other->GetArena()) { + UnsafeShallowSwapExtension(other, number); + return; + } + + Extension* this_ext = FindOrNull(number); + Extension* other_ext = other->FindOrNull(number); + + 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(extendee, number, *other_ext, + other->GetArena()); + Extension* temp_ext = temp.FindOrNull(number); + + other_ext->Clear(); + other->InternalExtensionMergeFrom(extendee, number, *this_ext, + this->GetArena()); + this_ext->Clear(); + InternalExtensionMergeFrom(extendee, number, *temp_ext, temp.GetArena()); + } else if (this_ext == nullptr) { + InternalExtensionMergeFrom(extendee, number, *other_ext, other->GetArena()); + if (other->GetArena() == nullptr) other_ext->Free(); + other->Erase(number); + } else { + other->InternalExtensionMergeFrom(extendee, number, *this_ext, + this->GetArena()); + if (GetArena() == nullptr) this_ext->Free(); + Erase(number); + } +} + +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); + } +} + +bool ExtensionSet::IsInitialized() const { + // Extensions are never required. However, we need to check that all + // embedded messages are initialized. + if (PROTOBUF_PREDICT_FALSE(is_large())) { + for (const auto& kv : *map_.large) { + if (!kv.second.IsInitialized()) return false; + } + return true; + } + for (const KeyValue* it = flat_begin(); it != flat_end(); ++it) { + if (!it->second.IsInitialized()) return false; + } + return true; +} + +bool ExtensionSet::FindExtensionInfoFromTag(arc_ui32 tag, + ExtensionFinder* extension_finder, + int* field_number, + ExtensionInfo* extension, + bool* was_packed_on_wire) { + *field_number = WireFormatLite::GetTagFieldNumber(tag); + WireFormatLite::WireType wire_type = WireFormatLite::GetTagWireType(tag); + return FindExtensionInfoFromFieldNumber(wire_type, *field_number, + extension_finder, extension, + was_packed_on_wire); +} + +bool ExtensionSet::FindExtensionInfoFromFieldNumber( + int wire_type, int field_number, ExtensionFinder* extension_finder, + ExtensionInfo* extension, bool* was_packed_on_wire) const { + if (!extension_finder->Find(field_number, extension)) { + return false; + } + + WireFormatLite::WireType expected_wire_type = + WireFormatLite::WireTypeForFieldType(real_type(extension->type)); + + // Check if this is a packed field. + *was_packed_on_wire = false; + if (extension->is_repeated && + wire_type == WireFormatLite::WIRETYPE_LENGTH_DELIMITED && + is_packable(expected_wire_type)) { + *was_packed_on_wire = true; + return true; + } + // Otherwise the wire type must match. + return expected_wire_type == wire_type; +} + +bool ExtensionSet::ParseField(arc_ui32 tag, io::CodedInputStream* input, + ExtensionFinder* extension_finder, + FieldSkipper* field_skipper) { + int number; + bool was_packed_on_wire; + ExtensionInfo extension; + if (!FindExtensionInfoFromTag(tag, extension_finder, &number, &extension, + &was_packed_on_wire)) { + return field_skipper->SkipField(input, tag); + } else { + return ParseFieldWithExtensionInfo(number, was_packed_on_wire, extension, + input, field_skipper); + } +} + +const char* ExtensionSet::ParseField(arc_ui64 tag, const char* ptr, + const MessageLite* extendee, + internal::InternalMetadata* metadata, + internal::ParseContext* ctx) { + GeneratedExtensionFinder finder(extendee); + int number = tag >> 3; + bool was_packed_on_wire; + ExtensionInfo extension; + if (!FindExtensionInfoFromFieldNumber(tag & 7, number, &finder, &extension, + &was_packed_on_wire)) { + return UnknownFieldParse( + tag, metadata->mutable_unknown_fields<TProtoStringType>(), ptr, ctx); + } + return ParseFieldWithExtensionInfo<TProtoStringType>( + number, was_packed_on_wire, extension, metadata, ptr, ctx); +} + +const char* ExtensionSet::ParseMessageSetItem( + const char* ptr, const MessageLite* extendee, + internal::InternalMetadata* metadata, internal::ParseContext* ctx) { + return ParseMessageSetItemTmpl<MessageLite, TProtoStringType>(ptr, extendee, + metadata, ctx); +} + +bool ExtensionSet::ParseFieldWithExtensionInfo(int number, + bool was_packed_on_wire, + const ExtensionInfo& extension, + io::CodedInputStream* input, + FieldSkipper* field_skipper) { + // Explicitly not read extension.is_packed, instead check whether the field + // was encoded in packed form on the wire. + if (was_packed_on_wire) { + arc_ui32 size; + if (!input->ReadVarint32(&size)) return false; + io::CodedInputStream::Limit limit = input->PushLimit(size); + + switch (extension.type) { +#define HANDLE_TYPE(UPPERCASE, CPP_CAMELCASE, CPP_LOWERCASE) \ + case WireFormatLite::TYPE_##UPPERCASE: \ + while (input->BytesUntilLimit() > 0) { \ + CPP_LOWERCASE value; \ + if (!WireFormatLite::ReadPrimitive<CPP_LOWERCASE, \ + WireFormatLite::TYPE_##UPPERCASE>( \ + input, &value)) \ + return false; \ + Add##CPP_CAMELCASE(number, WireFormatLite::TYPE_##UPPERCASE, \ + extension.is_packed, value, extension.descriptor); \ + } \ + break + + HANDLE_TYPE(INT32, Int32, arc_i32); + HANDLE_TYPE(INT64, Int64, arc_i64); + HANDLE_TYPE(UINT32, UInt32, arc_ui32); + HANDLE_TYPE(UINT64, UInt64, arc_ui64); + HANDLE_TYPE(SINT32, Int32, arc_i32); + HANDLE_TYPE(SINT64, Int64, arc_i64); + HANDLE_TYPE(FIXED32, UInt32, arc_ui32); + HANDLE_TYPE(FIXED64, UInt64, arc_ui64); + HANDLE_TYPE(SFIXED32, Int32, arc_i32); + HANDLE_TYPE(SFIXED64, Int64, arc_i64); + HANDLE_TYPE(FLOAT, Float, float); + HANDLE_TYPE(DOUBLE, Double, double); + HANDLE_TYPE(BOOL, Bool, bool); +#undef HANDLE_TYPE + + case WireFormatLite::TYPE_ENUM: + while (input->BytesUntilLimit() > 0) { + int value; + if (!WireFormatLite::ReadPrimitive<int, WireFormatLite::TYPE_ENUM>( + input, &value)) + return false; + if (extension.enum_validity_check.func( + extension.enum_validity_check.arg, value)) { + AddEnum(number, WireFormatLite::TYPE_ENUM, extension.is_packed, + value, extension.descriptor); + } else { + // Invalid value. Treat as unknown. + field_skipper->SkipUnknownEnum(number, value); + } + } + break; + + case WireFormatLite::TYPE_STRING: + case WireFormatLite::TYPE_BYTES: + case WireFormatLite::TYPE_GROUP: + case WireFormatLite::TYPE_MESSAGE: + GOOGLE_LOG(FATAL) << "Non-primitive types can't be packed."; + break; + } + + input->PopLimit(limit); + } else { + switch (extension.type) { +#define HANDLE_TYPE(UPPERCASE, CPP_CAMELCASE, CPP_LOWERCASE) \ + case WireFormatLite::TYPE_##UPPERCASE: { \ + CPP_LOWERCASE value; \ + if (!WireFormatLite::ReadPrimitive<CPP_LOWERCASE, \ + WireFormatLite::TYPE_##UPPERCASE>( \ + input, &value)) \ + return false; \ + if (extension.is_repeated) { \ + Add##CPP_CAMELCASE(number, WireFormatLite::TYPE_##UPPERCASE, \ + extension.is_packed, value, extension.descriptor); \ + } else { \ + Set##CPP_CAMELCASE(number, WireFormatLite::TYPE_##UPPERCASE, value, \ + extension.descriptor); \ + } \ + } break + + HANDLE_TYPE(INT32, Int32, arc_i32); + HANDLE_TYPE(INT64, Int64, arc_i64); + HANDLE_TYPE(UINT32, UInt32, arc_ui32); + HANDLE_TYPE(UINT64, UInt64, arc_ui64); + HANDLE_TYPE(SINT32, Int32, arc_i32); + HANDLE_TYPE(SINT64, Int64, arc_i64); + HANDLE_TYPE(FIXED32, UInt32, arc_ui32); + HANDLE_TYPE(FIXED64, UInt64, arc_ui64); + HANDLE_TYPE(SFIXED32, Int32, arc_i32); + HANDLE_TYPE(SFIXED64, Int64, arc_i64); + HANDLE_TYPE(FLOAT, Float, float); + HANDLE_TYPE(DOUBLE, Double, double); + HANDLE_TYPE(BOOL, Bool, bool); +#undef HANDLE_TYPE + + case WireFormatLite::TYPE_ENUM: { + int value; + if (!WireFormatLite::ReadPrimitive<int, WireFormatLite::TYPE_ENUM>( + input, &value)) + return false; + + if (!extension.enum_validity_check.func( + extension.enum_validity_check.arg, value)) { + // Invalid value. Treat as unknown. + field_skipper->SkipUnknownEnum(number, value); + } else if (extension.is_repeated) { + AddEnum(number, WireFormatLite::TYPE_ENUM, extension.is_packed, value, + extension.descriptor); + } else { + SetEnum(number, WireFormatLite::TYPE_ENUM, value, + extension.descriptor); + } + break; + } + + case WireFormatLite::TYPE_STRING: { + TProtoStringType* value = + extension.is_repeated + ? AddString(number, WireFormatLite::TYPE_STRING, + extension.descriptor) + : MutableString(number, WireFormatLite::TYPE_STRING, + extension.descriptor); + if (!WireFormatLite::ReadString(input, value)) return false; + break; + } + + case WireFormatLite::TYPE_BYTES: { + TProtoStringType* value = + extension.is_repeated + ? AddString(number, WireFormatLite::TYPE_BYTES, + extension.descriptor) + : MutableString(number, WireFormatLite::TYPE_BYTES, + extension.descriptor); + if (!WireFormatLite::ReadBytes(input, value)) return false; + break; + } + + case WireFormatLite::TYPE_GROUP: { + MessageLite* value = + extension.is_repeated + ? AddMessage(number, WireFormatLite::TYPE_GROUP, + *extension.message_info.prototype, + extension.descriptor) + : MutableMessage(number, WireFormatLite::TYPE_GROUP, + *extension.message_info.prototype, + extension.descriptor); + if (!WireFormatLite::ReadGroup(number, input, value)) return false; + break; + } + + case WireFormatLite::TYPE_MESSAGE: { + MessageLite* value = + extension.is_repeated + ? AddMessage(number, WireFormatLite::TYPE_MESSAGE, + *extension.message_info.prototype, + extension.descriptor) + : MutableMessage(number, WireFormatLite::TYPE_MESSAGE, + *extension.message_info.prototype, + extension.descriptor); + if (!WireFormatLite::ReadMessage(input, value)) return false; + break; + } + } + } + + return true; +} + +bool ExtensionSet::ParseField(arc_ui32 tag, io::CodedInputStream* input, + const MessageLite* extendee) { + FieldSkipper skipper; + GeneratedExtensionFinder finder(extendee); + return ParseField(tag, input, &finder, &skipper); +} + +bool ExtensionSet::ParseField(arc_ui32 tag, io::CodedInputStream* input, + const MessageLite* extendee, + io::CodedOutputStream* unknown_fields) { + CodedOutputStreamFieldSkipper skipper(unknown_fields); + GeneratedExtensionFinder finder(extendee); + return ParseField(tag, input, &finder, &skipper); +} + +bool ExtensionSet::ParseMessageSetLite(io::CodedInputStream* input, + ExtensionFinder* extension_finder, + FieldSkipper* field_skipper) { + while (true) { + const arc_ui32 tag = input->ReadTag(); + switch (tag) { + case 0: + return true; + case WireFormatLite::kMessageSetItemStartTag: + if (!ParseMessageSetItemLite(input, extension_finder, field_skipper)) { + return false; + } + break; + default: + if (!ParseField(tag, input, extension_finder, field_skipper)) { + return false; + } + break; + } + } +} + +bool ExtensionSet::ParseMessageSetItemLite(io::CodedInputStream* input, + ExtensionFinder* extension_finder, + FieldSkipper* field_skipper) { + struct MSLite { + bool ParseField(int type_id, io::CodedInputStream* input) { + return me->ParseField( + WireFormatLite::WIRETYPE_LENGTH_DELIMITED + 8 * type_id, input, + extension_finder, field_skipper); + } + + bool SkipField(arc_ui32 tag, io::CodedInputStream* input) { + return field_skipper->SkipField(input, tag); + } + + ExtensionSet* me; + ExtensionFinder* extension_finder; + FieldSkipper* field_skipper; + }; + + return ParseMessageSetItemImpl(input, + MSLite{this, extension_finder, field_skipper}); +} + +bool ExtensionSet::ParseMessageSet(io::CodedInputStream* input, + const MessageLite* extendee, + TProtoStringType* unknown_fields) { + io::StringOutputStream zcis(unknown_fields); + io::CodedOutputStream output(&zcis); + CodedOutputStreamFieldSkipper skipper(&output); + GeneratedExtensionFinder finder(extendee); + return ParseMessageSetLite(input, &finder, &skipper); +} + +uint8_t* ExtensionSet::_InternalSerializeImpl( + const MessageLite* extendee, int start_field_number, int end_field_number, + uint8_t* target, io::EpsCopyOutputStream* stream) const { + if (PROTOBUF_PREDICT_FALSE(is_large())) { + const auto& end = map_.large->end(); + for (auto it = map_.large->lower_bound(start_field_number); + it != end && it->first < end_field_number; ++it) { + target = it->second.InternalSerializeFieldWithCachedSizesToArray( + extendee, this, it->first, target, stream); + } + return target; + } + const KeyValue* end = flat_end(); + for (const KeyValue* it = std::lower_bound( + flat_begin(), end, start_field_number, KeyValue::FirstComparator()); + it != end && it->first < end_field_number; ++it) { + target = it->second.InternalSerializeFieldWithCachedSizesToArray( + extendee, this, it->first, target, stream); + } + return target; +} + +uint8_t* ExtensionSet::InternalSerializeMessageSetWithCachedSizesToArray( + const MessageLite* extendee, uint8_t* target, + io::EpsCopyOutputStream* stream) const { + const ExtensionSet* extension_set = this; + ForEach([&target, extendee, stream, extension_set](int number, + const Extension& ext) { + target = ext.InternalSerializeMessageSetItemWithCachedSizesToArray( + extendee, extension_set, number, target, stream); + }); + return target; +} + +size_t ExtensionSet::ByteSize() const { + size_t total_size = 0; + ForEach([&total_size](int number, const Extension& ext) { + total_size += ext.ByteSize(number); + }); + return total_size; +} + +// Defined in extension_set_heavy.cc. +// int ExtensionSet::SpaceUsedExcludingSelf() const + +bool ExtensionSet::MaybeNewExtension(int number, + const FieldDescriptor* descriptor, + Extension** result) { + bool extension_is_new = false; + std::tie(*result, extension_is_new) = Insert(number); + (*result)->descriptor = descriptor; + return extension_is_new; +} + +// =================================================================== +// Methods of ExtensionSet::Extension + +void ExtensionSet::Extension::Clear() { + if (is_repeated) { + switch (cpp_type(type)) { +#define HANDLE_TYPE(UPPERCASE, LOWERCASE) \ + case WireFormatLite::CPPTYPE_##UPPERCASE: \ + repeated_##LOWERCASE##_value->Clear(); \ + break + + HANDLE_TYPE(INT32, arc_i32); + HANDLE_TYPE(INT64, arc_i64); + HANDLE_TYPE(UINT32, arc_ui32); + HANDLE_TYPE(UINT64, arc_ui64); + HANDLE_TYPE(FLOAT, float); + HANDLE_TYPE(DOUBLE, double); + HANDLE_TYPE(BOOL, bool); + HANDLE_TYPE(ENUM, enum); + HANDLE_TYPE(STRING, string); + HANDLE_TYPE(MESSAGE, message); +#undef HANDLE_TYPE + } + } else { + if (!is_cleared) { + switch (cpp_type(type)) { + case WireFormatLite::CPPTYPE_STRING: + string_value->clear(); + break; + case WireFormatLite::CPPTYPE_MESSAGE: + if (is_lazy) { + lazymessage_value->Clear(); + } else { + message_value->Clear(); + } + break; + default: + // No need to do anything. Get*() will return the default value + // as long as is_cleared is true and Set*() will overwrite the + // previous value. + break; + } + + is_cleared = true; + } + } +} + +size_t ExtensionSet::Extension::ByteSize(int number) const { + size_t result = 0; + + if (is_repeated) { + if (is_packed) { + switch (real_type(type)) { +#define HANDLE_TYPE(UPPERCASE, CAMELCASE, LOWERCASE) \ + case WireFormatLite::TYPE_##UPPERCASE: \ + for (int i = 0; i < repeated_##LOWERCASE##_value->size(); i++) { \ + result += WireFormatLite::CAMELCASE##Size( \ + repeated_##LOWERCASE##_value->Get(i)); \ + } \ + break + + HANDLE_TYPE(INT32, Int32, arc_i32); + HANDLE_TYPE(INT64, Int64, arc_i64); + HANDLE_TYPE(UINT32, UInt32, arc_ui32); + HANDLE_TYPE(UINT64, UInt64, arc_ui64); + HANDLE_TYPE(SINT32, SInt32, arc_i32); + HANDLE_TYPE(SINT64, SInt64, arc_i64); + HANDLE_TYPE(ENUM, Enum, enum); +#undef HANDLE_TYPE + + // Stuff with fixed size. +#define HANDLE_TYPE(UPPERCASE, CAMELCASE, LOWERCASE) \ + case WireFormatLite::TYPE_##UPPERCASE: \ + result += WireFormatLite::k##CAMELCASE##Size * \ + FromIntSize(repeated_##LOWERCASE##_value->size()); \ + break + HANDLE_TYPE(FIXED32, Fixed32, arc_ui32); + HANDLE_TYPE(FIXED64, Fixed64, arc_ui64); + HANDLE_TYPE(SFIXED32, SFixed32, arc_i32); + HANDLE_TYPE(SFIXED64, SFixed64, arc_i64); + HANDLE_TYPE(FLOAT, Float, float); + HANDLE_TYPE(DOUBLE, Double, double); + HANDLE_TYPE(BOOL, Bool, bool); +#undef HANDLE_TYPE + + case WireFormatLite::TYPE_STRING: + case WireFormatLite::TYPE_BYTES: + case WireFormatLite::TYPE_GROUP: + case WireFormatLite::TYPE_MESSAGE: + GOOGLE_LOG(FATAL) << "Non-primitive types can't be packed."; + break; + } + + cached_size = ToCachedSize(result); + if (result > 0) { + result += io::CodedOutputStream::VarintSize32(result); + result += io::CodedOutputStream::VarintSize32(WireFormatLite::MakeTag( + number, WireFormatLite::WIRETYPE_LENGTH_DELIMITED)); + } + } else { + size_t tag_size = WireFormatLite::TagSize(number, real_type(type)); + + switch (real_type(type)) { +#define HANDLE_TYPE(UPPERCASE, CAMELCASE, LOWERCASE) \ + case WireFormatLite::TYPE_##UPPERCASE: \ + result += tag_size * FromIntSize(repeated_##LOWERCASE##_value->size()); \ + for (int i = 0; i < repeated_##LOWERCASE##_value->size(); i++) { \ + result += WireFormatLite::CAMELCASE##Size( \ + repeated_##LOWERCASE##_value->Get(i)); \ + } \ + break + + HANDLE_TYPE(INT32, Int32, arc_i32); + HANDLE_TYPE(INT64, Int64, arc_i64); + HANDLE_TYPE(UINT32, UInt32, arc_ui32); + HANDLE_TYPE(UINT64, UInt64, arc_ui64); + HANDLE_TYPE(SINT32, SInt32, arc_i32); + HANDLE_TYPE(SINT64, SInt64, arc_i64); + HANDLE_TYPE(STRING, String, string); + HANDLE_TYPE(BYTES, Bytes, string); + HANDLE_TYPE(ENUM, Enum, enum); + HANDLE_TYPE(GROUP, Group, message); + HANDLE_TYPE(MESSAGE, Message, message); +#undef HANDLE_TYPE + + // Stuff with fixed size. +#define HANDLE_TYPE(UPPERCASE, CAMELCASE, LOWERCASE) \ + case WireFormatLite::TYPE_##UPPERCASE: \ + result += (tag_size + WireFormatLite::k##CAMELCASE##Size) * \ + FromIntSize(repeated_##LOWERCASE##_value->size()); \ + break + HANDLE_TYPE(FIXED32, Fixed32, arc_ui32); + HANDLE_TYPE(FIXED64, Fixed64, arc_ui64); + HANDLE_TYPE(SFIXED32, SFixed32, arc_i32); + HANDLE_TYPE(SFIXED64, SFixed64, arc_i64); + HANDLE_TYPE(FLOAT, Float, float); + HANDLE_TYPE(DOUBLE, Double, double); + HANDLE_TYPE(BOOL, Bool, bool); +#undef HANDLE_TYPE + } + } + } else if (!is_cleared) { + result += WireFormatLite::TagSize(number, real_type(type)); + switch (real_type(type)) { +#define HANDLE_TYPE(UPPERCASE, CAMELCASE, LOWERCASE) \ + case WireFormatLite::TYPE_##UPPERCASE: \ + result += WireFormatLite::CAMELCASE##Size(LOWERCASE); \ + break + + HANDLE_TYPE(INT32, Int32, arc_i32_value); + HANDLE_TYPE(INT64, Int64, arc_i64_value); + HANDLE_TYPE(UINT32, UInt32, arc_ui32_value); + HANDLE_TYPE(UINT64, UInt64, arc_ui64_value); + HANDLE_TYPE(SINT32, SInt32, arc_i32_value); + HANDLE_TYPE(SINT64, SInt64, arc_i64_value); + HANDLE_TYPE(STRING, String, *string_value); + HANDLE_TYPE(BYTES, Bytes, *string_value); + HANDLE_TYPE(ENUM, Enum, enum_value); + HANDLE_TYPE(GROUP, Group, *message_value); +#undef HANDLE_TYPE + case WireFormatLite::TYPE_MESSAGE: { + if (is_lazy) { + size_t size = lazymessage_value->ByteSizeLong(); + result += io::CodedOutputStream::VarintSize32(size) + size; + } else { + result += WireFormatLite::MessageSize(*message_value); + } + break; + } + + // Stuff with fixed size. +#define HANDLE_TYPE(UPPERCASE, CAMELCASE) \ + case WireFormatLite::TYPE_##UPPERCASE: \ + result += WireFormatLite::k##CAMELCASE##Size; \ + break + HANDLE_TYPE(FIXED32, Fixed32); + HANDLE_TYPE(FIXED64, Fixed64); + HANDLE_TYPE(SFIXED32, SFixed32); + HANDLE_TYPE(SFIXED64, SFixed64); + HANDLE_TYPE(FLOAT, Float); + HANDLE_TYPE(DOUBLE, Double); + HANDLE_TYPE(BOOL, Bool); +#undef HANDLE_TYPE + } + } + + return result; +} + +int ExtensionSet::Extension::GetSize() const { + GOOGLE_DCHECK(is_repeated); + switch (cpp_type(type)) { +#define HANDLE_TYPE(UPPERCASE, LOWERCASE) \ + case WireFormatLite::CPPTYPE_##UPPERCASE: \ + return repeated_##LOWERCASE##_value->size() + + HANDLE_TYPE(INT32, arc_i32); + HANDLE_TYPE(INT64, arc_i64); + HANDLE_TYPE(UINT32, arc_ui32); + HANDLE_TYPE(UINT64, arc_ui64); + HANDLE_TYPE(FLOAT, float); + HANDLE_TYPE(DOUBLE, double); + HANDLE_TYPE(BOOL, bool); + HANDLE_TYPE(ENUM, enum); + HANDLE_TYPE(STRING, string); + HANDLE_TYPE(MESSAGE, message); +#undef HANDLE_TYPE + } + + GOOGLE_LOG(FATAL) << "Can't get here."; + return 0; +} + +// This function deletes all allocated objects. This function should be only +// called if the Extension was created without an arena. +void ExtensionSet::Extension::Free() { + if (is_repeated) { + switch (cpp_type(type)) { +#define HANDLE_TYPE(UPPERCASE, LOWERCASE) \ + case WireFormatLite::CPPTYPE_##UPPERCASE: \ + delete repeated_##LOWERCASE##_value; \ + break + + HANDLE_TYPE(INT32, arc_i32); + HANDLE_TYPE(INT64, arc_i64); + HANDLE_TYPE(UINT32, arc_ui32); + HANDLE_TYPE(UINT64, arc_ui64); + HANDLE_TYPE(FLOAT, float); + HANDLE_TYPE(DOUBLE, double); + HANDLE_TYPE(BOOL, bool); + HANDLE_TYPE(ENUM, enum); + HANDLE_TYPE(STRING, string); + HANDLE_TYPE(MESSAGE, message); +#undef HANDLE_TYPE + } + } else { + switch (cpp_type(type)) { + case WireFormatLite::CPPTYPE_STRING: + delete string_value; + break; + case WireFormatLite::CPPTYPE_MESSAGE: + if (is_lazy) { + delete lazymessage_value; + } else { + delete message_value; + } + break; + default: + break; + } + } +} + +// Defined in extension_set_heavy.cc. +// int ExtensionSet::Extension::SpaceUsedExcludingSelf() const + +bool ExtensionSet::Extension::IsInitialized() const { + if (cpp_type(type) == WireFormatLite::CPPTYPE_MESSAGE) { + if (is_repeated) { + for (int i = 0; i < repeated_message_value->size(); i++) { + if (!repeated_message_value->Get(i).IsInitialized()) { + return false; + } + } + } else { + if (!is_cleared) { + if (is_lazy) { + if (!lazymessage_value->IsInitialized()) return false; + } else { + if (!message_value->IsInitialized()) return false; + } + } + } + } + return true; +} + +// Dummy key method to avoid weak vtable. +void ExtensionSet::LazyMessageExtension::UnusedKeyMethod() {} + +const ExtensionSet::Extension* ExtensionSet::FindOrNull(int key) const { + if (flat_size_ == 0) { + return nullptr; + } else if (PROTOBUF_PREDICT_TRUE(!is_large())) { + auto it = std::lower_bound(flat_begin(), flat_end() - 1, key, + KeyValue::FirstComparator()); + return it->first == key ? &it->second : nullptr; + } else { + return FindOrNullInLargeMap(key); + } +} + +const ExtensionSet::Extension* ExtensionSet::FindOrNullInLargeMap( + int key) const { + assert(is_large()); + LargeMap::const_iterator it = map_.large->find(key); + if (it != map_.large->end()) { + return &it->second; + } + return nullptr; +} + +ExtensionSet::Extension* ExtensionSet::FindOrNull(int key) { + const auto* const_this = this; + return const_cast<ExtensionSet::Extension*>(const_this->FindOrNull(key)); +} + +ExtensionSet::Extension* ExtensionSet::FindOrNullInLargeMap(int key) { + const auto* const_this = this; + return const_cast<ExtensionSet::Extension*>( + const_this->FindOrNullInLargeMap(key)); +} + +std::pair<ExtensionSet::Extension*, bool> ExtensionSet::Insert(int key) { + if (PROTOBUF_PREDICT_FALSE(is_large())) { + auto maybe = map_.large->insert({key, Extension()}); + return {&maybe.first->second, maybe.second}; + } + KeyValue* end = flat_end(); + KeyValue* it = + std::lower_bound(flat_begin(), end, key, KeyValue::FirstComparator()); + if (it != end && it->first == key) { + return {&it->second, false}; + } + if (flat_size_ < flat_capacity_) { + std::copy_backward(it, end, end + 1); + ++flat_size_; + it->first = key; + it->second = Extension(); + return {&it->second, true}; + } + GrowCapacity(flat_size_ + 1); + return Insert(key); +} + +void ExtensionSet::GrowCapacity(size_t minimum_new_capacity) { + if (PROTOBUF_PREDICT_FALSE(is_large())) { + return; // LargeMap does not have a "reserve" method. + } + if (flat_capacity_ >= minimum_new_capacity) { + return; + } + + auto new_flat_capacity = flat_capacity_; + do { + new_flat_capacity = new_flat_capacity == 0 ? 1 : new_flat_capacity * 4; + } while (new_flat_capacity < minimum_new_capacity); + + const KeyValue* begin = flat_begin(); + const KeyValue* end = flat_end(); + AllocatedData new_map; + if (new_flat_capacity > kMaximumFlatCapacity) { + new_map.large = Arena::Create<LargeMap>(arena_); + LargeMap::iterator hint = new_map.large->begin(); + for (const KeyValue* it = begin; it != end; ++it) { + hint = new_map.large->insert(hint, {it->first, it->second}); + } + flat_size_ = static_cast<uint16_t>(-1); + GOOGLE_DCHECK(is_large()); + } else { + new_map.flat = Arena::CreateArray<KeyValue>(arena_, new_flat_capacity); + std::copy(begin, end, new_map.flat); + } + + if (arena_ == nullptr) { + DeleteFlatMap(begin, flat_capacity_); + } + flat_capacity_ = new_flat_capacity; + map_ = new_map; +} + +#if (__cplusplus < 201703) && \ + (!defined(_MSC_VER) || (_MSC_VER >= 1900 && _MSC_VER < 1912)) +// static +constexpr uint16_t ExtensionSet::kMaximumFlatCapacity; +#endif // (__cplusplus < 201703) && (!defined(_MSC_VER) || (_MSC_VER >= 1900 + // && _MSC_VER < 1912)) + +void ExtensionSet::Erase(int key) { + if (PROTOBUF_PREDICT_FALSE(is_large())) { + map_.large->erase(key); + return; + } + KeyValue* end = flat_end(); + KeyValue* it = + std::lower_bound(flat_begin(), end, key, KeyValue::FirstComparator()); + if (it != end && it->first == key) { + std::copy(it + 1, end, it); + --flat_size_; + } +} + +// ================================================================== +// Default repeated field instances for iterator-compatible accessors + +const RepeatedPrimitiveDefaults* RepeatedPrimitiveDefaults::default_instance() { + static auto instance = OnShutdownDelete(new RepeatedPrimitiveDefaults); + return instance; +} + +const RepeatedStringTypeTraits::RepeatedFieldType* +RepeatedStringTypeTraits::GetDefaultRepeatedField() { + static auto instance = OnShutdownDelete(new RepeatedFieldType); + return instance; +} + +uint8_t* ExtensionSet::Extension::InternalSerializeFieldWithCachedSizesToArray( + const MessageLite* extendee, const ExtensionSet* extension_set, int number, + uint8_t* target, io::EpsCopyOutputStream* stream) const { + if (is_repeated) { + if (is_packed) { + if (cached_size == 0) return target; + + target = stream->EnsureSpace(target); + target = WireFormatLite::WriteTagToArray( + number, WireFormatLite::WIRETYPE_LENGTH_DELIMITED, target); + target = WireFormatLite::WriteInt32NoTagToArray(cached_size, target); + + switch (real_type(type)) { +#define HANDLE_TYPE(UPPERCASE, CAMELCASE, LOWERCASE) \ + case WireFormatLite::TYPE_##UPPERCASE: \ + for (int i = 0; i < repeated_##LOWERCASE##_value->size(); i++) { \ + target = stream->EnsureSpace(target); \ + target = WireFormatLite::Write##CAMELCASE##NoTagToArray( \ + repeated_##LOWERCASE##_value->Get(i), target); \ + } \ + break + + HANDLE_TYPE(INT32, Int32, arc_i32); + HANDLE_TYPE(INT64, Int64, arc_i64); + HANDLE_TYPE(UINT32, UInt32, arc_ui32); + HANDLE_TYPE(UINT64, UInt64, arc_ui64); + HANDLE_TYPE(SINT32, SInt32, arc_i32); + HANDLE_TYPE(SINT64, SInt64, arc_i64); + HANDLE_TYPE(FIXED32, Fixed32, arc_ui32); + HANDLE_TYPE(FIXED64, Fixed64, arc_ui64); + HANDLE_TYPE(SFIXED32, SFixed32, arc_i32); + HANDLE_TYPE(SFIXED64, SFixed64, arc_i64); + HANDLE_TYPE(FLOAT, Float, float); + HANDLE_TYPE(DOUBLE, Double, double); + HANDLE_TYPE(BOOL, Bool, bool); + HANDLE_TYPE(ENUM, Enum, enum); +#undef HANDLE_TYPE + + case WireFormatLite::TYPE_STRING: + case WireFormatLite::TYPE_BYTES: + case WireFormatLite::TYPE_GROUP: + case WireFormatLite::TYPE_MESSAGE: + GOOGLE_LOG(FATAL) << "Non-primitive types can't be packed."; + break; + } + } else { + switch (real_type(type)) { +#define HANDLE_TYPE(UPPERCASE, CAMELCASE, LOWERCASE) \ + case WireFormatLite::TYPE_##UPPERCASE: \ + for (int i = 0; i < repeated_##LOWERCASE##_value->size(); i++) { \ + target = stream->EnsureSpace(target); \ + target = WireFormatLite::Write##CAMELCASE##ToArray( \ + number, repeated_##LOWERCASE##_value->Get(i), target); \ + } \ + break + + HANDLE_TYPE(INT32, Int32, arc_i32); + HANDLE_TYPE(INT64, Int64, arc_i64); + HANDLE_TYPE(UINT32, UInt32, arc_ui32); + HANDLE_TYPE(UINT64, UInt64, arc_ui64); + HANDLE_TYPE(SINT32, SInt32, arc_i32); + HANDLE_TYPE(SINT64, SInt64, arc_i64); + HANDLE_TYPE(FIXED32, Fixed32, arc_ui32); + HANDLE_TYPE(FIXED64, Fixed64, arc_ui64); + HANDLE_TYPE(SFIXED32, SFixed32, arc_i32); + HANDLE_TYPE(SFIXED64, SFixed64, arc_i64); + HANDLE_TYPE(FLOAT, Float, float); + HANDLE_TYPE(DOUBLE, Double, double); + HANDLE_TYPE(BOOL, Bool, bool); + HANDLE_TYPE(ENUM, Enum, enum); +#undef HANDLE_TYPE +#define HANDLE_TYPE(UPPERCASE, CAMELCASE, LOWERCASE) \ + case WireFormatLite::TYPE_##UPPERCASE: \ + for (int i = 0; i < repeated_##LOWERCASE##_value->size(); i++) { \ + target = stream->EnsureSpace(target); \ + target = stream->WriteString( \ + number, repeated_##LOWERCASE##_value->Get(i), target); \ + } \ + break + HANDLE_TYPE(STRING, String, string); + HANDLE_TYPE(BYTES, Bytes, string); +#undef HANDLE_TYPE +#define HANDLE_TYPE(UPPERCASE, CAMELCASE, LOWERCASE) \ + case WireFormatLite::TYPE_##UPPERCASE: \ + for (int i = 0; i < repeated_##LOWERCASE##_value->size(); i++) { \ + target = stream->EnsureSpace(target); \ + target = WireFormatLite::InternalWrite##CAMELCASE( \ + number, repeated_##LOWERCASE##_value->Get(i), target, stream); \ + } \ + break + + HANDLE_TYPE(GROUP, Group, message); + HANDLE_TYPE(MESSAGE, Message, message); +#undef HANDLE_TYPE + } + } + } else if (!is_cleared) { + switch (real_type(type)) { +#define HANDLE_TYPE(UPPERCASE, CAMELCASE, VALUE) \ + case WireFormatLite::TYPE_##UPPERCASE: \ + target = stream->EnsureSpace(target); \ + target = WireFormatLite::Write##CAMELCASE##ToArray(number, VALUE, target); \ + break + + HANDLE_TYPE(INT32, Int32, arc_i32_value); + HANDLE_TYPE(INT64, Int64, arc_i64_value); + HANDLE_TYPE(UINT32, UInt32, arc_ui32_value); + HANDLE_TYPE(UINT64, UInt64, arc_ui64_value); + HANDLE_TYPE(SINT32, SInt32, arc_i32_value); + HANDLE_TYPE(SINT64, SInt64, arc_i64_value); + HANDLE_TYPE(FIXED32, Fixed32, arc_ui32_value); + HANDLE_TYPE(FIXED64, Fixed64, arc_ui64_value); + HANDLE_TYPE(SFIXED32, SFixed32, arc_i32_value); + HANDLE_TYPE(SFIXED64, SFixed64, arc_i64_value); + HANDLE_TYPE(FLOAT, Float, float_value); + HANDLE_TYPE(DOUBLE, Double, double_value); + HANDLE_TYPE(BOOL, Bool, bool_value); + HANDLE_TYPE(ENUM, Enum, enum_value); +#undef HANDLE_TYPE +#define HANDLE_TYPE(UPPERCASE, CAMELCASE, VALUE) \ + case WireFormatLite::TYPE_##UPPERCASE: \ + target = stream->EnsureSpace(target); \ + target = stream->WriteString(number, VALUE, target); \ + break + HANDLE_TYPE(STRING, String, *string_value); + HANDLE_TYPE(BYTES, Bytes, *string_value); +#undef HANDLE_TYPE + case WireFormatLite::TYPE_GROUP: + target = stream->EnsureSpace(target); + target = WireFormatLite::InternalWriteGroup(number, *message_value, + target, stream); + break; + case WireFormatLite::TYPE_MESSAGE: + if (is_lazy) { + const auto* prototype = + extension_set->GetPrototypeForLazyMessage(extendee, number); + target = lazymessage_value->WriteMessageToArray(prototype, number, + target, stream); + } else { + target = stream->EnsureSpace(target); + target = WireFormatLite::InternalWriteMessage(number, *message_value, + target, stream); + } + break; + } + } + return target; +} + +const MessageLite* ExtensionSet::GetPrototypeForLazyMessage( + const MessageLite* extendee, int number) const { + GeneratedExtensionFinder finder(extendee); + bool was_packed_on_wire = false; + ExtensionInfo extension_info; + if (!FindExtensionInfoFromFieldNumber( + WireFormatLite::WireType::WIRETYPE_LENGTH_DELIMITED, number, &finder, + &extension_info, &was_packed_on_wire)) { + return nullptr; + } + return extension_info.message_info.prototype; +} + +uint8_t* +ExtensionSet::Extension::InternalSerializeMessageSetItemWithCachedSizesToArray( + const MessageLite* extendee, const ExtensionSet* extension_set, int number, + uint8_t* target, io::EpsCopyOutputStream* stream) const { + if (type != WireFormatLite::TYPE_MESSAGE || is_repeated) { + // Not a valid MessageSet extension, but serialize it the normal way. + GOOGLE_LOG(WARNING) << "Invalid message set extension."; + return InternalSerializeFieldWithCachedSizesToArray(extendee, extension_set, + number, target, stream); + } + + if (is_cleared) return target; + + target = stream->EnsureSpace(target); + // Start group. + target = io::CodedOutputStream::WriteTagToArray( + WireFormatLite::kMessageSetItemStartTag, target); + // Write type ID. + target = WireFormatLite::WriteUInt32ToArray( + WireFormatLite::kMessageSetTypeIdNumber, number, target); + // Write message. + if (is_lazy) { + const auto* prototype = + extension_set->GetPrototypeForLazyMessage(extendee, number); + target = lazymessage_value->WriteMessageToArray( + prototype, WireFormatLite::kMessageSetMessageNumber, target, stream); + } else { + target = WireFormatLite::InternalWriteMessage( + WireFormatLite::kMessageSetMessageNumber, *message_value, target, + stream); + } + // End group. + target = stream->EnsureSpace(target); + target = io::CodedOutputStream::WriteTagToArray( + WireFormatLite::kMessageSetItemEndTag, target); + return target; +} + +size_t ExtensionSet::Extension::MessageSetItemByteSize(int number) const { + if (type != WireFormatLite::TYPE_MESSAGE || is_repeated) { + // Not a valid MessageSet extension, but compute the byte size for it the + // normal way. + return ByteSize(number); + } + + if (is_cleared) return 0; + + size_t our_size = WireFormatLite::kMessageSetItemTagsSize; + + // type_id + our_size += io::CodedOutputStream::VarintSize32(number); + + // message + size_t message_size = 0; + if (is_lazy) { + message_size = lazymessage_value->ByteSizeLong(); + } else { + message_size = message_value->ByteSizeLong(); + } + + our_size += io::CodedOutputStream::VarintSize32(message_size); + our_size += message_size; + + return our_size; +} + +size_t ExtensionSet::MessageSetByteSize() const { + size_t total_size = 0; + ForEach([&total_size](int number, const Extension& ext) { + total_size += ext.MessageSetItemByteSize(number); + }); + return total_size; +} + + +} // namespace internal +} // namespace protobuf +} // namespace google + +#include <google/protobuf/port_undef.inc> diff --git a/contrib/libs/protobuf_old/src/google/protobuf/extension_set.h b/contrib/libs/protobuf_old/src/google/protobuf/extension_set.h new file mode 100644 index 0000000000..1ea91bfa32 --- /dev/null +++ b/contrib/libs/protobuf_old/src/google/protobuf/extension_set.h @@ -0,0 +1,1560 @@ +// 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: kenton@google.com (Kenton Varda) +// Based on original Protocol Buffers design by +// Sanjay Ghemawat, Jeff Dean, and others. +// +// This header is logically internal, but is made public because it is used +// from protocol-compiler-generated code, which may reside in other components. + +#ifndef GOOGLE_PROTOBUF_EXTENSION_SET_H__ +#define GOOGLE_PROTOBUF_EXTENSION_SET_H__ + +#include <algorithm> +#include <cassert> +#include <map> +#include <string> +#include <utility> +#include <vector> + +#include <google/protobuf/stubs/common.h> +#include <google/protobuf/stubs/logging.h> +#include <google/protobuf/parse_context.h> +#include <google/protobuf/io/coded_stream.h> +#include <google/protobuf/port.h> +#include <google/protobuf/repeated_field.h> +#include <google/protobuf/wire_format_lite.h> + +// clang-format off +#include <google/protobuf/port_def.inc> // Must be last +// clang-format on + +#ifdef SWIG +#error "You cannot SWIG proto headers" +#endif + +namespace google { +namespace protobuf { +class Arena; +class Descriptor; // descriptor.h +class FieldDescriptor; // descriptor.h +class DescriptorPool; // descriptor.h +class MessageLite; // message_lite.h +class Message; // message.h +class MessageFactory; // message.h +class Reflection; // message.h +class UnknownFieldSet; // unknown_field_set.h +namespace internal { +class FieldSkipper; // wire_format_lite.h +} // namespace internal +} // namespace protobuf +} // namespace google + +namespace google { +namespace protobuf { +namespace internal { + +class InternalMetadata; + +// Used to store values of type WireFormatLite::FieldType without having to +// #include wire_format_lite.h. Also, ensures that we use only one byte to +// store these values, which is important to keep the layout of +// ExtensionSet::Extension small. +typedef uint8_t FieldType; + +// A function which, given an integer value, returns true if the number +// matches one of the defined values for the corresponding enum type. This +// is used with RegisterEnumExtension, below. +typedef bool EnumValidityFunc(int number); + +// Version of the above which takes an argument. This is needed to deal with +// extensions that are not compiled in. +typedef bool EnumValidityFuncWithArg(const void* arg, int number); + +// Information about a registered extension. +struct ExtensionInfo { + constexpr ExtensionInfo() : enum_validity_check() {} + constexpr ExtensionInfo(const MessageLite* extendee, int param_number, + FieldType type_param, bool isrepeated, bool ispacked) + : message(extendee), + number(param_number), + type(type_param), + is_repeated(isrepeated), + is_packed(ispacked), + enum_validity_check() {} + + const MessageLite* message = nullptr; + int number = 0; + + FieldType type = 0; + bool is_repeated = false; + bool is_packed = false; + + struct EnumValidityCheck { + EnumValidityFuncWithArg* func; + const void* arg; + }; + + struct MessageInfo { + const MessageLite* prototype; + }; + + union { + EnumValidityCheck enum_validity_check; + MessageInfo message_info; + }; + + // The descriptor for this extension, if one exists and is known. May be + // nullptr. Must not be nullptr if the descriptor for the extension does not + // live in the same pool as the descriptor for the containing type. + const FieldDescriptor* descriptor = nullptr; +}; + +// Abstract interface for an object which looks up extension definitions. Used +// when parsing. +class PROTOBUF_EXPORT ExtensionFinder { + public: + virtual ~ExtensionFinder(); + + // Find the extension with the given containing type and number. + virtual bool Find(int number, ExtensionInfo* output) = 0; +}; + +// Implementation of ExtensionFinder which finds extensions defined in .proto +// files which have been compiled into the binary. +class PROTOBUF_EXPORT GeneratedExtensionFinder : public ExtensionFinder { + public: + explicit GeneratedExtensionFinder(const MessageLite* extendee) + : extendee_(extendee) {} + ~GeneratedExtensionFinder() override {} + + // Returns true and fills in *output if found, otherwise returns false. + bool Find(int number, ExtensionInfo* output) override; + + private: + const MessageLite* extendee_; +}; + +// A FieldSkipper used for parsing MessageSet. +class MessageSetFieldSkipper; + +// Note: extension_set_heavy.cc defines DescriptorPoolExtensionFinder for +// finding extensions from a DescriptorPool. + +// This is an internal helper class intended for use within the protocol buffer +// library and generated classes. Clients should not use it directly. Instead, +// use the generated accessors such as GetExtension() of the class being +// extended. +// +// This class manages extensions for a protocol message object. The +// message's HasExtension(), GetExtension(), MutableExtension(), and +// ClearExtension() methods are just thin wrappers around the embedded +// ExtensionSet. When parsing, if a tag number is encountered which is +// inside one of the message type's extension ranges, the tag is passed +// off to the ExtensionSet for parsing. Etc. +class PROTOBUF_EXPORT ExtensionSet { + public: + constexpr ExtensionSet(); + explicit ExtensionSet(Arena* arena); + ~ExtensionSet(); + + // These are called at startup by protocol-compiler-generated code to + // register known extensions. The registrations are used by ParseField() + // to look up extensions for parsed field numbers. Note that dynamic parsing + // does not use ParseField(); only protocol-compiler-generated parsing + // methods do. + static void RegisterExtension(const MessageLite* extendee, int number, + FieldType type, bool is_repeated, + bool is_packed); + static void RegisterEnumExtension(const MessageLite* extendee, int number, + FieldType type, bool is_repeated, + bool is_packed, EnumValidityFunc* is_valid); + static void RegisterMessageExtension(const MessageLite* extendee, int number, + FieldType type, bool is_repeated, + bool is_packed, + const MessageLite* prototype); + + // ================================================================= + + // Add all fields which are currently present to the given vector. This + // is useful to implement Reflection::ListFields(). + void AppendToList(const Descriptor* extendee, const DescriptorPool* pool, + std::vector<const FieldDescriptor*>* output) const; + + // ================================================================= + // Accessors + // + // Generated message classes include type-safe templated wrappers around + // these methods. Generally you should use those rather than call these + // directly, unless you are doing low-level memory management. + // + // When calling any of these accessors, the extension number requested + // MUST exist in the DescriptorPool provided to the constructor. Otherwise, + // the method will fail an assert. Normally, though, you would not call + // these directly; you would either call the generated accessors of your + // message class (e.g. GetExtension()) or you would call the accessors + // of the reflection interface. In both cases, it is impossible to + // trigger this assert failure: the generated accessors only accept + // linked-in extension types as parameters, while the Reflection interface + // requires you to provide the FieldDescriptor describing the extension. + // + // When calling any of these accessors, a protocol-compiler-generated + // implementation of the extension corresponding to the number MUST + // be linked in, and the FieldDescriptor used to refer to it MUST be + // the one generated by that linked-in code. Otherwise, the method will + // die on an assert failure. The message objects returned by the message + // accessors are guaranteed to be of the correct linked-in type. + // + // These methods pretty much match Reflection except that: + // - They're not virtual. + // - They identify fields by number rather than FieldDescriptors. + // - They identify enum values using integers rather than descriptors. + // - Strings provide Mutable() in addition to Set() accessors. + + bool Has(int number) const; + int ExtensionSize(int number) const; // Size of a repeated extension. + int NumExtensions() const; // The number of extensions + FieldType ExtensionType(int number) const; + void ClearExtension(int number); + + // singular fields ------------------------------------------------- + + arc_i32 GetInt32(int number, arc_i32 default_value) const; + arc_i64 GetInt64(int number, arc_i64 default_value) const; + arc_ui32 GetUInt32(int number, arc_ui32 default_value) const; + arc_ui64 GetUInt64(int number, arc_ui64 default_value) const; + float GetFloat(int number, float default_value) const; + double GetDouble(int number, double default_value) const; + bool GetBool(int number, bool default_value) const; + int GetEnum(int number, int default_value) const; + const TProtoStringType& GetString(int number, + const TProtoStringType& default_value) const; + const MessageLite& GetMessage(int number, + const MessageLite& default_value) const; + const MessageLite& GetMessage(int number, const Descriptor* message_type, + MessageFactory* factory) const; + + // |descriptor| may be nullptr so long as it is known that the descriptor for + // the extension lives in the same pool as the descriptor for the containing + // type. +#define desc const FieldDescriptor* descriptor // avoid line wrapping + void SetInt32(int number, FieldType type, arc_i32 value, desc); + void SetInt64(int number, FieldType type, arc_i64 value, desc); + void SetUInt32(int number, FieldType type, arc_ui32 value, desc); + void SetUInt64(int number, FieldType type, arc_ui64 value, desc); + void SetFloat(int number, FieldType type, float value, desc); + void SetDouble(int number, FieldType type, double value, desc); + void SetBool(int number, FieldType type, bool value, desc); + void SetEnum(int number, FieldType type, int value, desc); + void SetString(int number, FieldType type, TProtoStringType value, desc); + TProtoStringType* MutableString(int number, FieldType type, desc); + MessageLite* MutableMessage(int number, FieldType type, + const MessageLite& prototype, desc); + MessageLite* MutableMessage(const FieldDescriptor* descriptor, + MessageFactory* factory); + // Adds the given message to the ExtensionSet, taking ownership of the + // message object. Existing message with the same number will be deleted. + // If "message" is nullptr, this is equivalent to "ClearExtension(number)". + void SetAllocatedMessage(int number, FieldType type, + const FieldDescriptor* descriptor, + MessageLite* message); + void UnsafeArenaSetAllocatedMessage(int number, FieldType type, + const FieldDescriptor* descriptor, + MessageLite* message); + PROTOBUF_NODISCARD MessageLite* ReleaseMessage(int number, + const MessageLite& prototype); + MessageLite* UnsafeArenaReleaseMessage(int number, + const MessageLite& prototype); + + PROTOBUF_NODISCARD MessageLite* ReleaseMessage( + const FieldDescriptor* descriptor, MessageFactory* factory); + MessageLite* UnsafeArenaReleaseMessage(const FieldDescriptor* descriptor, + MessageFactory* factory); +#undef desc + Arena* GetArena() const { return arena_; } + + // repeated fields ------------------------------------------------- + + // Fetches a RepeatedField extension by number; returns |default_value| + // if no such extension exists. User should not touch this directly; it is + // used by the GetRepeatedExtension() method. + const void* GetRawRepeatedField(int number, const void* default_value) const; + // Fetches a mutable version of a RepeatedField extension by number, + // instantiating one if none exists. Similar to above, user should not use + // this directly; it underlies MutableRepeatedExtension(). + void* MutableRawRepeatedField(int number, FieldType field_type, bool packed, + const FieldDescriptor* desc); + + // This is an overload of MutableRawRepeatedField to maintain compatibility + // with old code using a previous API. This version of + // MutableRawRepeatedField() will GOOGLE_CHECK-fail on a missing extension. + // (E.g.: borg/clients/internal/proto1/proto2_reflection.cc.) + void* MutableRawRepeatedField(int number); + + arc_i32 GetRepeatedInt32(int number, int index) const; + arc_i64 GetRepeatedInt64(int number, int index) const; + arc_ui32 GetRepeatedUInt32(int number, int index) const; + arc_ui64 GetRepeatedUInt64(int number, int index) const; + float GetRepeatedFloat(int number, int index) const; + double GetRepeatedDouble(int number, int index) const; + bool GetRepeatedBool(int number, int index) const; + int GetRepeatedEnum(int number, int index) const; + const TProtoStringType& GetRepeatedString(int number, int index) const; + const MessageLite& GetRepeatedMessage(int number, int index) const; + + void SetRepeatedInt32(int number, int index, arc_i32 value); + void SetRepeatedInt64(int number, int index, arc_i64 value); + void SetRepeatedUInt32(int number, int index, arc_ui32 value); + void SetRepeatedUInt64(int number, int index, arc_ui64 value); + void SetRepeatedFloat(int number, int index, float value); + void SetRepeatedDouble(int number, int index, double value); + void SetRepeatedBool(int number, int index, bool value); + void SetRepeatedEnum(int number, int index, int value); + void SetRepeatedString(int number, int index, TProtoStringType value); + TProtoStringType* MutableRepeatedString(int number, int index); + MessageLite* MutableRepeatedMessage(int number, int index); + +#define desc const FieldDescriptor* descriptor // avoid line wrapping + void AddInt32(int number, FieldType type, bool packed, arc_i32 value, desc); + void AddInt64(int number, FieldType type, bool packed, arc_i64 value, desc); + void AddUInt32(int number, FieldType type, bool packed, arc_ui32 value, desc); + void AddUInt64(int number, FieldType type, bool packed, arc_ui64 value, desc); + void AddFloat(int number, FieldType type, bool packed, float value, desc); + void AddDouble(int number, FieldType type, bool packed, double value, desc); + void AddBool(int number, FieldType type, bool packed, bool value, desc); + void AddEnum(int number, FieldType type, bool packed, int value, desc); + void AddString(int number, FieldType type, TProtoStringType value, desc); + TProtoStringType* AddString(int number, FieldType type, desc); + MessageLite* AddMessage(int number, FieldType type, + const MessageLite& prototype, desc); + MessageLite* AddMessage(const FieldDescriptor* descriptor, + MessageFactory* factory); + void AddAllocatedMessage(const FieldDescriptor* descriptor, + MessageLite* new_entry); + void UnsafeArenaAddAllocatedMessage(const FieldDescriptor* descriptor, + MessageLite* new_entry); +#undef desc + + void RemoveLast(int number); + PROTOBUF_NODISCARD MessageLite* ReleaseLast(int number); + MessageLite* UnsafeArenaReleaseLast(int number); + void SwapElements(int number, int index1, int index2); + + // ----------------------------------------------------------------- + // TODO(kenton): Hardcore memory management accessors + + // ================================================================= + // convenience methods for implementing methods of Message + // + // These could all be implemented in terms of the other methods of this + // class, but providing them here helps keep the generated code size down. + + void Clear(); + void MergeFrom(const MessageLite* extendee, const ExtensionSet& other); + void Swap(const MessageLite* extendee, ExtensionSet* other); + void InternalSwap(ExtensionSet* other); + void SwapExtension(const MessageLite* extendee, 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 + // positioned immediately after the tag. + bool ParseField(arc_ui32 tag, io::CodedInputStream* input, + ExtensionFinder* extension_finder, + FieldSkipper* field_skipper); + + // Specific versions for lite or full messages (constructs the appropriate + // FieldSkipper automatically). |extendee| is the default + // instance for the containing message; it is used only to look up the + // extension by number. See RegisterExtension(), above. Unlike the other + // methods of ExtensionSet, this only works for generated message types -- + // it looks up extensions registered using RegisterExtension(). + bool ParseField(arc_ui32 tag, io::CodedInputStream* input, + const MessageLite* extendee); + bool ParseField(arc_ui32 tag, io::CodedInputStream* input, + const Message* extendee, UnknownFieldSet* unknown_fields); + bool ParseField(arc_ui32 tag, io::CodedInputStream* input, + const MessageLite* extendee, + io::CodedOutputStream* unknown_fields); + + // Lite parser + const char* ParseField(arc_ui64 tag, const char* ptr, + const MessageLite* extendee, + internal::InternalMetadata* metadata, + internal::ParseContext* ctx); + // Full parser + const char* ParseField(arc_ui64 tag, const char* ptr, const Message* extendee, + internal::InternalMetadata* metadata, + internal::ParseContext* ctx); + template <typename Msg> + const char* ParseMessageSet(const char* ptr, const Msg* extendee, + InternalMetadata* metadata, + internal::ParseContext* ctx) { + struct MessageSetItem { + const char* _InternalParse(const char* ptr, ParseContext* ctx) { + return me->ParseMessageSetItem(ptr, extendee, metadata, ctx); + } + ExtensionSet* me; + const Msg* extendee; + InternalMetadata* metadata; + } item{this, extendee, metadata}; + while (!ctx->Done(&ptr)) { + arc_ui32 tag; + ptr = ReadTag(ptr, &tag); + GOOGLE_PROTOBUF_PARSER_ASSERT(ptr); + if (tag == WireFormatLite::kMessageSetItemStartTag) { + ptr = ctx->ParseGroup(&item, ptr, tag); + GOOGLE_PROTOBUF_PARSER_ASSERT(ptr); + } else { + if (tag == 0 || (tag & 7) == 4) { + ctx->SetLastTag(tag); + return ptr; + } + ptr = ParseField(tag, ptr, extendee, metadata, ctx); + GOOGLE_PROTOBUF_PARSER_ASSERT(ptr); + } + } + return ptr; + } + + // Parse an entire message in MessageSet format. Such messages have no + // fields, only extensions. + bool ParseMessageSetLite(io::CodedInputStream* input, + ExtensionFinder* extension_finder, + FieldSkipper* field_skipper); + bool ParseMessageSet(io::CodedInputStream* input, + ExtensionFinder* extension_finder, + MessageSetFieldSkipper* field_skipper); + + // Specific versions for lite or full messages (constructs the appropriate + // FieldSkipper automatically). + bool ParseMessageSet(io::CodedInputStream* input, const MessageLite* extendee, + TProtoStringType* unknown_fields); + bool ParseMessageSet(io::CodedInputStream* input, const Message* extendee, + UnknownFieldSet* unknown_fields); + + // Write all extension fields with field numbers in the range + // [start_field_number, end_field_number) + // to the output stream, using the cached sizes computed when ByteSize() was + // last called. Note that the range bounds are inclusive-exclusive. + void SerializeWithCachedSizes(const MessageLite* extendee, + int start_field_number, int end_field_number, + io::CodedOutputStream* output) const { + output->SetCur(_InternalSerialize(extendee, start_field_number, + end_field_number, output->Cur(), + output->EpsCopy())); + } + + // Same as SerializeWithCachedSizes, but without any bounds checking. + // The caller must ensure that target has sufficient capacity for the + // serialized extensions. + // + // Returns a pointer past the last written byte. + + uint8_t* _InternalSerialize(const MessageLite* extendee, + int start_field_number, int end_field_number, + uint8_t* target, + io::EpsCopyOutputStream* stream) const { + if (flat_size_ == 0) { + assert(!is_large()); + return target; + } + return _InternalSerializeImpl(extendee, start_field_number, + end_field_number, target, stream); + } + + // Like above but serializes in MessageSet format. + void SerializeMessageSetWithCachedSizes(const MessageLite* extendee, + io::CodedOutputStream* output) const { + output->SetCur(InternalSerializeMessageSetWithCachedSizesToArray( + extendee, output->Cur(), output->EpsCopy())); + } + uint8_t* InternalSerializeMessageSetWithCachedSizesToArray( + const MessageLite* extendee, uint8_t* target, + io::EpsCopyOutputStream* stream) const; + + // For backward-compatibility, versions of two of the above methods that + // serialize deterministically iff SetDefaultSerializationDeterministic() + // has been called. + uint8_t* SerializeWithCachedSizesToArray(int start_field_number, + int end_field_number, + uint8_t* target) const; + uint8_t* SerializeMessageSetWithCachedSizesToArray( + const MessageLite* extendee, uint8_t* target) const; + + // Returns the total serialized size of all the extensions. + size_t ByteSize() const; + + // Like ByteSize() but uses MessageSet format. + size_t MessageSetByteSize() const; + + // Returns (an estimate of) the total number of bytes used for storing the + // extensions in memory, excluding sizeof(*this). If the ExtensionSet is + // for a lite message (and thus possibly contains lite messages), the results + // are undefined (might work, might crash, might corrupt data, might not even + // be linked in). It's up to the protocol compiler to avoid calling this on + // such ExtensionSets (easy enough since lite messages don't implement + // SpaceUsed()). + size_t SpaceUsedExcludingSelfLong() const; + + // This method just calls SpaceUsedExcludingSelfLong() but it can not be + // inlined because the definition of SpaceUsedExcludingSelfLong() is not + // included in lite runtime and when an inline method refers to it MSVC + // will complain about unresolved symbols when building the lite runtime + // as .dll. + int SpaceUsedExcludingSelf() const; + + private: + template <typename Type> + friend class PrimitiveTypeTraits; + + template <typename Type> + friend class RepeatedPrimitiveTypeTraits; + + template <typename Type, bool IsValid(int)> + friend class EnumTypeTraits; + + template <typename Type, bool IsValid(int)> + friend class RepeatedEnumTypeTraits; + + friend class google::protobuf::Reflection; + + const arc_i32& GetRefInt32(int number, const arc_i32& default_value) const; + const arc_i64& GetRefInt64(int number, const arc_i64& default_value) const; + const arc_ui32& GetRefUInt32(int number, const arc_ui32& default_value) const; + const arc_ui64& GetRefUInt64(int number, const arc_ui64& default_value) const; + const float& GetRefFloat(int number, const float& default_value) const; + const double& GetRefDouble(int number, const double& default_value) const; + const bool& GetRefBool(int number, const bool& default_value) const; + const int& GetRefEnum(int number, const int& default_value) const; + const arc_i32& GetRefRepeatedInt32(int number, int index) const; + const arc_i64& GetRefRepeatedInt64(int number, int index) const; + const arc_ui32& GetRefRepeatedUInt32(int number, int index) const; + const arc_ui64& GetRefRepeatedUInt64(int number, int index) const; + const float& GetRefRepeatedFloat(int number, int index) const; + const double& GetRefRepeatedDouble(int number, int index) const; + const bool& GetRefRepeatedBool(int number, int index) const; + const int& GetRefRepeatedEnum(int number, int index) const; + + // Implementation of _InternalSerialize for non-empty map_. + uint8_t* _InternalSerializeImpl(const MessageLite* extendee, + int start_field_number, int end_field_number, + uint8_t* target, + io::EpsCopyOutputStream* stream) const; + // Interface of a lazily parsed singular message extension. + class PROTOBUF_EXPORT LazyMessageExtension { + public: + LazyMessageExtension() {} + virtual ~LazyMessageExtension() {} + + virtual LazyMessageExtension* New(Arena* arena) const = 0; + virtual const MessageLite& GetMessage(const MessageLite& prototype, + Arena* arena) const = 0; + virtual MessageLite* MutableMessage(const MessageLite& prototype, + Arena* arena) = 0; + virtual void SetAllocatedMessage(MessageLite* message, Arena* arena) = 0; + virtual void UnsafeArenaSetAllocatedMessage(MessageLite* message, + Arena* arena) = 0; + PROTOBUF_NODISCARD virtual MessageLite* ReleaseMessage( + const MessageLite& prototype, Arena* arena) = 0; + virtual MessageLite* UnsafeArenaReleaseMessage(const MessageLite& prototype, + Arena* arena) = 0; + + virtual bool IsInitialized() const = 0; + + PROTOBUF_DEPRECATED_MSG("Please use ByteSizeLong() instead") + virtual int ByteSize() const { return internal::ToIntSize(ByteSizeLong()); } + virtual size_t ByteSizeLong() const = 0; + virtual size_t SpaceUsedLong() const = 0; + + virtual void MergeFrom(const MessageLite* prototype, + const LazyMessageExtension& other, Arena* arena) = 0; + virtual void MergeFromMessage(const MessageLite& msg, Arena* arena) = 0; + virtual void Clear() = 0; + + virtual bool ReadMessage(const MessageLite& prototype, + io::CodedInputStream* input) = 0; + virtual const char* _InternalParse(const Message& prototype, Arena* arena, + const char* ptr, ParseContext* ctx) = 0; + virtual uint8_t* WriteMessageToArray( + const MessageLite* prototype, int number, uint8_t* target, + io::EpsCopyOutputStream* stream) const = 0; + + private: + virtual void UnusedKeyMethod(); // Dummy key method to avoid weak vtable. + + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(LazyMessageExtension); + }; + // Give access to function defined below to see LazyMessageExtension. + friend LazyMessageExtension* MaybeCreateLazyExtension(Arena* arena); + struct Extension { + // The order of these fields packs Extension into 24 bytes when using 8 + // byte alignment. Consider this when adding or removing fields here. + union { + arc_i32 arc_i32_value; + arc_i64 arc_i64_value; + arc_ui32 arc_ui32_value; + arc_ui64 arc_ui64_value; + float float_value; + double double_value; + bool bool_value; + int enum_value; + TProtoStringType* string_value; + MessageLite* message_value; + LazyMessageExtension* lazymessage_value; + + RepeatedField<arc_i32>* repeated_arc_i32_value; + RepeatedField<arc_i64>* repeated_arc_i64_value; + RepeatedField<arc_ui32>* repeated_arc_ui32_value; + RepeatedField<arc_ui64>* repeated_arc_ui64_value; + RepeatedField<float>* repeated_float_value; + RepeatedField<double>* repeated_double_value; + RepeatedField<bool>* repeated_bool_value; + RepeatedField<int>* repeated_enum_value; + RepeatedPtrField<TProtoStringType>* repeated_string_value; + RepeatedPtrField<MessageLite>* repeated_message_value; + }; + + FieldType type; + bool is_repeated; + + // For singular types, indicates if the extension is "cleared". This + // happens when an extension is set and then later cleared by the caller. + // We want to keep the Extension object around for reuse, so instead of + // removing it from the map, we just set is_cleared = true. This has no + // meaning for repeated types; for those, the size of the RepeatedField + // simply becomes zero when cleared. + bool is_cleared : 4; + + // For singular message types, indicates whether lazy parsing is enabled + // for this extension. This field is only valid when type == TYPE_MESSAGE + // and !is_repeated because we only support lazy parsing for singular + // message types currently. If is_lazy = true, the extension is stored in + // lazymessage_value. Otherwise, the extension will be message_value. + bool is_lazy : 4; + + // For repeated types, this indicates if the [packed=true] option is set. + bool is_packed; + + // For packed fields, the size of the packed data is recorded here when + // ByteSize() is called then used during serialization. + // TODO(kenton): Use atomic<int> when C++ supports it. + mutable int cached_size; + + // The descriptor for this extension, if one exists and is known. May be + // nullptr. Must not be nullptr if the descriptor for the extension does + // not live in the same pool as the descriptor for the containing type. + const FieldDescriptor* descriptor; + + // Some helper methods for operations on a single Extension. + uint8_t* InternalSerializeFieldWithCachedSizesToArray( + const MessageLite* extendee, const ExtensionSet* extension_set, + int number, uint8_t* target, io::EpsCopyOutputStream* stream) const; + uint8_t* InternalSerializeMessageSetItemWithCachedSizesToArray( + const MessageLite* extendee, const ExtensionSet* extension_set, + int number, uint8_t* target, io::EpsCopyOutputStream* stream) const; + size_t ByteSize(int number) const; + size_t MessageSetItemByteSize(int number) const; + void Clear(); + int GetSize() const; + void Free(); + size_t SpaceUsedExcludingSelfLong() const; + bool IsInitialized() const; + }; + + // The Extension struct is small enough to be passed by value, so we use it + // directly as the value type in mappings rather than use pointers. We use + // sorted maps rather than hash-maps because we expect most ExtensionSets will + // only contain a small number of extension. Also, we want AppendToList and + // deterministic serialization to order fields by field number. + + struct KeyValue { + int first; + Extension second; + + struct FirstComparator { + bool operator()(const KeyValue& lhs, const KeyValue& rhs) const { + return lhs.first < rhs.first; + } + bool operator()(const KeyValue& lhs, int key) const { + return lhs.first < key; + } + bool operator()(int key, const KeyValue& rhs) const { + return key < rhs.first; + } + }; + }; + + typedef std::map<int, Extension> LargeMap; + + // Wrapper API that switches between flat-map and LargeMap. + + // Finds a key (if present) in the ExtensionSet. + const Extension* FindOrNull(int key) const; + Extension* FindOrNull(int key); + + // Helper-functions that only inspect the LargeMap. + const Extension* FindOrNullInLargeMap(int key) const; + Extension* FindOrNullInLargeMap(int key); + + // Inserts a new (key, Extension) into the ExtensionSet (and returns true), or + // finds the already-existing Extension for that key (returns false). + // The Extension* will point to the new-or-found Extension. + std::pair<Extension*, bool> Insert(int key); + + // Grows the flat_capacity_. + // If flat_capacity_ > kMaximumFlatCapacity, converts to LargeMap. + void GrowCapacity(size_t minimum_new_capacity); + static constexpr uint16_t kMaximumFlatCapacity = 256; + bool is_large() const { return static_cast<int16_t>(flat_size_) < 0; } + + // Removes a key from the ExtensionSet. + void Erase(int key); + + size_t Size() const { + return PROTOBUF_PREDICT_FALSE(is_large()) ? map_.large->size() : flat_size_; + } + + // Similar to std::for_each. + // Each Iterator is decomposed into ->first and ->second fields, so + // that the KeyValueFunctor can be agnostic vis-a-vis KeyValue-vs-std::pair. + template <typename Iterator, typename KeyValueFunctor> + static KeyValueFunctor ForEach(Iterator begin, Iterator end, + KeyValueFunctor func) { + for (Iterator it = begin; it != end; ++it) func(it->first, it->second); + return std::move(func); + } + + // Applies a functor to the <int, Extension&> pairs in sorted order. + template <typename KeyValueFunctor> + KeyValueFunctor ForEach(KeyValueFunctor func) { + if (PROTOBUF_PREDICT_FALSE(is_large())) { + return ForEach(map_.large->begin(), map_.large->end(), std::move(func)); + } + return ForEach(flat_begin(), flat_end(), std::move(func)); + } + + // Applies a functor to the <int, const Extension&> pairs in sorted order. + template <typename KeyValueFunctor> + KeyValueFunctor ForEach(KeyValueFunctor func) const { + if (PROTOBUF_PREDICT_FALSE(is_large())) { + return ForEach(map_.large->begin(), map_.large->end(), std::move(func)); + } + return ForEach(flat_begin(), flat_end(), std::move(func)); + } + + // Merges existing Extension from other_extension + void InternalExtensionMergeFrom(const MessageLite* extendee, int number, + const Extension& other_extension, + Arena* other_arena); + + // Returns true and fills field_number and extension if extension is found. + // Note to support packed repeated field compatibility, it also fills whether + // the tag on wire is packed, which can be different from + // extension->is_packed (whether packed=true is specified). + bool FindExtensionInfoFromTag(arc_ui32 tag, ExtensionFinder* extension_finder, + int* field_number, ExtensionInfo* extension, + bool* was_packed_on_wire); + + // Returns true and fills extension if extension is found. + // Note to support packed repeated field compatibility, it also fills whether + // the tag on wire is packed, which can be different from + // extension->is_packed (whether packed=true is specified). + bool FindExtensionInfoFromFieldNumber(int wire_type, int field_number, + ExtensionFinder* extension_finder, + ExtensionInfo* extension, + bool* was_packed_on_wire) const; + + // Find the prototype for a LazyMessage from the extension registry. Returns + // null if the extension is not found. + const MessageLite* GetPrototypeForLazyMessage(const MessageLite* extendee, + int number) const; + + // Parses a single extension from the input. The input should start out + // positioned immediately after the wire tag. This method is called in + // ParseField() after field number and was_packed_on_wire is extracted from + // the wire tag and ExtensionInfo is found by the field number. + bool ParseFieldWithExtensionInfo(int field_number, bool was_packed_on_wire, + const ExtensionInfo& extension, + io::CodedInputStream* input, + FieldSkipper* field_skipper); + + // Like ParseField(), but this method may parse singular message extensions + // lazily depending on the value of FLAGS_eagerly_parse_message_sets. + bool ParseFieldMaybeLazily(int wire_type, int field_number, + io::CodedInputStream* input, + ExtensionFinder* extension_finder, + MessageSetFieldSkipper* field_skipper); + + // Returns true if extension is present and lazy. + bool HasLazy(int number) const; + + // Gets the extension with the given number, creating it if it does not + // already exist. Returns true if the extension did not already exist. + bool MaybeNewExtension(int number, const FieldDescriptor* descriptor, + Extension** result); + + // Gets the repeated extension for the given descriptor, creating it if + // it does not exist. + Extension* MaybeNewRepeatedExtension(const FieldDescriptor* descriptor); + + // Parse a single MessageSet item -- called just after the item group start + // tag has been read. + bool ParseMessageSetItemLite(io::CodedInputStream* input, + ExtensionFinder* extension_finder, + FieldSkipper* field_skipper); + // Parse a single MessageSet item -- called just after the item group start + // tag has been read. + bool ParseMessageSetItem(io::CodedInputStream* input, + ExtensionFinder* extension_finder, + MessageSetFieldSkipper* field_skipper); + + bool FindExtension(int wire_type, arc_ui32 field, const MessageLite* extendee, + const internal::ParseContext* /*ctx*/, + ExtensionInfo* extension, bool* was_packed_on_wire) { + GeneratedExtensionFinder finder(extendee); + return FindExtensionInfoFromFieldNumber(wire_type, field, &finder, + extension, was_packed_on_wire); + } + inline bool FindExtension(int wire_type, arc_ui32 field, + const Message* extendee, + const internal::ParseContext* ctx, + ExtensionInfo* extension, bool* was_packed_on_wire); + // Used for MessageSet only + const char* ParseFieldMaybeLazily(arc_ui64 tag, const char* ptr, + const MessageLite* extendee, + internal::InternalMetadata* metadata, + internal::ParseContext* ctx) { + // Lite MessageSet doesn't implement lazy. + return ParseField(tag, ptr, extendee, metadata, ctx); + } + const char* ParseFieldMaybeLazily(arc_ui64 tag, const char* ptr, + const Message* extendee, + internal::InternalMetadata* metadata, + internal::ParseContext* ctx); + const char* ParseMessageSetItem(const char* ptr, const MessageLite* extendee, + internal::InternalMetadata* metadata, + internal::ParseContext* ctx); + const char* ParseMessageSetItem(const char* ptr, const Message* extendee, + internal::InternalMetadata* metadata, + internal::ParseContext* ctx); + + // Implemented in extension_set_inl.h to keep code out of the header file. + template <typename T> + const char* ParseFieldWithExtensionInfo(int number, bool was_packed_on_wire, + const ExtensionInfo& info, + internal::InternalMetadata* metadata, + const char* ptr, + internal::ParseContext* ctx); + template <typename Msg, typename T> + const char* ParseMessageSetItemTmpl(const char* ptr, const Msg* extendee, + internal::InternalMetadata* metadata, + internal::ParseContext* ctx); + + // Hack: RepeatedPtrFieldBase declares ExtensionSet as a friend. This + // friendship should automatically extend to ExtensionSet::Extension, but + // unfortunately some older compilers (e.g. GCC 3.4.4) do not implement this + // correctly. So, we must provide helpers for calling methods of that + // class. + + // Defined in extension_set_heavy.cc. + static inline size_t RepeatedMessage_SpaceUsedExcludingSelfLong( + RepeatedPtrFieldBase* field); + + KeyValue* flat_begin() { + assert(!is_large()); + return map_.flat; + } + const KeyValue* flat_begin() const { + assert(!is_large()); + return map_.flat; + } + KeyValue* flat_end() { + assert(!is_large()); + return map_.flat + flat_size_; + } + const KeyValue* flat_end() const { + assert(!is_large()); + return map_.flat + flat_size_; + } + + Arena* arena_; + + // Manual memory-management: + // map_.flat is an allocated array of flat_capacity_ elements. + // [map_.flat, map_.flat + flat_size_) is the currently-in-use prefix. + uint16_t flat_capacity_; + uint16_t flat_size_; // negative int16_t(flat_size_) indicates is_large() + union AllocatedData { + KeyValue* flat; + + // If flat_capacity_ > kMaximumFlatCapacity, switch to LargeMap, + // which guarantees O(n lg n) CPU but larger constant factors. + LargeMap* large; + } map_; + + static void DeleteFlatMap(const KeyValue* flat, uint16_t flat_capacity); + + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ExtensionSet); +}; + +constexpr ExtensionSet::ExtensionSet() + : arena_(nullptr), flat_capacity_(0), flat_size_(0), map_{nullptr} {} + +// These are just for convenience... +inline void ExtensionSet::SetString(int number, FieldType type, + TProtoStringType value, + const FieldDescriptor* descriptor) { + MutableString(number, type, descriptor)->assign(std::move(value)); +} +inline void ExtensionSet::SetRepeatedString(int number, int index, + TProtoStringType value) { + MutableRepeatedString(number, index)->assign(std::move(value)); +} +inline void ExtensionSet::AddString(int number, FieldType type, + TProtoStringType value, + const FieldDescriptor* descriptor) { + AddString(number, type, descriptor)->assign(std::move(value)); +} +// =================================================================== +// Glue for generated extension accessors + +// ------------------------------------------------------------------- +// Template magic + +// First we have a set of classes representing "type traits" for different +// field types. A type traits class knows how to implement basic accessors +// for extensions of a particular type given an ExtensionSet. The signature +// for a type traits class looks like this: +// +// class TypeTraits { +// public: +// typedef ? ConstType; +// typedef ? MutableType; +// // TypeTraits for singular fields and repeated fields will define the +// // symbol "Singular" or "Repeated" respectively. These two symbols will +// // be used in extension accessors to distinguish between singular +// // extensions and repeated extensions. If the TypeTraits for the passed +// // in extension doesn't have the expected symbol defined, it means the +// // user is passing a repeated extension to a singular accessor, or the +// // opposite. In that case the C++ compiler will generate an error +// // message "no matching member function" to inform the user. +// typedef ? Singular +// typedef ? Repeated +// +// static inline ConstType Get(int number, const ExtensionSet& set); +// static inline void Set(int number, ConstType value, ExtensionSet* set); +// static inline MutableType Mutable(int number, ExtensionSet* set); +// +// // Variants for repeated fields. +// static inline ConstType Get(int number, const ExtensionSet& set, +// int index); +// static inline void Set(int number, int index, +// ConstType value, ExtensionSet* set); +// static inline MutableType Mutable(int number, int index, +// ExtensionSet* set); +// static inline void Add(int number, ConstType value, ExtensionSet* set); +// static inline MutableType Add(int number, ExtensionSet* set); +// This is used by the ExtensionIdentifier constructor to register +// the extension at dynamic initialization. +// template <typename ExtendeeT> +// static void Register(int number, FieldType type, bool is_packed); +// }; +// +// Not all of these methods make sense for all field types. For example, the +// "Mutable" methods only make sense for strings and messages, and the +// repeated methods only make sense for repeated types. So, each type +// traits class implements only the set of methods from this signature that it +// actually supports. This will cause a compiler error if the user tries to +// access an extension using a method that doesn't make sense for its type. +// For example, if "foo" is an extension of type "optional int32", then if you +// try to write code like: +// my_message.MutableExtension(foo) +// you will get a compile error because PrimitiveTypeTraits<arc_i32> does not +// have a "Mutable()" method. + +// ------------------------------------------------------------------- +// PrimitiveTypeTraits + +// Since the ExtensionSet has different methods for each primitive type, +// we must explicitly define the methods of the type traits class for each +// known type. +template <typename Type> +class PrimitiveTypeTraits { + public: + typedef Type ConstType; + typedef Type MutableType; + typedef PrimitiveTypeTraits<Type> Singular; + + static inline ConstType Get(int number, const ExtensionSet& set, + ConstType default_value); + + static inline const ConstType* GetPtr(int number, const ExtensionSet& set, + const ConstType& default_value); + static inline void Set(int number, FieldType field_type, ConstType value, + ExtensionSet* set); + template <typename ExtendeeT> + static void Register(int number, FieldType type, bool is_packed) { + ExtensionSet::RegisterExtension(&ExtendeeT::default_instance(), number, + type, false, is_packed); + } +}; + +template <typename Type> +class RepeatedPrimitiveTypeTraits { + public: + typedef Type ConstType; + typedef Type MutableType; + typedef RepeatedPrimitiveTypeTraits<Type> Repeated; + + typedef RepeatedField<Type> RepeatedFieldType; + + static inline Type Get(int number, const ExtensionSet& set, int index); + static inline const Type* GetPtr(int number, const ExtensionSet& set, + int index); + static inline const RepeatedField<ConstType>* GetRepeatedPtr( + int number, const ExtensionSet& set); + static inline void Set(int number, int index, Type value, ExtensionSet* set); + static inline void Add(int number, FieldType field_type, bool is_packed, + Type value, ExtensionSet* set); + + static inline const RepeatedField<ConstType>& GetRepeated( + int number, const ExtensionSet& set); + static inline RepeatedField<Type>* MutableRepeated(int number, + FieldType field_type, + bool is_packed, + ExtensionSet* set); + + static const RepeatedFieldType* GetDefaultRepeatedField(); + template <typename ExtendeeT> + static void Register(int number, FieldType type, bool is_packed) { + ExtensionSet::RegisterExtension(&ExtendeeT::default_instance(), number, + type, true, is_packed); + } +}; + +class PROTOBUF_EXPORT RepeatedPrimitiveDefaults { + private: + template <typename Type> + friend class RepeatedPrimitiveTypeTraits; + static const RepeatedPrimitiveDefaults* default_instance(); + RepeatedField<arc_i32> default_repeated_field_arc_i32_; + RepeatedField<arc_i64> default_repeated_field_arc_i64_; + RepeatedField<arc_ui32> default_repeated_field_arc_ui32_; + RepeatedField<arc_ui64> default_repeated_field_arc_ui64_; + RepeatedField<double> default_repeated_field_double_; + RepeatedField<float> default_repeated_field_float_; + RepeatedField<bool> default_repeated_field_bool_; +}; + +#define PROTOBUF_DEFINE_PRIMITIVE_TYPE(TYPE, METHOD) \ + template <> \ + inline TYPE PrimitiveTypeTraits<TYPE>::Get( \ + int number, const ExtensionSet& set, TYPE default_value) { \ + return set.Get##METHOD(number, default_value); \ + } \ + template <> \ + inline const TYPE* PrimitiveTypeTraits<TYPE>::GetPtr( \ + int number, const ExtensionSet& set, const TYPE& default_value) { \ + return &set.GetRef##METHOD(number, default_value); \ + } \ + template <> \ + inline void PrimitiveTypeTraits<TYPE>::Set(int number, FieldType field_type, \ + TYPE value, ExtensionSet* set) { \ + set->Set##METHOD(number, field_type, value, nullptr); \ + } \ + \ + template <> \ + inline TYPE RepeatedPrimitiveTypeTraits<TYPE>::Get( \ + int number, const ExtensionSet& set, int index) { \ + return set.GetRepeated##METHOD(number, index); \ + } \ + template <> \ + inline const TYPE* RepeatedPrimitiveTypeTraits<TYPE>::GetPtr( \ + int number, const ExtensionSet& set, int index) { \ + return &set.GetRefRepeated##METHOD(number, index); \ + } \ + template <> \ + inline void RepeatedPrimitiveTypeTraits<TYPE>::Set( \ + int number, int index, TYPE value, ExtensionSet* set) { \ + set->SetRepeated##METHOD(number, index, value); \ + } \ + template <> \ + inline void RepeatedPrimitiveTypeTraits<TYPE>::Add( \ + int number, FieldType field_type, bool is_packed, TYPE value, \ + ExtensionSet* set) { \ + set->Add##METHOD(number, field_type, is_packed, value, nullptr); \ + } \ + template <> \ + inline const RepeatedField<TYPE>* \ + RepeatedPrimitiveTypeTraits<TYPE>::GetDefaultRepeatedField() { \ + return &RepeatedPrimitiveDefaults::default_instance() \ + ->default_repeated_field_##TYPE##_; \ + } \ + template <> \ + inline const RepeatedField<TYPE>& \ + RepeatedPrimitiveTypeTraits<TYPE>::GetRepeated(int number, \ + const ExtensionSet& set) { \ + return *reinterpret_cast<const RepeatedField<TYPE>*>( \ + set.GetRawRepeatedField(number, GetDefaultRepeatedField())); \ + } \ + template <> \ + inline const RepeatedField<TYPE>* \ + RepeatedPrimitiveTypeTraits<TYPE>::GetRepeatedPtr(int number, \ + const ExtensionSet& set) { \ + return &GetRepeated(number, set); \ + } \ + template <> \ + inline RepeatedField<TYPE>* \ + RepeatedPrimitiveTypeTraits<TYPE>::MutableRepeated( \ + int number, FieldType field_type, bool is_packed, ExtensionSet* set) { \ + return reinterpret_cast<RepeatedField<TYPE>*>( \ + set->MutableRawRepeatedField(number, field_type, is_packed, nullptr)); \ + } + +PROTOBUF_DEFINE_PRIMITIVE_TYPE(arc_i32, Int32) +PROTOBUF_DEFINE_PRIMITIVE_TYPE(arc_i64, Int64) +PROTOBUF_DEFINE_PRIMITIVE_TYPE(arc_ui32, UInt32) +PROTOBUF_DEFINE_PRIMITIVE_TYPE(arc_ui64, UInt64) +PROTOBUF_DEFINE_PRIMITIVE_TYPE(float, Float) +PROTOBUF_DEFINE_PRIMITIVE_TYPE(double, Double) +PROTOBUF_DEFINE_PRIMITIVE_TYPE(bool, Bool) + +#undef PROTOBUF_DEFINE_PRIMITIVE_TYPE + +// ------------------------------------------------------------------- +// StringTypeTraits + +// Strings support both Set() and Mutable(). +class PROTOBUF_EXPORT StringTypeTraits { + public: + typedef const TProtoStringType& ConstType; + typedef TProtoStringType* MutableType; + typedef StringTypeTraits Singular; + + static inline const TProtoStringType& Get(int number, const ExtensionSet& set, + ConstType default_value) { + return set.GetString(number, default_value); + } + static inline const TProtoStringType* GetPtr(int number, const ExtensionSet& set, + ConstType default_value) { + return &Get(number, set, default_value); + } + static inline void Set(int number, FieldType field_type, + const TProtoStringType& value, ExtensionSet* set) { + set->SetString(number, field_type, value, nullptr); + } + static inline TProtoStringType* Mutable(int number, FieldType field_type, + ExtensionSet* set) { + return set->MutableString(number, field_type, nullptr); + } + template <typename ExtendeeT> + static void Register(int number, FieldType type, bool is_packed) { + ExtensionSet::RegisterExtension(&ExtendeeT::default_instance(), number, + type, false, is_packed); + } +}; + +class PROTOBUF_EXPORT RepeatedStringTypeTraits { + public: + typedef const TProtoStringType& ConstType; + typedef TProtoStringType* MutableType; + typedef RepeatedStringTypeTraits Repeated; + + typedef RepeatedPtrField<TProtoStringType> RepeatedFieldType; + + static inline const TProtoStringType& Get(int number, const ExtensionSet& set, + int index) { + return set.GetRepeatedString(number, index); + } + static inline const TProtoStringType* GetPtr(int number, const ExtensionSet& set, + int index) { + return &Get(number, set, index); + } + static inline const RepeatedPtrField<TProtoStringType>* GetRepeatedPtr( + int number, const ExtensionSet& set) { + return &GetRepeated(number, set); + } + static inline void Set(int number, int index, const TProtoStringType& value, + ExtensionSet* set) { + set->SetRepeatedString(number, index, value); + } + static inline TProtoStringType* Mutable(int number, int index, ExtensionSet* set) { + return set->MutableRepeatedString(number, index); + } + static inline void Add(int number, FieldType field_type, bool /*is_packed*/, + const TProtoStringType& value, ExtensionSet* set) { + set->AddString(number, field_type, value, nullptr); + } + static inline TProtoStringType* Add(int number, FieldType field_type, + ExtensionSet* set) { + return set->AddString(number, field_type, nullptr); + } + static inline const RepeatedPtrField<TProtoStringType>& GetRepeated( + int number, const ExtensionSet& set) { + return *reinterpret_cast<const RepeatedPtrField<TProtoStringType>*>( + set.GetRawRepeatedField(number, GetDefaultRepeatedField())); + } + + static inline RepeatedPtrField<TProtoStringType>* MutableRepeated( + int number, FieldType field_type, bool is_packed, ExtensionSet* set) { + return reinterpret_cast<RepeatedPtrField<TProtoStringType>*>( + set->MutableRawRepeatedField(number, field_type, is_packed, nullptr)); + } + + static const RepeatedFieldType* GetDefaultRepeatedField(); + + template <typename ExtendeeT> + static void Register(int number, FieldType type, bool is_packed) { + ExtensionSet::RegisterExtension(&ExtendeeT::default_instance(), number, + type, true, is_packed); + } + + private: + static void InitializeDefaultRepeatedFields(); + static void DestroyDefaultRepeatedFields(); +}; + +// ------------------------------------------------------------------- +// EnumTypeTraits + +// ExtensionSet represents enums using integers internally, so we have to +// static_cast around. +template <typename Type, bool IsValid(int)> +class EnumTypeTraits { + public: + typedef Type ConstType; + typedef Type MutableType; + typedef EnumTypeTraits<Type, IsValid> Singular; + + static inline ConstType Get(int number, const ExtensionSet& set, + ConstType default_value) { + return static_cast<Type>(set.GetEnum(number, default_value)); + } + static inline const ConstType* GetPtr(int number, const ExtensionSet& set, + const ConstType& default_value) { + return reinterpret_cast<const Type*>( + &set.GetRefEnum(number, default_value)); + } + static inline void Set(int number, FieldType field_type, ConstType value, + ExtensionSet* set) { + GOOGLE_DCHECK(IsValid(value)); + set->SetEnum(number, field_type, value, nullptr); + } + template <typename ExtendeeT> + static void Register(int number, FieldType type, bool is_packed) { + ExtensionSet::RegisterEnumExtension(&ExtendeeT::default_instance(), number, + type, false, is_packed, IsValid); + } +}; + +template <typename Type, bool IsValid(int)> +class RepeatedEnumTypeTraits { + public: + typedef Type ConstType; + typedef Type MutableType; + typedef RepeatedEnumTypeTraits<Type, IsValid> Repeated; + + typedef RepeatedField<Type> RepeatedFieldType; + + static inline ConstType Get(int number, const ExtensionSet& set, int index) { + return static_cast<Type>(set.GetRepeatedEnum(number, index)); + } + static inline const ConstType* GetPtr(int number, const ExtensionSet& set, + int index) { + return reinterpret_cast<const Type*>( + &set.GetRefRepeatedEnum(number, index)); + } + static inline void Set(int number, int index, ConstType value, + ExtensionSet* set) { + GOOGLE_DCHECK(IsValid(value)); + set->SetRepeatedEnum(number, index, value); + } + static inline void Add(int number, FieldType field_type, bool is_packed, + ConstType value, ExtensionSet* set) { + GOOGLE_DCHECK(IsValid(value)); + set->AddEnum(number, field_type, is_packed, value, nullptr); + } + static inline const RepeatedField<Type>& GetRepeated( + int number, const ExtensionSet& set) { + // Hack: the `Extension` struct stores a RepeatedField<int> for enums. + // RepeatedField<int> cannot implicitly convert to RepeatedField<EnumType> + // so we need to do some casting magic. See message.h for similar + // contortions for non-extension fields. + return *reinterpret_cast<const RepeatedField<Type>*>( + set.GetRawRepeatedField(number, GetDefaultRepeatedField())); + } + static inline const RepeatedField<Type>* GetRepeatedPtr( + int number, const ExtensionSet& set) { + return &GetRepeated(number, set); + } + static inline RepeatedField<Type>* MutableRepeated(int number, + FieldType field_type, + bool is_packed, + ExtensionSet* set) { + return reinterpret_cast<RepeatedField<Type>*>( + set->MutableRawRepeatedField(number, field_type, is_packed, nullptr)); + } + + static const RepeatedFieldType* GetDefaultRepeatedField() { + // Hack: as noted above, repeated enum fields are internally stored as a + // RepeatedField<int>. We need to be able to instantiate global static + // objects to return as default (empty) repeated fields on non-existent + // extensions. We would not be able to know a-priori all of the enum types + // (values of |Type|) to instantiate all of these, so we just re-use + // arc_i32's default repeated field object. + return reinterpret_cast<const RepeatedField<Type>*>( + RepeatedPrimitiveTypeTraits<arc_i32>::GetDefaultRepeatedField()); + } + template <typename ExtendeeT> + static void Register(int number, FieldType type, bool is_packed) { + ExtensionSet::RegisterEnumExtension(&ExtendeeT::default_instance(), number, + type, true, is_packed, IsValid); + } +}; + +// ------------------------------------------------------------------- +// MessageTypeTraits + +// ExtensionSet guarantees that when manipulating extensions with message +// types, the implementation used will be the compiled-in class representing +// that type. So, we can static_cast down to the exact type we expect. +template <typename Type> +class MessageTypeTraits { + public: + typedef const Type& ConstType; + typedef Type* MutableType; + typedef MessageTypeTraits<Type> Singular; + + static inline ConstType Get(int number, const ExtensionSet& set, + ConstType default_value) { + return static_cast<const Type&>(set.GetMessage(number, default_value)); + } + static inline std::nullptr_t GetPtr(int /* number */, const ExtensionSet& /* set */, + ConstType /* default_value */) { + // Cannot be implemented because of forward declared messages? + return nullptr; + } + static inline MutableType Mutable(int number, FieldType field_type, + ExtensionSet* set) { + return static_cast<Type*>(set->MutableMessage( + number, field_type, Type::default_instance(), nullptr)); + } + static inline void SetAllocated(int number, FieldType field_type, + MutableType message, ExtensionSet* set) { + set->SetAllocatedMessage(number, field_type, nullptr, message); + } + static inline void UnsafeArenaSetAllocated(int number, FieldType field_type, + MutableType message, + ExtensionSet* set) { + set->UnsafeArenaSetAllocatedMessage(number, field_type, nullptr, message); + } + PROTOBUF_NODISCARD static inline MutableType Release( + int number, FieldType /* field_type */, ExtensionSet* set) { + return static_cast<Type*>( + set->ReleaseMessage(number, Type::default_instance())); + } + static inline MutableType UnsafeArenaRelease(int number, + FieldType /* field_type */, + ExtensionSet* set) { + return static_cast<Type*>( + set->UnsafeArenaReleaseMessage(number, Type::default_instance())); + } + template <typename ExtendeeT> + static void Register(int number, FieldType type, bool is_packed) { + ExtensionSet::RegisterMessageExtension(&ExtendeeT::default_instance(), + number, type, false, is_packed, + &Type::default_instance()); + } +}; + +// forward declaration. +class RepeatedMessageGenericTypeTraits; + +template <typename Type> +class RepeatedMessageTypeTraits { + public: + typedef const Type& ConstType; + typedef Type* MutableType; + typedef RepeatedMessageTypeTraits<Type> Repeated; + + typedef RepeatedPtrField<Type> RepeatedFieldType; + + static inline ConstType Get(int number, const ExtensionSet& set, int index) { + return static_cast<const Type&>(set.GetRepeatedMessage(number, index)); + } + static inline std::nullptr_t GetPtr(int /* number */, const ExtensionSet& /* set */, + int /* index */) { + // Cannot be implemented because of forward declared messages? + return nullptr; + } + static inline std::nullptr_t GetRepeatedPtr(int /* number */, + const ExtensionSet& /* set */) { + // Cannot be implemented because of forward declared messages? + return nullptr; + } + static inline MutableType Mutable(int number, int index, ExtensionSet* set) { + return static_cast<Type*>(set->MutableRepeatedMessage(number, index)); + } + static inline MutableType Add(int number, FieldType field_type, + ExtensionSet* set) { + return static_cast<Type*>( + set->AddMessage(number, field_type, Type::default_instance(), nullptr)); + } + static inline const RepeatedPtrField<Type>& GetRepeated( + int number, const ExtensionSet& set) { + // See notes above in RepeatedEnumTypeTraits::GetRepeated(): same + // casting hack applies here, because a RepeatedPtrField<MessageLite> + // cannot naturally become a RepeatedPtrType<Type> even though Type is + // presumably a message. google::protobuf::Message goes through similar contortions + // with a reinterpret_cast<>. + return *reinterpret_cast<const RepeatedPtrField<Type>*>( + set.GetRawRepeatedField(number, GetDefaultRepeatedField())); + } + static inline RepeatedPtrField<Type>* MutableRepeated(int number, + FieldType field_type, + bool is_packed, + ExtensionSet* set) { + return reinterpret_cast<RepeatedPtrField<Type>*>( + set->MutableRawRepeatedField(number, field_type, is_packed, nullptr)); + } + + static const RepeatedFieldType* GetDefaultRepeatedField(); + template <typename ExtendeeT> + static void Register(int number, FieldType type, bool is_packed) { + ExtensionSet::RegisterMessageExtension(&ExtendeeT::default_instance(), + number, type, true, is_packed, + &Type::default_instance()); + } +}; + +template <typename Type> +inline const typename RepeatedMessageTypeTraits<Type>::RepeatedFieldType* +RepeatedMessageTypeTraits<Type>::GetDefaultRepeatedField() { + static auto instance = OnShutdownDelete(new RepeatedFieldType); + return instance; +} + +// ------------------------------------------------------------------- +// ExtensionIdentifier + +// This is the type of actual extension objects. E.g. if you have: +// extend Foo { +// optional int32 bar = 1234; +// } +// then "bar" will be defined in C++ as: +// ExtensionIdentifier<Foo, PrimitiveTypeTraits<arc_i32>, 5, false> bar(1234); +// +// Note that we could, in theory, supply the field number as a template +// parameter, and thus make an instance of ExtensionIdentifier have no +// actual contents. However, if we did that, then using an extension +// identifier would not necessarily cause the compiler to output any sort +// of reference to any symbol defined in the extension's .pb.o file. Some +// linkers will actually drop object files that are not explicitly referenced, +// but that would be bad because it would cause this extension to not be +// registered at static initialization, and therefore using it would crash. + +template <typename ExtendeeType, typename TypeTraitsType, FieldType field_type, + bool is_packed> +class ExtensionIdentifier { + public: + typedef TypeTraitsType TypeTraits; + typedef ExtendeeType Extendee; + + ExtensionIdentifier(int number, typename TypeTraits::ConstType default_value) + : number_(number), default_value_(default_value) { + Register(number); + } + inline int number() const { return number_; } + typename TypeTraits::ConstType default_value() const { + return default_value_; + } + + static void Register(int number) { + TypeTraits::template Register<ExtendeeType>(number, field_type, is_packed); + } + + typename TypeTraits::ConstType const& default_value_ref() const { + return default_value_; + } + + private: + const int number_; + typename TypeTraits::ConstType default_value_; +}; + +// ------------------------------------------------------------------- +// Generated accessors + + +// Used to retrieve a lazy extension, may return nullptr in some environments. +extern PROTOBUF_ATTRIBUTE_WEAK ExtensionSet::LazyMessageExtension* +MaybeCreateLazyExtension(Arena* arena); + +} // namespace internal + +// Call this function to ensure that this extensions's reflection is linked into +// the binary: +// +// google::protobuf::LinkExtensionReflection(Foo::my_extension); +// +// This will ensure that the following lookup will succeed: +// +// DescriptorPool::generated_pool()->FindExtensionByName("Foo.my_extension"); +// +// This is often relevant for parsing extensions in text mode. +// +// As a side-effect, it will also guarantee that anything else from the same +// .proto file will also be available for lookup in the generated pool. +// +// This function does not actually register the extension, so it does not need +// to be called before the lookup. However it does need to occur in a function +// that cannot be stripped from the binary (ie. it must be reachable from main). +// +// Best practice is to call this function as close as possible to where the +// reflection is actually needed. This function is very cheap to call, so you +// should not need to worry about its runtime overhead except in tight loops (on +// x86-64 it compiles into two "mov" instructions). +template <typename ExtendeeType, typename TypeTraitsType, + internal::FieldType field_type, bool is_packed> +void LinkExtensionReflection( + const google::protobuf::internal::ExtensionIdentifier< + ExtendeeType, TypeTraitsType, field_type, is_packed>& extension) { + internal::StrongReference(extension); +} + +} // namespace protobuf +} // namespace google + +#include <google/protobuf/port_undef.inc> + +#endif // GOOGLE_PROTOBUF_EXTENSION_SET_H__ diff --git a/contrib/libs/protobuf_old/src/google/protobuf/extension_set_heavy.cc b/contrib/libs/protobuf_old/src/google/protobuf/extension_set_heavy.cc new file mode 100644 index 0000000000..7bb4433d70 --- /dev/null +++ b/contrib/libs/protobuf_old/src/google/protobuf/extension_set_heavy.cc @@ -0,0 +1,546 @@ +// 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: kenton@google.com (Kenton Varda) +// Based on original Protocol Buffers design by +// Sanjay Ghemawat, Jeff Dean, and others. +// +// Contains methods defined in extension_set.h which cannot be part of the +// lite library because they use descriptors or reflection. + +#include <google/protobuf/stubs/casts.h> +#include <google/protobuf/descriptor.pb.h> +#include <google/protobuf/extension_set_inl.h> +#include <google/protobuf/parse_context.h> +#include <google/protobuf/io/coded_stream.h> +#include <google/protobuf/arena.h> +#include <google/protobuf/descriptor.h> +#include <google/protobuf/extension_set.h> +#include <google/protobuf/message.h> +#include <google/protobuf/message_lite.h> +#include <google/protobuf/repeated_field.h> +#include <google/protobuf/unknown_field_set.h> +#include <google/protobuf/wire_format.h> +#include <google/protobuf/wire_format_lite.h> + + +#include <google/protobuf/port_def.inc> + +namespace google { +namespace protobuf { +namespace internal { + +// A FieldSkipper used to store unknown MessageSet fields into UnknownFieldSet. +class MessageSetFieldSkipper : public UnknownFieldSetFieldSkipper { + public: + explicit MessageSetFieldSkipper(UnknownFieldSet* unknown_fields) + : UnknownFieldSetFieldSkipper(unknown_fields) {} + ~MessageSetFieldSkipper() override {} + + virtual bool SkipMessageSetField(io::CodedInputStream* input, + int field_number); +}; +bool MessageSetFieldSkipper::SkipMessageSetField(io::CodedInputStream* input, + int field_number) { + arc_ui32 length; + if (!input->ReadVarint32(&length)) return false; + if (unknown_fields_ == nullptr) { + return input->Skip(length); + } else { + return input->ReadString(unknown_fields_->AddLengthDelimited(field_number), + length); + } +} + + +// Implementation of ExtensionFinder which finds extensions in a given +// DescriptorPool, using the given MessageFactory to construct sub-objects. +// This class is implemented in extension_set_heavy.cc. +class DescriptorPoolExtensionFinder : public ExtensionFinder { + public: + DescriptorPoolExtensionFinder(const DescriptorPool* pool, + MessageFactory* factory, + const Descriptor* containing_type) + : pool_(pool), factory_(factory), containing_type_(containing_type) {} + ~DescriptorPoolExtensionFinder() override {} + + bool Find(int number, ExtensionInfo* output) override; + + private: + const DescriptorPool* pool_; + MessageFactory* factory_; + const Descriptor* containing_type_; +}; + +void ExtensionSet::AppendToList( + const Descriptor* containing_type, const DescriptorPool* pool, + std::vector<const FieldDescriptor*>* output) const { + ForEach([containing_type, pool, &output](int number, const Extension& ext) { + bool has = false; + if (ext.is_repeated) { + has = ext.GetSize() > 0; + } else { + has = !ext.is_cleared; + } + + if (has) { + // TODO(kenton): Looking up each field by number is somewhat unfortunate. + // Is there a better way? The problem is that descriptors are lazily- + // initialized, so they might not even be constructed until + // AppendToList() is called. + + if (ext.descriptor == nullptr) { + output->push_back(pool->FindExtensionByNumber(containing_type, number)); + } else { + output->push_back(ext.descriptor); + } + } + }); +} + +inline FieldDescriptor::Type real_type(FieldType type) { + GOOGLE_DCHECK(type > 0 && type <= FieldDescriptor::MAX_TYPE); + return static_cast<FieldDescriptor::Type>(type); +} + +inline FieldDescriptor::CppType cpp_type(FieldType type) { + return FieldDescriptor::TypeToCppType( + static_cast<FieldDescriptor::Type>(type)); +} + +inline WireFormatLite::FieldType field_type(FieldType type) { + GOOGLE_DCHECK(type > 0 && type <= WireFormatLite::MAX_FIELD_TYPE); + return static_cast<WireFormatLite::FieldType>(type); +} + +#define GOOGLE_DCHECK_TYPE(EXTENSION, LABEL, CPPTYPE) \ + GOOGLE_DCHECK_EQ((EXTENSION).is_repeated ? FieldDescriptor::LABEL_REPEATED \ + : FieldDescriptor::LABEL_OPTIONAL, \ + FieldDescriptor::LABEL_##LABEL); \ + GOOGLE_DCHECK_EQ(cpp_type((EXTENSION).type), FieldDescriptor::CPPTYPE_##CPPTYPE) + +const MessageLite& ExtensionSet::GetMessage(int number, + const Descriptor* message_type, + MessageFactory* factory) const { + const Extension* extension = FindOrNull(number); + if (extension == nullptr || extension->is_cleared) { + // Not present. Return the default value. + return *factory->GetPrototype(message_type); + } else { + GOOGLE_DCHECK_TYPE(*extension, OPTIONAL, MESSAGE); + if (extension->is_lazy) { + return extension->lazymessage_value->GetMessage( + *factory->GetPrototype(message_type), arena_); + } else { + return *extension->message_value; + } + } +} + +MessageLite* ExtensionSet::MutableMessage(const FieldDescriptor* descriptor, + MessageFactory* factory) { + Extension* extension; + if (MaybeNewExtension(descriptor->number(), descriptor, &extension)) { + extension->type = descriptor->type(); + GOOGLE_DCHECK_EQ(cpp_type(extension->type), FieldDescriptor::CPPTYPE_MESSAGE); + extension->is_repeated = false; + extension->is_packed = false; + const MessageLite* prototype = + factory->GetPrototype(descriptor->message_type()); + extension->is_lazy = false; + extension->message_value = prototype->New(arena_); + extension->is_cleared = false; + return extension->message_value; + } else { + GOOGLE_DCHECK_TYPE(*extension, OPTIONAL, MESSAGE); + extension->is_cleared = false; + if (extension->is_lazy) { + return extension->lazymessage_value->MutableMessage( + *factory->GetPrototype(descriptor->message_type()), arena_); + } else { + return extension->message_value; + } + } +} + +MessageLite* ExtensionSet::ReleaseMessage(const FieldDescriptor* descriptor, + MessageFactory* factory) { + Extension* extension = FindOrNull(descriptor->number()); + if (extension == nullptr) { + // Not present. Return nullptr. + return nullptr; + } else { + GOOGLE_DCHECK_TYPE(*extension, OPTIONAL, MESSAGE); + MessageLite* ret = nullptr; + if (extension->is_lazy) { + ret = extension->lazymessage_value->ReleaseMessage( + *factory->GetPrototype(descriptor->message_type()), arena_); + if (arena_ == nullptr) { + delete extension->lazymessage_value; + } + } else { + if (arena_ != nullptr) { + ret = extension->message_value->New(); + ret->CheckTypeAndMergeFrom(*extension->message_value); + } else { + ret = extension->message_value; + } + } + Erase(descriptor->number()); + return ret; + } +} + +MessageLite* ExtensionSet::UnsafeArenaReleaseMessage( + const FieldDescriptor* descriptor, MessageFactory* factory) { + Extension* extension = FindOrNull(descriptor->number()); + if (extension == nullptr) { + // Not present. Return nullptr. + return nullptr; + } else { + GOOGLE_DCHECK_TYPE(*extension, OPTIONAL, MESSAGE); + MessageLite* ret = nullptr; + if (extension->is_lazy) { + ret = extension->lazymessage_value->UnsafeArenaReleaseMessage( + *factory->GetPrototype(descriptor->message_type()), arena_); + if (arena_ == nullptr) { + delete extension->lazymessage_value; + } + } else { + ret = extension->message_value; + } + Erase(descriptor->number()); + return ret; + } +} + +ExtensionSet::Extension* ExtensionSet::MaybeNewRepeatedExtension( + const FieldDescriptor* descriptor) { + Extension* extension; + if (MaybeNewExtension(descriptor->number(), descriptor, &extension)) { + extension->type = descriptor->type(); + GOOGLE_DCHECK_EQ(cpp_type(extension->type), FieldDescriptor::CPPTYPE_MESSAGE); + extension->is_repeated = true; + extension->repeated_message_value = + Arena::CreateMessage<RepeatedPtrField<MessageLite> >(arena_); + } else { + GOOGLE_DCHECK_TYPE(*extension, REPEATED, MESSAGE); + } + return extension; +} + +MessageLite* ExtensionSet::AddMessage(const FieldDescriptor* descriptor, + MessageFactory* factory) { + Extension* extension = MaybeNewRepeatedExtension(descriptor); + + // RepeatedPtrField<Message> does not know how to Add() since it cannot + // allocate an abstract object, so we have to be tricky. + MessageLite* result = + reinterpret_cast<internal::RepeatedPtrFieldBase*>( + extension->repeated_message_value) + ->AddFromCleared<GenericTypeHandler<MessageLite> >(); + if (result == nullptr) { + const MessageLite* prototype; + if (extension->repeated_message_value->empty()) { + prototype = factory->GetPrototype(descriptor->message_type()); + GOOGLE_CHECK(prototype != nullptr); + } else { + prototype = &extension->repeated_message_value->Get(0); + } + result = prototype->New(arena_); + extension->repeated_message_value->AddAllocated(result); + } + return result; +} + +void ExtensionSet::AddAllocatedMessage(const FieldDescriptor* descriptor, + MessageLite* new_entry) { + Extension* extension = MaybeNewRepeatedExtension(descriptor); + + extension->repeated_message_value->AddAllocated(new_entry); +} + +void ExtensionSet::UnsafeArenaAddAllocatedMessage( + const FieldDescriptor* descriptor, MessageLite* new_entry) { + Extension* extension = MaybeNewRepeatedExtension(descriptor); + + extension->repeated_message_value->UnsafeArenaAddAllocated(new_entry); +} + +static bool ValidateEnumUsingDescriptor(const void* arg, int number) { + return reinterpret_cast<const EnumDescriptor*>(arg)->FindValueByNumber( + number) != nullptr; +} + +bool DescriptorPoolExtensionFinder::Find(int number, ExtensionInfo* output) { + const FieldDescriptor* extension = + pool_->FindExtensionByNumber(containing_type_, number); + if (extension == nullptr) { + return false; + } else { + output->type = extension->type(); + output->is_repeated = extension->is_repeated(); + output->is_packed = extension->options().packed(); + output->descriptor = extension; + if (extension->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) { + output->message_info.prototype = + factory_->GetPrototype(extension->message_type()); + GOOGLE_CHECK(output->message_info.prototype != nullptr) + << "Extension factory's GetPrototype() returned nullptr; extension: " + << extension->full_name(); + } else if (extension->cpp_type() == FieldDescriptor::CPPTYPE_ENUM) { + output->enum_validity_check.func = ValidateEnumUsingDescriptor; + output->enum_validity_check.arg = extension->enum_type(); + } + + return true; + } +} + + +bool ExtensionSet::FindExtension(int wire_type, arc_ui32 field, + const Message* containing_type, + const internal::ParseContext* ctx, + ExtensionInfo* extension, + bool* was_packed_on_wire) { + if (ctx->data().pool == nullptr) { + GeneratedExtensionFinder finder(containing_type); + if (!FindExtensionInfoFromFieldNumber(wire_type, field, &finder, extension, + was_packed_on_wire)) { + return false; + } + } else { + DescriptorPoolExtensionFinder finder(ctx->data().pool, ctx->data().factory, + containing_type->GetDescriptor()); + if (!FindExtensionInfoFromFieldNumber(wire_type, field, &finder, extension, + was_packed_on_wire)) { + return false; + } + } + return true; +} + +const char* ExtensionSet::ParseField(arc_ui64 tag, const char* ptr, + const Message* containing_type, + internal::InternalMetadata* metadata, + internal::ParseContext* ctx) { + int number = tag >> 3; + bool was_packed_on_wire; + ExtensionInfo extension; + if (!FindExtension(tag & 7, number, containing_type, ctx, &extension, + &was_packed_on_wire)) { + return UnknownFieldParse( + tag, metadata->mutable_unknown_fields<UnknownFieldSet>(), ptr, ctx); + } + return ParseFieldWithExtensionInfo<UnknownFieldSet>( + number, was_packed_on_wire, extension, metadata, ptr, ctx); +} + +const char* ExtensionSet::ParseFieldMaybeLazily( + arc_ui64 tag, const char* ptr, const Message* containing_type, + internal::InternalMetadata* metadata, internal::ParseContext* ctx) { + return ParseField(tag, ptr, containing_type, metadata, ctx); +} + +const char* ExtensionSet::ParseMessageSetItem( + const char* ptr, const Message* containing_type, + internal::InternalMetadata* metadata, internal::ParseContext* ctx) { + return ParseMessageSetItemTmpl<Message, UnknownFieldSet>(ptr, containing_type, + metadata, ctx); +} + +bool ExtensionSet::ParseField(arc_ui32 tag, io::CodedInputStream* input, + const Message* containing_type, + UnknownFieldSet* unknown_fields) { + UnknownFieldSetFieldSkipper skipper(unknown_fields); + if (input->GetExtensionPool() == nullptr) { + GeneratedExtensionFinder finder(containing_type); + return ParseField(tag, input, &finder, &skipper); + } else { + DescriptorPoolExtensionFinder finder(input->GetExtensionPool(), + input->GetExtensionFactory(), + containing_type->GetDescriptor()); + return ParseField(tag, input, &finder, &skipper); + } +} + +bool ExtensionSet::ParseMessageSet(io::CodedInputStream* input, + const Message* containing_type, + UnknownFieldSet* unknown_fields) { + MessageSetFieldSkipper skipper(unknown_fields); + if (input->GetExtensionPool() == nullptr) { + GeneratedExtensionFinder finder(containing_type); + return ParseMessageSet(input, &finder, &skipper); + } else { + DescriptorPoolExtensionFinder finder(input->GetExtensionPool(), + input->GetExtensionFactory(), + containing_type->GetDescriptor()); + return ParseMessageSet(input, &finder, &skipper); + } +} + +int ExtensionSet::SpaceUsedExcludingSelf() const { + return internal::FromIntSize(SpaceUsedExcludingSelfLong()); +} + +size_t ExtensionSet::SpaceUsedExcludingSelfLong() const { + size_t total_size = Size() * sizeof(KeyValue); + ForEach([&total_size](int /* number */, const Extension& ext) { + total_size += ext.SpaceUsedExcludingSelfLong(); + }); + return total_size; +} + +inline size_t ExtensionSet::RepeatedMessage_SpaceUsedExcludingSelfLong( + RepeatedPtrFieldBase* field) { + return field->SpaceUsedExcludingSelfLong<GenericTypeHandler<Message> >(); +} + +size_t ExtensionSet::Extension::SpaceUsedExcludingSelfLong() const { + size_t total_size = 0; + if (is_repeated) { + switch (cpp_type(type)) { +#define HANDLE_TYPE(UPPERCASE, LOWERCASE) \ + case FieldDescriptor::CPPTYPE_##UPPERCASE: \ + total_size += sizeof(*repeated_##LOWERCASE##_value) + \ + repeated_##LOWERCASE##_value->SpaceUsedExcludingSelfLong(); \ + break + + HANDLE_TYPE(INT32, arc_i32); + HANDLE_TYPE(INT64, arc_i64); + HANDLE_TYPE(UINT32, arc_ui32); + HANDLE_TYPE(UINT64, arc_ui64); + HANDLE_TYPE(FLOAT, float); + HANDLE_TYPE(DOUBLE, double); + HANDLE_TYPE(BOOL, bool); + HANDLE_TYPE(ENUM, enum); + HANDLE_TYPE(STRING, string); +#undef HANDLE_TYPE + + case FieldDescriptor::CPPTYPE_MESSAGE: + // repeated_message_value is actually a RepeatedPtrField<MessageLite>, + // but MessageLite has no SpaceUsedLong(), so we must directly call + // RepeatedPtrFieldBase::SpaceUsedExcludingSelfLong() with a different + // type handler. + total_size += sizeof(*repeated_message_value) + + RepeatedMessage_SpaceUsedExcludingSelfLong( + reinterpret_cast<internal::RepeatedPtrFieldBase*>( + repeated_message_value)); + break; + } + } else { + switch (cpp_type(type)) { + case FieldDescriptor::CPPTYPE_STRING: + total_size += sizeof(*string_value) + + StringSpaceUsedExcludingSelfLong(*string_value); + break; + case FieldDescriptor::CPPTYPE_MESSAGE: + if (is_lazy) { + total_size += lazymessage_value->SpaceUsedLong(); + } else { + total_size += down_cast<Message*>(message_value)->SpaceUsedLong(); + } + break; + default: + // No extra storage costs for primitive types. + break; + } + } + return total_size; +} + +uint8_t* ExtensionSet::SerializeMessageSetWithCachedSizesToArray( + const MessageLite* extendee, uint8_t* target) const { + io::EpsCopyOutputStream stream( + target, MessageSetByteSize(), + io::CodedOutputStream::IsDefaultSerializationDeterministic()); + return InternalSerializeMessageSetWithCachedSizesToArray(extendee, target, + &stream); +} + +bool ExtensionSet::ParseFieldMaybeLazily( + int wire_type, int field_number, io::CodedInputStream* input, + ExtensionFinder* extension_finder, MessageSetFieldSkipper* field_skipper) { + return ParseField( + WireFormatLite::MakeTag(field_number, + static_cast<WireFormatLite::WireType>(wire_type)), + input, extension_finder, field_skipper); +} + +bool ExtensionSet::ParseMessageSet(io::CodedInputStream* input, + ExtensionFinder* extension_finder, + MessageSetFieldSkipper* field_skipper) { + while (true) { + const arc_ui32 tag = input->ReadTag(); + switch (tag) { + case 0: + return true; + case WireFormatLite::kMessageSetItemStartTag: + if (!ParseMessageSetItem(input, extension_finder, field_skipper)) { + return false; + } + break; + default: + if (!ParseField(tag, input, extension_finder, field_skipper)) { + return false; + } + break; + } + } +} + +bool ExtensionSet::ParseMessageSetItem(io::CodedInputStream* input, + ExtensionFinder* extension_finder, + MessageSetFieldSkipper* field_skipper) { + struct MSFull { + bool ParseField(int type_id, io::CodedInputStream* input) { + return me->ParseFieldMaybeLazily( + WireFormatLite::WIRETYPE_LENGTH_DELIMITED, type_id, input, + extension_finder, field_skipper); + } + + bool SkipField(arc_ui32 tag, io::CodedInputStream* input) { + return field_skipper->SkipField(input, tag); + } + + ExtensionSet* me; + ExtensionFinder* extension_finder; + MessageSetFieldSkipper* field_skipper; + }; + + return ParseMessageSetItemImpl(input, + MSFull{this, extension_finder, field_skipper}); +} + +} // namespace internal +} // namespace protobuf +} // namespace google + +#include <google/protobuf/port_undef.inc> diff --git a/contrib/libs/protobuf_old/src/google/protobuf/extension_set_inl.h b/contrib/libs/protobuf_old/src/google/protobuf/extension_set_inl.h new file mode 100644 index 0000000000..df05f610aa --- /dev/null +++ b/contrib/libs/protobuf_old/src/google/protobuf/extension_set_inl.h @@ -0,0 +1,276 @@ +// 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_EXTENSION_SET_INL_H__ +#define GOOGLE_PROTOBUF_EXTENSION_SET_INL_H__ + +#include <google/protobuf/parse_context.h> +#include <google/protobuf/extension_set.h> +#include <google/protobuf/metadata_lite.h> + +namespace google { +namespace protobuf { +namespace internal { + +template <typename T> +const char* ExtensionSet::ParseFieldWithExtensionInfo( + int number, bool was_packed_on_wire, const ExtensionInfo& extension, + InternalMetadata* metadata, const char* ptr, internal::ParseContext* ctx) { + if (was_packed_on_wire) { + switch (extension.type) { +#define HANDLE_TYPE(UPPERCASE, CPP_CAMELCASE) \ + case WireFormatLite::TYPE_##UPPERCASE: \ + return internal::Packed##CPP_CAMELCASE##Parser( \ + MutableRawRepeatedField(number, extension.type, extension.is_packed, \ + extension.descriptor), \ + ptr, ctx); + HANDLE_TYPE(INT32, Int32); + HANDLE_TYPE(INT64, Int64); + HANDLE_TYPE(UINT32, UInt32); + HANDLE_TYPE(UINT64, UInt64); + HANDLE_TYPE(SINT32, SInt32); + HANDLE_TYPE(SINT64, SInt64); + HANDLE_TYPE(FIXED32, Fixed32); + HANDLE_TYPE(FIXED64, Fixed64); + HANDLE_TYPE(SFIXED32, SFixed32); + HANDLE_TYPE(SFIXED64, SFixed64); + HANDLE_TYPE(FLOAT, Float); + HANDLE_TYPE(DOUBLE, Double); + HANDLE_TYPE(BOOL, Bool); +#undef HANDLE_TYPE + + case WireFormatLite::TYPE_ENUM: + return internal::PackedEnumParserArg<T>( + MutableRawRepeatedField(number, extension.type, extension.is_packed, + extension.descriptor), + ptr, ctx, extension.enum_validity_check.func, + extension.enum_validity_check.arg, metadata, number); + case WireFormatLite::TYPE_STRING: + case WireFormatLite::TYPE_BYTES: + case WireFormatLite::TYPE_GROUP: + case WireFormatLite::TYPE_MESSAGE: + GOOGLE_LOG(FATAL) << "Non-primitive types can't be packed."; + break; + } + } else { + switch (extension.type) { +#define HANDLE_VARINT_TYPE(UPPERCASE, CPP_CAMELCASE) \ + case WireFormatLite::TYPE_##UPPERCASE: { \ + arc_ui64 value; \ + ptr = VarintParse(ptr, &value); \ + GOOGLE_PROTOBUF_PARSER_ASSERT(ptr); \ + if (extension.is_repeated) { \ + Add##CPP_CAMELCASE(number, WireFormatLite::TYPE_##UPPERCASE, \ + extension.is_packed, value, extension.descriptor); \ + } else { \ + Set##CPP_CAMELCASE(number, WireFormatLite::TYPE_##UPPERCASE, value, \ + extension.descriptor); \ + } \ + } break + + HANDLE_VARINT_TYPE(INT32, Int32); + HANDLE_VARINT_TYPE(INT64, Int64); + HANDLE_VARINT_TYPE(UINT32, UInt32); + HANDLE_VARINT_TYPE(UINT64, UInt64); + HANDLE_VARINT_TYPE(BOOL, Bool); +#undef HANDLE_VARINT_TYPE +#define HANDLE_SVARINT_TYPE(UPPERCASE, CPP_CAMELCASE, SIZE) \ + case WireFormatLite::TYPE_##UPPERCASE: { \ + arc_ui64 val; \ + ptr = VarintParse(ptr, &val); \ + GOOGLE_PROTOBUF_PARSER_ASSERT(ptr); \ + auto value = WireFormatLite::ZigZagDecode##SIZE(val); \ + if (extension.is_repeated) { \ + Add##CPP_CAMELCASE(number, WireFormatLite::TYPE_##UPPERCASE, \ + extension.is_packed, value, extension.descriptor); \ + } else { \ + Set##CPP_CAMELCASE(number, WireFormatLite::TYPE_##UPPERCASE, value, \ + extension.descriptor); \ + } \ + } break + + HANDLE_SVARINT_TYPE(SINT32, Int32, 32); + HANDLE_SVARINT_TYPE(SINT64, Int64, 64); +#undef HANDLE_SVARINT_TYPE +#define HANDLE_FIXED_TYPE(UPPERCASE, CPP_CAMELCASE, CPPTYPE) \ + case WireFormatLite::TYPE_##UPPERCASE: { \ + auto value = UnalignedLoad<CPPTYPE>(ptr); \ + ptr += sizeof(CPPTYPE); \ + if (extension.is_repeated) { \ + Add##CPP_CAMELCASE(number, WireFormatLite::TYPE_##UPPERCASE, \ + extension.is_packed, value, extension.descriptor); \ + } else { \ + Set##CPP_CAMELCASE(number, WireFormatLite::TYPE_##UPPERCASE, value, \ + extension.descriptor); \ + } \ + } break + + HANDLE_FIXED_TYPE(FIXED32, UInt32, arc_ui32); + HANDLE_FIXED_TYPE(FIXED64, UInt64, arc_ui64); + HANDLE_FIXED_TYPE(SFIXED32, Int32, arc_i32); + HANDLE_FIXED_TYPE(SFIXED64, Int64, arc_i64); + HANDLE_FIXED_TYPE(FLOAT, Float, float); + HANDLE_FIXED_TYPE(DOUBLE, Double, double); +#undef HANDLE_FIXED_TYPE + + case WireFormatLite::TYPE_ENUM: { + arc_ui64 val; + ptr = VarintParse(ptr, &val); + GOOGLE_PROTOBUF_PARSER_ASSERT(ptr); + int value = val; + + if (!extension.enum_validity_check.func( + extension.enum_validity_check.arg, value)) { + WriteVarint(number, val, metadata->mutable_unknown_fields<T>()); + } else if (extension.is_repeated) { + AddEnum(number, WireFormatLite::TYPE_ENUM, extension.is_packed, value, + extension.descriptor); + } else { + SetEnum(number, WireFormatLite::TYPE_ENUM, value, + extension.descriptor); + } + break; + } + + case WireFormatLite::TYPE_BYTES: + case WireFormatLite::TYPE_STRING: { + TProtoStringType* value = + extension.is_repeated + ? AddString(number, WireFormatLite::TYPE_STRING, + extension.descriptor) + : MutableString(number, WireFormatLite::TYPE_STRING, + extension.descriptor); + int size = ReadSize(&ptr); + GOOGLE_PROTOBUF_PARSER_ASSERT(ptr); + return ctx->ReadString(ptr, size, value); + } + + case WireFormatLite::TYPE_GROUP: { + MessageLite* value = + extension.is_repeated + ? AddMessage(number, WireFormatLite::TYPE_GROUP, + *extension.message_info.prototype, + extension.descriptor) + : MutableMessage(number, WireFormatLite::TYPE_GROUP, + *extension.message_info.prototype, + extension.descriptor); + arc_ui32 tag = (number << 3) + WireFormatLite::WIRETYPE_START_GROUP; + return ctx->ParseGroup(value, ptr, tag); + } + + case WireFormatLite::TYPE_MESSAGE: { + MessageLite* value = + extension.is_repeated + ? AddMessage(number, WireFormatLite::TYPE_MESSAGE, + *extension.message_info.prototype, + extension.descriptor) + : MutableMessage(number, WireFormatLite::TYPE_MESSAGE, + *extension.message_info.prototype, + extension.descriptor); + return ctx->ParseMessage(value, ptr); + } + } + } + return ptr; +} + +template <typename Msg, typename T> +const char* ExtensionSet::ParseMessageSetItemTmpl( + const char* ptr, const Msg* extendee, internal::InternalMetadata* metadata, + internal::ParseContext* ctx) { + TProtoStringType payload; + arc_ui32 type_id = 0; + bool payload_read = false; + while (!ctx->Done(&ptr)) { + arc_ui32 tag = static_cast<uint8_t>(*ptr++); + if (tag == WireFormatLite::kMessageSetTypeIdTag) { + arc_ui64 tmp; + ptr = ParseBigVarint(ptr, &tmp); + GOOGLE_PROTOBUF_PARSER_ASSERT(ptr); + type_id = tmp; + if (payload_read) { + ExtensionInfo extension; + bool was_packed_on_wire; + if (!FindExtension(2, type_id, extendee, ctx, &extension, + &was_packed_on_wire)) { + WriteLengthDelimited(type_id, payload, + metadata->mutable_unknown_fields<T>()); + } else { + MessageLite* value = + extension.is_repeated + ? AddMessage(type_id, WireFormatLite::TYPE_MESSAGE, + *extension.message_info.prototype, + extension.descriptor) + : MutableMessage(type_id, WireFormatLite::TYPE_MESSAGE, + *extension.message_info.prototype, + extension.descriptor); + + const char* p; + // We can't use regular parse from string as we have to track + // proper recursion depth and descriptor pools. + ParseContext tmp_ctx(ctx->depth(), false, &p, payload); + tmp_ctx.data().pool = ctx->data().pool; + tmp_ctx.data().factory = ctx->data().factory; + GOOGLE_PROTOBUF_PARSER_ASSERT(value->_InternalParse(p, &tmp_ctx) && + tmp_ctx.EndedAtLimit()); + } + type_id = 0; + } + } else if (tag == WireFormatLite::kMessageSetMessageTag) { + if (type_id != 0) { + ptr = ParseFieldMaybeLazily(static_cast<arc_ui64>(type_id) * 8 + 2, ptr, + extendee, metadata, ctx); + GOOGLE_PROTOBUF_PARSER_ASSERT(ptr != nullptr); + type_id = 0; + } else { + arc_i32 size = ReadSize(&ptr); + GOOGLE_PROTOBUF_PARSER_ASSERT(ptr); + ptr = ctx->ReadString(ptr, size, &payload); + GOOGLE_PROTOBUF_PARSER_ASSERT(ptr); + payload_read = true; + } + } else { + ptr = ReadTag(ptr - 1, &tag); + if (tag == 0 || (tag & 7) == 4) { + ctx->SetLastTag(tag); + return ptr; + } + ptr = ParseField(tag, ptr, extendee, metadata, ctx); + GOOGLE_PROTOBUF_PARSER_ASSERT(ptr); + } + } + return ptr; +} + +} // namespace internal +} // namespace protobuf +} // namespace google + +#endif // GOOGLE_PROTOBUF_EXTENSION_SET_INL_H__ diff --git a/contrib/libs/protobuf_old/src/google/protobuf/field_mask.pb.cc b/contrib/libs/protobuf_old/src/google/protobuf/field_mask.pb.cc new file mode 100644 index 0000000000..25d027839e --- /dev/null +++ b/contrib/libs/protobuf_old/src/google/protobuf/field_mask.pb.cc @@ -0,0 +1,276 @@ +// Generated by the protocol buffer compiler. DO NOT EDIT! +// source: google/protobuf/field_mask.proto + +#include <google/protobuf/field_mask.pb.h> + +#include <algorithm> + +#include <google/protobuf/io/coded_stream.h> +#include <google/protobuf/extension_set.h> +#include <google/protobuf/wire_format_lite.h> +#include <google/protobuf/descriptor.h> +#include <google/protobuf/generated_message_reflection.h> +#include <google/protobuf/reflection_ops.h> +#include <google/protobuf/wire_format.h> +// @@protoc_insertion_point(includes) +#include <google/protobuf/port_def.inc> + +PROTOBUF_PRAGMA_INIT_SEG +PROTOBUF_NAMESPACE_OPEN +constexpr FieldMask::FieldMask( + ::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized) + : paths_(){} +struct FieldMaskDefaultTypeInternal { + constexpr FieldMaskDefaultTypeInternal() + : _instance(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized{}) {} + ~FieldMaskDefaultTypeInternal() {} + union { + FieldMask _instance; + }; +}; +PROTOBUF_ATTRIBUTE_NO_DESTROY PROTOBUF_CONSTINIT FieldMaskDefaultTypeInternal _FieldMask_default_instance_; +PROTOBUF_NAMESPACE_CLOSE +static ::PROTOBUF_NAMESPACE_ID::Metadata file_level_metadata_google_2fprotobuf_2ffield_5fmask_2eproto[1]; +static constexpr ::PROTOBUF_NAMESPACE_ID::EnumDescriptor const** file_level_enum_descriptors_google_2fprotobuf_2ffield_5fmask_2eproto = nullptr; +static constexpr ::PROTOBUF_NAMESPACE_ID::ServiceDescriptor const** file_level_service_descriptors_google_2fprotobuf_2ffield_5fmask_2eproto = nullptr; + +const arc_ui32 TableStruct_google_2fprotobuf_2ffield_5fmask_2eproto::offsets[] PROTOBUF_SECTION_VARIABLE(protodesc_cold) = { + ~0u, // no _has_bits_ + PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::FieldMask, _internal_metadata_), + ~0u, // no _extensions_ + ~0u, // no _oneof_case_ + ~0u, // no _weak_field_map_ + ~0u, // no _inlined_string_donated_ + PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::FieldMask, paths_), +}; +static const ::PROTOBUF_NAMESPACE_ID::internal::MigrationSchema schemas[] PROTOBUF_SECTION_VARIABLE(protodesc_cold) = { + { 0, -1, -1, sizeof(::PROTOBUF_NAMESPACE_ID::FieldMask)}, +}; + +static ::PROTOBUF_NAMESPACE_ID::Message const * const file_default_instances[] = { + reinterpret_cast<const ::PROTOBUF_NAMESPACE_ID::Message*>(&::PROTOBUF_NAMESPACE_ID::_FieldMask_default_instance_), +}; + +const char descriptor_table_protodef_google_2fprotobuf_2ffield_5fmask_2eproto[] PROTOBUF_SECTION_VARIABLE(protodesc_cold) = + "\n google/protobuf/field_mask.proto\022\017goog" + "le.protobuf\"\032\n\tFieldMask\022\r\n\005paths\030\001 \003(\tB" + "\205\001\n\023com.google.protobufB\016FieldMaskProtoP" + "\001Z2google.golang.org/protobuf/types/know" + "n/fieldmaskpb\370\001\001\242\002\003GPB\252\002\036Google.Protobuf" + ".WellKnownTypesb\006proto3" + ; +static ::PROTOBUF_NAMESPACE_ID::internal::once_flag descriptor_table_google_2fprotobuf_2ffield_5fmask_2eproto_once; +const ::PROTOBUF_NAMESPACE_ID::internal::DescriptorTable descriptor_table_google_2fprotobuf_2ffield_5fmask_2eproto = { + false, false, 223, descriptor_table_protodef_google_2fprotobuf_2ffield_5fmask_2eproto, "google/protobuf/field_mask.proto", + &descriptor_table_google_2fprotobuf_2ffield_5fmask_2eproto_once, nullptr, 0, 1, + schemas, file_default_instances, TableStruct_google_2fprotobuf_2ffield_5fmask_2eproto::offsets, + file_level_metadata_google_2fprotobuf_2ffield_5fmask_2eproto, file_level_enum_descriptors_google_2fprotobuf_2ffield_5fmask_2eproto, file_level_service_descriptors_google_2fprotobuf_2ffield_5fmask_2eproto, +}; +PROTOBUF_ATTRIBUTE_WEAK const ::PROTOBUF_NAMESPACE_ID::internal::DescriptorTable* descriptor_table_google_2fprotobuf_2ffield_5fmask_2eproto_getter() { + return &descriptor_table_google_2fprotobuf_2ffield_5fmask_2eproto; +} + +// Force running AddDescriptors() at dynamic initialization time. +PROTOBUF_ATTRIBUTE_INIT_PRIORITY static ::PROTOBUF_NAMESPACE_ID::internal::AddDescriptorsRunner dynamic_init_dummy_google_2fprotobuf_2ffield_5fmask_2eproto(&descriptor_table_google_2fprotobuf_2ffield_5fmask_2eproto); +PROTOBUF_NAMESPACE_OPEN + +// =================================================================== + +class FieldMask::_Internal { + public: +}; + +FieldMask::FieldMask(::PROTOBUF_NAMESPACE_ID::Arena* arena, + bool is_message_owned) + : ::PROTOBUF_NAMESPACE_ID::Message(arena, is_message_owned), + paths_(arena) { + SharedCtor(); + if (!is_message_owned) { + RegisterArenaDtor(arena); + } + // @@protoc_insertion_point(arena_constructor:google.protobuf.FieldMask) +} +FieldMask::FieldMask(const FieldMask& from) + : ::PROTOBUF_NAMESPACE_ID::Message(), + paths_(from.paths_) { + _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_); + // @@protoc_insertion_point(copy_constructor:google.protobuf.FieldMask) +} + +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>(); +} + +inline void FieldMask::SharedDtor() { + GOOGLE_DCHECK(GetArenaForAllocation() == nullptr); +} + +void FieldMask::ArenaDtor(void* object) { + FieldMask* _this = reinterpret_cast< FieldMask* >(object); + (void)_this; +} +void FieldMask::RegisterArenaDtor(::PROTOBUF_NAMESPACE_ID::Arena*) { +} +void FieldMask::SetCachedSize(int size) const { + _cached_size_.Set(size); +} + +void FieldMask::Clear() { +// @@protoc_insertion_point(message_clear_start:google.protobuf.FieldMask) + arc_ui32 cached_has_bits = 0; + // Prevent compiler warnings about cached_has_bits being unused + (void) cached_has_bits; + + paths_.Clear(); + _internal_metadata_.Clear<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(); +} + +const char* FieldMask::_InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) { +#define CHK_(x) if (PROTOBUF_PREDICT_FALSE(!(x))) goto failure + while (!ctx->Done(&ptr)) { + arc_ui32 tag; + ptr = ::PROTOBUF_NAMESPACE_ID::internal::ReadTag(ptr, &tag); + switch (tag >> 3) { + // repeated string paths = 1; + case 1: + if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 10)) { + ptr -= 1; + do { + ptr += 1; + auto str = _internal_add_paths(); + ptr = ::PROTOBUF_NAMESPACE_ID::internal::InlineGreedyStringParser(str, ptr, ctx); + CHK_(::PROTOBUF_NAMESPACE_ID::internal::VerifyUTF8(str, "google.protobuf.FieldMask.paths")); + CHK_(ptr); + if (!ctx->DataAvailable(ptr)) break; + } while (::PROTOBUF_NAMESPACE_ID::internal::ExpectTag<10>(ptr)); + } else + goto handle_unusual; + continue; + default: + goto handle_unusual; + } // switch + handle_unusual: + if ((tag == 0) || ((tag & 7) == 4)) { + CHK_(ptr); + ctx->SetLastTag(tag); + goto message_done; + } + ptr = UnknownFieldParse( + tag, + _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(), + ptr, ctx); + CHK_(ptr != nullptr); + } // while +message_done: + return ptr; +failure: + ptr = nullptr; + goto message_done; +#undef CHK_ +} + +uint8_t* FieldMask::_InternalSerialize( + uint8_t* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const { + // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.FieldMask) + arc_ui32 cached_has_bits = 0; + (void) cached_has_bits; + + // repeated string paths = 1; + for (int i = 0, n = this->_internal_paths_size(); i < n; i++) { + const auto& s = this->_internal_paths(i); + ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::VerifyUtf8String( + s.data(), static_cast<int>(s.length()), + ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::SERIALIZE, + "google.protobuf.FieldMask.paths"); + target = stream->WriteString(1, s, target); + } + + if (PROTOBUF_PREDICT_FALSE(_internal_metadata_.have_unknown_fields())) { + target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::InternalSerializeUnknownFieldsToArray( + _internal_metadata_.unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(::PROTOBUF_NAMESPACE_ID::UnknownFieldSet::default_instance), target, stream); + } + // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.FieldMask) + return target; +} + +size_t FieldMask::ByteSizeLong() const { +// @@protoc_insertion_point(message_byte_size_start:google.protobuf.FieldMask) + size_t total_size = 0; + + arc_ui32 cached_has_bits = 0; + // Prevent compiler warnings about cached_has_bits being unused + (void) cached_has_bits; + + // repeated string paths = 1; + total_size += 1 * + ::PROTOBUF_NAMESPACE_ID::internal::FromIntSize(paths_.size()); + for (int i = 0, n = paths_.size(); i < n; i++) { + total_size += ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::StringSize( + paths_.Get(i)); + } + + return MaybeComputeUnknownFieldsSize(total_size, &_cached_size_); +} + +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); + arc_ui32 cached_has_bits = 0; + (void) cached_has_bits; + + paths_.MergeFrom(from.paths_); + _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_); +} + +void FieldMask::CopyFrom(const FieldMask& from) { +// @@protoc_insertion_point(class_specific_copy_from_start:google.protobuf.FieldMask) + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool FieldMask::IsInitialized() const { + return true; +} + +void FieldMask::InternalSwap(FieldMask* other) { + using std::swap; + _internal_metadata_.InternalSwap(&other->_internal_metadata_); + paths_.InternalSwap(&other->paths_); +} + +::PROTOBUF_NAMESPACE_ID::Metadata FieldMask::GetMetadata() const { + return ::PROTOBUF_NAMESPACE_ID::internal::AssignDescriptors( + &descriptor_table_google_2fprotobuf_2ffield_5fmask_2eproto_getter, &descriptor_table_google_2fprotobuf_2ffield_5fmask_2eproto_once, + file_level_metadata_google_2fprotobuf_2ffield_5fmask_2eproto[0]); +} + +// @@protoc_insertion_point(namespace_scope) +PROTOBUF_NAMESPACE_CLOSE +PROTOBUF_NAMESPACE_OPEN +template<> PROTOBUF_NOINLINE ::PROTOBUF_NAMESPACE_ID::FieldMask* Arena::CreateMaybeMessage< ::PROTOBUF_NAMESPACE_ID::FieldMask >(Arena* arena) { + return Arena::CreateMessageInternal< ::PROTOBUF_NAMESPACE_ID::FieldMask >(arena); +} +PROTOBUF_NAMESPACE_CLOSE + +// @@protoc_insertion_point(global_scope) +#include <google/protobuf/port_undef.inc> diff --git a/contrib/libs/protobuf_old/src/google/protobuf/field_mask.pb.h b/contrib/libs/protobuf_old/src/google/protobuf/field_mask.pb.h new file mode 100644 index 0000000000..fe0a7ae2db --- /dev/null +++ b/contrib/libs/protobuf_old/src/google/protobuf/field_mask.pb.h @@ -0,0 +1,324 @@ +// Generated by the protocol buffer compiler. DO NOT EDIT! +// source: google/protobuf/field_mask.proto + +#ifndef GOOGLE_PROTOBUF_INCLUDED_google_2fprotobuf_2ffield_5fmask_2eproto +#define GOOGLE_PROTOBUF_INCLUDED_google_2fprotobuf_2ffield_5fmask_2eproto + +#include <limits> +#include <string> + +#include <google/protobuf/port_def.inc> +#if PROTOBUF_VERSION < 3019000 +#error This file was generated by a newer version of protoc which is +#error incompatible with your Protocol Buffer headers. Please update +#error your headers. +#endif +#if 3019000 < PROTOBUF_MIN_PROTOC_VERSION +#error This file was generated by an older version of protoc which is +#error incompatible with your Protocol Buffer headers. Please +#error regenerate this file with a newer version of protoc. +#endif + +#include <google/protobuf/port_undef.inc> +#include <google/protobuf/io/coded_stream.h> +#include <google/protobuf/arena.h> +#include <google/protobuf/arenastring.h> +#include <google/protobuf/generated_message_table_driven.h> +#include <google/protobuf/generated_message_util.h> +#include <google/protobuf/metadata_lite.h> +#include <google/protobuf/generated_message_reflection.h> +#include <google/protobuf/message.h> +#include <google/protobuf/repeated_field.h> // IWYU pragma: export +#include <google/protobuf/extension_set.h> // IWYU pragma: export +#include <google/protobuf/unknown_field_set.h> +// @@protoc_insertion_point(includes) +#include <google/protobuf/port_def.inc> +#define PROTOBUF_INTERNAL_EXPORT_google_2fprotobuf_2ffield_5fmask_2eproto PROTOBUF_EXPORT +PROTOBUF_NAMESPACE_OPEN +namespace internal { +class AnyMetadata; +} // namespace internal +PROTOBUF_NAMESPACE_CLOSE + +// Internal implementation detail -- do not use these members. +struct PROTOBUF_EXPORT TableStruct_google_2fprotobuf_2ffield_5fmask_2eproto { + static const ::PROTOBUF_NAMESPACE_ID::internal::ParseTableField entries[] + PROTOBUF_SECTION_VARIABLE(protodesc_cold); + static const ::PROTOBUF_NAMESPACE_ID::internal::AuxiliaryParseTableField aux[] + PROTOBUF_SECTION_VARIABLE(protodesc_cold); + static const ::PROTOBUF_NAMESPACE_ID::internal::ParseTable schema[1] + PROTOBUF_SECTION_VARIABLE(protodesc_cold); + static const ::PROTOBUF_NAMESPACE_ID::internal::FieldMetadata field_metadata[]; + static const ::PROTOBUF_NAMESPACE_ID::internal::SerializationTable serialization_table[]; + static const arc_ui32 offsets[]; +}; +PROTOBUF_EXPORT extern const ::PROTOBUF_NAMESPACE_ID::internal::DescriptorTable descriptor_table_google_2fprotobuf_2ffield_5fmask_2eproto; +PROTOBUF_NAMESPACE_OPEN +class FieldMask; +struct FieldMaskDefaultTypeInternal; +PROTOBUF_EXPORT extern FieldMaskDefaultTypeInternal _FieldMask_default_instance_; +PROTOBUF_NAMESPACE_CLOSE +PROTOBUF_NAMESPACE_OPEN +template<> PROTOBUF_EXPORT ::PROTOBUF_NAMESPACE_ID::FieldMask* Arena::CreateMaybeMessage<::PROTOBUF_NAMESPACE_ID::FieldMask>(Arena*); +PROTOBUF_NAMESPACE_CLOSE +PROTOBUF_NAMESPACE_OPEN + +// =================================================================== + +class PROTOBUF_EXPORT FieldMask final : + public ::PROTOBUF_NAMESPACE_ID::Message /* @@protoc_insertion_point(class_definition:google.protobuf.FieldMask) */ { + public: + inline FieldMask() : FieldMask(nullptr) {} + ~FieldMask() override; + explicit constexpr FieldMask(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized); + + FieldMask(const FieldMask& from); + FieldMask(FieldMask&& from) noexcept + : FieldMask() { + *this = ::std::move(from); + } + + inline FieldMask& operator=(const FieldMask& from) { + CopyFrom(from); + return *this; + } + inline FieldMask& operator=(FieldMask&& from) noexcept { + if (this == &from) return *this; + if (GetOwningArena() == from.GetOwningArena() + #ifdef PROTOBUF_FORCE_COPY_IN_MOVE + && GetOwningArena() != nullptr + #endif // !PROTOBUF_FORCE_COPY_IN_MOVE + ) { + InternalSwap(&from); + } else { + CopyFrom(from); + } + return *this; + } + + static const ::PROTOBUF_NAMESPACE_ID::Descriptor* descriptor() { + return GetDescriptor(); + } + static const ::PROTOBUF_NAMESPACE_ID::Descriptor* GetDescriptor() { + return default_instance().GetMetadata().descriptor; + } + static const ::PROTOBUF_NAMESPACE_ID::Reflection* GetReflection() { + return default_instance().GetMetadata().reflection; + } + static const FieldMask& default_instance() { + return *internal_default_instance(); + } + static inline const FieldMask* internal_default_instance() { + return reinterpret_cast<const FieldMask*>( + &_FieldMask_default_instance_); + } + static constexpr int kIndexInFileMessages = + 0; + + friend void swap(FieldMask& a, FieldMask& b) { + a.Swap(&b); + } + inline void Swap(FieldMask* other) { + if (other == this) return; + #ifdef PROTOBUF_FORCE_COPY_IN_SWAP + if (GetOwningArena() != nullptr && + GetOwningArena() == other->GetOwningArena()) { + #else // PROTOBUF_FORCE_COPY_IN_SWAP + if (GetOwningArena() == other->GetOwningArena()) { + #endif // !PROTOBUF_FORCE_COPY_IN_SWAP + InternalSwap(other); + } else { + ::PROTOBUF_NAMESPACE_ID::internal::GenericSwap(this, other); + } + } + void UnsafeArenaSwap(FieldMask* other) { + if (other == this) return; + GOOGLE_DCHECK(GetOwningArena() == other->GetOwningArena()); + InternalSwap(other); + } + + // implements Message ---------------------------------------------- + + FieldMask* New(::PROTOBUF_NAMESPACE_ID::Arena* arena = nullptr) const final { + return CreateMaybeMessage<FieldMask>(arena); + } + 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; + + size_t ByteSizeLong() const final; + const char* _InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) final; + uint8_t* _InternalSerialize( + uint8_t* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const final; + int GetCachedSize() const final { return _cached_size_.Get(); } + + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const final; + void InternalSwap(FieldMask* other); + + private: + friend class ::PROTOBUF_NAMESPACE_ID::internal::AnyMetadata; + static ::PROTOBUF_NAMESPACE_ID::StringPiece FullMessageName() { + return "google.protobuf.FieldMask"; + } + protected: + 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 ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + enum : int { + kPathsFieldNumber = 1, + }; + // repeated string paths = 1; + int paths_size() const; + private: + int _internal_paths_size() const; + public: + void clear_paths(); + const TProtoStringType& paths(int index) const; + TProtoStringType* mutable_paths(int index); + void set_paths(int index, const TProtoStringType& value); + void set_paths(int index, TProtoStringType&& value); + void set_paths(int index, const char* value); + void set_paths(int index, const char* value, size_t size); + TProtoStringType* add_paths(); + void add_paths(const TProtoStringType& value); + void add_paths(TProtoStringType&& value); + void add_paths(const char* value); + void add_paths(const char* value, size_t size); + const ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField<TProtoStringType>& paths() const; + ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField<TProtoStringType>* mutable_paths(); + private: + const TProtoStringType& _internal_paths(int index) const; + TProtoStringType* _internal_add_paths(); + public: + + // @@protoc_insertion_point(class_scope:google.protobuf.FieldMask) + private: + class _Internal; + + template <typename T> friend class ::PROTOBUF_NAMESPACE_ID::Arena::InternalHelper; + typedef void InternalArenaConstructable_; + typedef void DestructorSkippable_; + ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField<TProtoStringType> paths_; + mutable ::PROTOBUF_NAMESPACE_ID::internal::CachedSize _cached_size_; + friend struct ::TableStruct_google_2fprotobuf_2ffield_5fmask_2eproto; +}; +// =================================================================== + + +// =================================================================== + +#ifdef __GNUC__ + #pragma GCC diagnostic push + #pragma GCC diagnostic ignored "-Wstrict-aliasing" +#endif // __GNUC__ +// FieldMask + +// repeated string paths = 1; +inline int FieldMask::_internal_paths_size() const { + return paths_.size(); +} +inline int FieldMask::paths_size() const { + return _internal_paths_size(); +} +inline void FieldMask::clear_paths() { + paths_.Clear(); +} +inline TProtoStringType* FieldMask::add_paths() { + TProtoStringType* _s = _internal_add_paths(); + // @@protoc_insertion_point(field_add_mutable:google.protobuf.FieldMask.paths) + return _s; +} +inline const TProtoStringType& FieldMask::_internal_paths(int index) const { + return paths_.Get(index); +} +inline const TProtoStringType& FieldMask::paths(int index) const { + // @@protoc_insertion_point(field_get:google.protobuf.FieldMask.paths) + return _internal_paths(index); +} +inline TProtoStringType* FieldMask::mutable_paths(int index) { + // @@protoc_insertion_point(field_mutable:google.protobuf.FieldMask.paths) + return paths_.Mutable(index); +} +inline void FieldMask::set_paths(int index, const TProtoStringType& value) { + paths_.Mutable(index)->assign(value); + // @@protoc_insertion_point(field_set:google.protobuf.FieldMask.paths) +} +inline void FieldMask::set_paths(int index, TProtoStringType&& value) { + 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); + paths_.Mutable(index)->assign(value); + // @@protoc_insertion_point(field_set_char:google.protobuf.FieldMask.paths) +} +inline void FieldMask::set_paths(int index, const char* value, size_t size) { + paths_.Mutable(index)->assign( + reinterpret_cast<const char*>(value), size); + // @@protoc_insertion_point(field_set_pointer:google.protobuf.FieldMask.paths) +} +inline TProtoStringType* FieldMask::_internal_add_paths() { + return paths_.Add(); +} +inline void FieldMask::add_paths(const TProtoStringType& value) { + paths_.Add()->assign(value); + // @@protoc_insertion_point(field_add:google.protobuf.FieldMask.paths) +} +inline void FieldMask::add_paths(TProtoStringType&& value) { + paths_.Add(std::move(value)); + // @@protoc_insertion_point(field_add:google.protobuf.FieldMask.paths) +} +inline void FieldMask::add_paths(const char* value) { + GOOGLE_DCHECK(value != nullptr); + paths_.Add()->assign(value); + // @@protoc_insertion_point(field_add_char:google.protobuf.FieldMask.paths) +} +inline void FieldMask::add_paths(const char* value, size_t size) { + paths_.Add()->assign(reinterpret_cast<const char*>(value), size); + // @@protoc_insertion_point(field_add_pointer:google.protobuf.FieldMask.paths) +} +inline const ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField<TProtoStringType>& +FieldMask::paths() const { + // @@protoc_insertion_point(field_list:google.protobuf.FieldMask.paths) + return paths_; +} +inline ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField<TProtoStringType>* +FieldMask::mutable_paths() { + // @@protoc_insertion_point(field_mutable_list:google.protobuf.FieldMask.paths) + return &paths_; +} + +#ifdef __GNUC__ + #pragma GCC diagnostic pop +#endif // __GNUC__ + +// @@protoc_insertion_point(namespace_scope) + +PROTOBUF_NAMESPACE_CLOSE + +// @@protoc_insertion_point(global_scope) + +#include <google/protobuf/port_undef.inc> +#endif // GOOGLE_PROTOBUF_INCLUDED_GOOGLE_PROTOBUF_INCLUDED_google_2fprotobuf_2ffield_5fmask_2eproto diff --git a/contrib/libs/protobuf_old/src/google/protobuf/field_mask.proto b/contrib/libs/protobuf_old/src/google/protobuf/field_mask.proto new file mode 100644 index 0000000000..6b5104f188 --- /dev/null +++ b/contrib/libs/protobuf_old/src/google/protobuf/field_mask.proto @@ -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. + +syntax = "proto3"; + +package google.protobuf; + +option csharp_namespace = "Google.Protobuf.WellKnownTypes"; +option java_package = "com.google.protobuf"; +option java_outer_classname = "FieldMaskProto"; +option java_multiple_files = true; +option objc_class_prefix = "GPB"; +option go_package = "google.golang.org/protobuf/types/known/fieldmaskpb"; +option cc_enable_arenas = true; + +// `FieldMask` represents a set of symbolic field paths, for example: +// +// paths: "f.a" +// paths: "f.b.d" +// +// Here `f` represents a field in some root message, `a` and `b` +// fields in the message found in `f`, and `d` a field found in the +// message in `f.b`. +// +// Field masks are used to specify a subset of fields that should be +// returned by a get operation or modified by an update operation. +// Field masks also have a custom JSON encoding (see below). +// +// # Field Masks in Projections +// +// When used in the context of a projection, a response message or +// sub-message is filtered by the API to only contain those fields as +// specified in the mask. For example, if the mask in the previous +// example is applied to a response message as follows: +// +// f { +// a : 22 +// b { +// d : 1 +// x : 2 +// } +// y : 13 +// } +// z: 8 +// +// The result will not contain specific values for fields x,y and z +// (their value will be set to the default, and omitted in proto text +// output): +// +// +// f { +// a : 22 +// b { +// d : 1 +// } +// } +// +// A repeated field is not allowed except at the last position of a +// paths string. +// +// If a FieldMask object is not present in a get operation, the +// operation applies to all fields (as if a FieldMask of all fields +// had been specified). +// +// Note that a field mask does not necessarily apply to the +// top-level response message. In case of a REST get operation, the +// field mask applies directly to the response, but in case of a REST +// list operation, the mask instead applies to each individual message +// in the returned resource list. In case of a REST custom method, +// other definitions may be used. Where the mask applies will be +// clearly documented together with its declaration in the API. In +// any case, the effect on the returned resource/resources is required +// behavior for APIs. +// +// # Field Masks in Update Operations +// +// A field mask in update operations specifies which fields of the +// targeted resource are going to be updated. The API is required +// to only change the values of the fields as specified in the mask +// and leave the others untouched. If a resource is passed in to +// describe the updated values, the API ignores the values of all +// fields not covered by the mask. +// +// If a repeated field is specified for an update operation, new values will +// be appended to the existing repeated field in the target resource. Note that +// a repeated field is only allowed in the last position of a `paths` string. +// +// If a sub-message is specified in the last position of the field mask for an +// update operation, then new value will be merged into the existing sub-message +// in the target resource. +// +// For example, given the target message: +// +// f { +// b { +// d: 1 +// x: 2 +// } +// c: [1] +// } +// +// And an update message: +// +// f { +// b { +// d: 10 +// } +// c: [2] +// } +// +// then if the field mask is: +// +// paths: ["f.b", "f.c"] +// +// then the result will be: +// +// f { +// b { +// d: 10 +// x: 2 +// } +// c: [1, 2] +// } +// +// An implementation may provide options to override this default behavior for +// repeated and message fields. +// +// In order to reset a field's value to the default, the field must +// be in the mask and set to the default value in the provided resource. +// Hence, in order to reset all fields of a resource, provide a default +// instance of the resource and set all fields in the mask, or do +// not provide a mask as described below. +// +// If a field mask is not present on update, the operation applies to +// all fields (as if a field mask of all fields has been specified). +// Note that in the presence of schema evolution, this may mean that +// fields the client does not know and has therefore not filled into +// the request will be reset to their default. If this is unwanted +// behavior, a specific service may require a client to always specify +// a field mask, producing an error if not. +// +// As with get operations, the location of the resource which +// describes the updated values in the request message depends on the +// operation kind. In any case, the effect of the field mask is +// required to be honored by the API. +// +// ## Considerations for HTTP REST +// +// The HTTP kind of an update operation which uses a field mask must +// be set to PATCH instead of PUT in order to satisfy HTTP semantics +// (PUT must only be used for full updates). +// +// # JSON Encoding of Field Masks +// +// In JSON, a field mask is encoded as a single string where paths are +// separated by a comma. Fields name in each path are converted +// to/from lower-camel naming conventions. +// +// As an example, consider the following message declarations: +// +// message Profile { +// User user = 1; +// Photo photo = 2; +// } +// message User { +// string display_name = 1; +// string address = 2; +// } +// +// In proto a field mask for `Profile` may look as such: +// +// mask { +// paths: "user.display_name" +// paths: "photo" +// } +// +// In JSON, the same mask is represented as below: +// +// { +// mask: "user.displayName,photo" +// } +// +// # Field Masks and Oneof Fields +// +// Field masks treat fields in oneofs just as regular fields. Consider the +// following message: +// +// message SampleMessage { +// oneof test_oneof { +// string name = 4; +// SubMessage sub_message = 9; +// } +// } +// +// The field mask can be: +// +// mask { +// paths: "name" +// } +// +// Or: +// +// mask { +// paths: "sub_message" +// } +// +// Note that oneof type names ("test_oneof" in this case) cannot be used in +// paths. +// +// ## Field Mask Verification +// +// The implementation of any API method which has a FieldMask type field in the +// request should verify the included field paths, and return an +// `INVALID_ARGUMENT` error if any path is unmappable. +message FieldMask { + // The set of field mask paths. + repeated string paths = 1; +} diff --git a/contrib/libs/protobuf_old/src/google/protobuf/generated_enum_reflection.h b/contrib/libs/protobuf_old/src/google/protobuf/generated_enum_reflection.h new file mode 100644 index 0000000000..f20eba71b5 --- /dev/null +++ b/contrib/libs/protobuf_old/src/google/protobuf/generated_enum_reflection.h @@ -0,0 +1,98 @@ +// 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: jasonh@google.com (Jason Hsueh) +// +// This header is logically internal, but is made public because it is used +// from protocol-compiler-generated code, which may reside in other components. +// It provides reflection support for generated enums, and is included in +// generated .pb.h files and should have minimal dependencies. The methods are +// implemented in generated_message_reflection.cc. + +#ifndef GOOGLE_PROTOBUF_GENERATED_ENUM_REFLECTION_H__ +#define GOOGLE_PROTOBUF_GENERATED_ENUM_REFLECTION_H__ + +#include <string> + +#include <google/protobuf/generated_enum_util.h> +#include <google/protobuf/port.h> +#include <google/protobuf/stubs/strutil.h> + +#ifdef SWIG +#error "You cannot SWIG proto headers" +#endif + +#include <google/protobuf/port_def.inc> + +namespace google { +namespace protobuf { +class EnumDescriptor; +} // namespace protobuf +} // namespace google + +namespace google { +namespace protobuf { + +// Returns the EnumDescriptor for enum type E, which must be a +// proto-declared enum type. Code generated by the protocol compiler +// will include specializations of this template for each enum type declared. +template <typename E> +const EnumDescriptor* GetEnumDescriptor(); + +namespace internal { + +// Helper for EnumType_Parse functions: try to parse the string 'name' as +// an enum name of the given type, returning true and filling in value on +// success, or returning false and leaving value unchanged on failure. +PROTOBUF_EXPORT bool ParseNamedEnum(const EnumDescriptor* descriptor, + ConstStringParam name, int* value); + +template <typename EnumType> +bool ParseNamedEnum(const EnumDescriptor* descriptor, ConstStringParam name, + EnumType* value) { + int tmp; + if (!ParseNamedEnum(descriptor, name, &tmp)) return false; + *value = static_cast<EnumType>(tmp); + return true; +} + +// Just a wrapper around printing the name of a value. The main point of this +// function is not to be inlined, so that you can do this without including +// descriptor.h. +PROTOBUF_EXPORT const TProtoStringType& NameOfEnum(const EnumDescriptor* descriptor, + int value); + +} // namespace internal +} // namespace protobuf +} // namespace google + +#include <google/protobuf/port_undef.inc> + +#endif // GOOGLE_PROTOBUF_GENERATED_ENUM_REFLECTION_H__ diff --git a/contrib/libs/protobuf_old/src/google/protobuf/generated_enum_util.cc b/contrib/libs/protobuf_old/src/google/protobuf/generated_enum_util.cc new file mode 100644 index 0000000000..35939309a5 --- /dev/null +++ b/contrib/libs/protobuf_old/src/google/protobuf/generated_enum_util.cc @@ -0,0 +1,95 @@ +// 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 <google/protobuf/generated_enum_util.h> + +#include <algorithm> + +#include <google/protobuf/generated_message_util.h> + +namespace google { +namespace protobuf { +namespace internal { +namespace { + +bool EnumCompareByName(const EnumEntry& a, const EnumEntry& b) { + return StringPiece(a.name) < StringPiece(b.name); +} + +// Gets the numeric value of the EnumEntry at the given index, but returns a +// special value for the index -1. This gives a way to use std::lower_bound on a +// sorted array of indices while searching for value that we associate with -1. +int GetValue(const EnumEntry* enums, int i, int target) { + if (i == -1) { + return target; + } else { + return enums[i].value; + } +} + +} // namespace + +bool LookUpEnumValue(const EnumEntry* enums, size_t size, + StringPiece name, int* value) { + EnumEntry target{name, 0}; + auto it = std::lower_bound(enums, enums + size, target, EnumCompareByName); + if (it != enums + size && it->name == name) { + *value = it->value; + return true; + } + return false; +} + +int LookUpEnumName(const EnumEntry* enums, const int* sorted_indices, + size_t size, int value) { + auto comparator = [enums, value](int a, int b) { + return GetValue(enums, a, value) < GetValue(enums, b, value); + }; + auto it = + std::lower_bound(sorted_indices, sorted_indices + size, -1, comparator); + if (it != sorted_indices + size && enums[*it].value == value) { + return it - sorted_indices; + } + return -1; +} + +bool InitializeEnumStrings( + const EnumEntry* enums, const int* sorted_indices, size_t size, + internal::ExplicitlyConstructed<TProtoStringType>* enum_strings) { + for (size_t i = 0; i < size; ++i) { + enum_strings[i].Construct(enums[sorted_indices[i]].name); + internal::OnShutdownDestroyString(enum_strings[i].get_mutable()); + } + return true; +} + +} // namespace internal +} // namespace protobuf +} // namespace google diff --git a/contrib/libs/protobuf_old/src/google/protobuf/generated_enum_util.h b/contrib/libs/protobuf_old/src/google/protobuf/generated_enum_util.h new file mode 100644 index 0000000000..d987a5e626 --- /dev/null +++ b/contrib/libs/protobuf_old/src/google/protobuf/generated_enum_util.h @@ -0,0 +1,83 @@ +// 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_ENUM_UTIL_H__ +#define GOOGLE_PROTOBUF_GENERATED_ENUM_UTIL_H__ + +#include <type_traits> + +#include <google/protobuf/message_lite.h> +#include <google/protobuf/stubs/strutil.h> + +#include <google/protobuf/port_def.inc> + +#ifdef SWIG +#error "You cannot SWIG proto headers" +#endif + +namespace google { +namespace protobuf { + +// This type trait can be used to cause templates to only match proto2 enum +// types. +template <typename T> +struct is_proto_enum : ::std::false_type {}; + +namespace internal { + +// The table entry format for storing enum name-to-value mapping used with lite +// protos. This struct and the following related functions should only be used +// by protobuf generated code. +struct EnumEntry { + StringPiece name; + int value; +}; + +// Looks up a numeric enum value given the string name. +PROTOBUF_EXPORT bool LookUpEnumValue(const EnumEntry* enums, size_t size, + StringPiece name, int* value); + +// Looks up an enum name given the numeric value. +PROTOBUF_EXPORT int LookUpEnumName(const EnumEntry* enums, + const int* sorted_indices, size_t size, + int value); + +// Initializes the list of enum names in TProtoStringType form. +PROTOBUF_EXPORT bool InitializeEnumStrings( + const EnumEntry* enums, const int* sorted_indices, size_t size, + internal::ExplicitlyConstructed<TProtoStringType>* enum_strings); + +} // namespace internal +} // namespace protobuf +} // namespace google + +#include <google/protobuf/port_undef.inc> + +#endif // GOOGLE_PROTOBUF_GENERATED_ENUM_UTIL_H__ diff --git a/contrib/libs/protobuf_old/src/google/protobuf/generated_message_bases.cc b/contrib/libs/protobuf_old/src/google/protobuf/generated_message_bases.cc new file mode 100644 index 0000000000..0679ab51a1 --- /dev/null +++ b/contrib/libs/protobuf_old/src/google/protobuf/generated_message_bases.cc @@ -0,0 +1,125 @@ +// 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 <google/protobuf/generated_message_bases.h> + +#include <google/protobuf/parse_context.h> +#include <google/protobuf/io/coded_stream.h> +#include <google/protobuf/io/zero_copy_stream_impl.h> +#include <google/protobuf/unknown_field_set.h> +#include <google/protobuf/wire_format.h> +#include <google/protobuf/wire_format_lite.h> + +// Must be last: +#include <google/protobuf/port_def.inc> + +namespace google { +namespace protobuf { +namespace internal { + +// ============================================================================= +// ZeroFieldsBase + +void ZeroFieldsBase::Clear() { + _internal_metadata_.Clear<UnknownFieldSet>(); // +} + +ZeroFieldsBase::~ZeroFieldsBase() { + if (GetArenaForAllocation() != nullptr) return; + _internal_metadata_.Delete<UnknownFieldSet>(); +} + +size_t ZeroFieldsBase::ByteSizeLong() const { + return MaybeComputeUnknownFieldsSize(0, &_cached_size_); +} + +const char* ZeroFieldsBase::_InternalParse(const char* ptr, + internal::ParseContext* ctx) { +#define CHK_(x) \ + if (PROTOBUF_PREDICT_FALSE(!(x))) { \ + goto failure; \ + } + + while (!ctx->Done(&ptr)) { + arc_ui32 tag; + ptr = internal::ReadTag(ptr, &tag); + if ((tag == 0) || ((tag & 7) == 4)) { + CHK_(ptr); + ctx->SetLastTag(tag); + goto message_done; + } + ptr = UnknownFieldParse( + tag, _internal_metadata_.mutable_unknown_fields<UnknownFieldSet>(), ptr, + ctx); + CHK_(ptr); + } // while +message_done: + return ptr; +failure: + ptr = nullptr; + goto message_done; +#undef CHK_ +} + +::uint8_t* ZeroFieldsBase::_InternalSerialize( + ::uint8_t* target, io::EpsCopyOutputStream* stream) const { + if (PROTOBUF_PREDICT_FALSE(_internal_metadata_.have_unknown_fields())) { + target = internal::WireFormat::InternalSerializeUnknownFieldsToArray( + _internal_metadata_.unknown_fields<UnknownFieldSet>( + UnknownFieldSet::default_instance), + target, stream); + } + return target; +} + +void ZeroFieldsBase::MergeImpl(Message* to_param, const Message& from_param) { + auto* to = static_cast<ZeroFieldsBase*>(to_param); + const auto* from = static_cast<const ZeroFieldsBase*>(&from_param); + GOOGLE_DCHECK_NE(from, to); + to->_internal_metadata_.MergeFrom<UnknownFieldSet>(from->_internal_metadata_); +} + +void ZeroFieldsBase::CopyImpl(Message* to_param, const Message& from_param) { + auto* to = static_cast<ZeroFieldsBase*>(to_param); + const auto* from = static_cast<const ZeroFieldsBase*>(&from_param); + if (from == to) return; + to->_internal_metadata_.Clear<UnknownFieldSet>(); + to->_internal_metadata_.MergeFrom<UnknownFieldSet>(from->_internal_metadata_); +} + +void ZeroFieldsBase::InternalSwap(ZeroFieldsBase* other) { + _internal_metadata_.Swap<UnknownFieldSet>(&other->_internal_metadata_); +} + +} // namespace internal +} // namespace protobuf +} // namespace google + +#include <google/protobuf/port_undef.inc> diff --git a/contrib/libs/protobuf_old/src/google/protobuf/generated_message_bases.h b/contrib/libs/protobuf_old/src/google/protobuf/generated_message_bases.h new file mode 100644 index 0000000000..29ab66bd4f --- /dev/null +++ b/contrib/libs/protobuf_old/src/google/protobuf/generated_message_bases.h @@ -0,0 +1,87 @@ +// 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 helpers for generated code. +// +// Nothing in this file should be directly referenced by users of protobufs. + +#ifndef GOOGLE_PROTOBUF_GENERATED_MESSAGE_BASES_H__ +#define GOOGLE_PROTOBUF_GENERATED_MESSAGE_BASES_H__ + +#include <google/protobuf/parse_context.h> +#include <google/protobuf/io/zero_copy_stream_impl.h> +#include <google/protobuf/arena.h> +#include <google/protobuf/generated_message_util.h> +#include <google/protobuf/message.h> + +// Must come last: +#include <google/protobuf/port_def.inc> + +namespace google { +namespace protobuf { +namespace internal { + +// To save code size, protos without any fields are derived from ZeroFieldsBase +// rather than Message. +class PROTOBUF_EXPORT ZeroFieldsBase : public Message { + public: + PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final; + bool IsInitialized() const final { return true; } + size_t ByteSizeLong() const final; + int GetCachedSize() const final { return _cached_size_.Get(); } + const char* _InternalParse(const char* ptr, + internal::ParseContext* ctx) final; + ::uint8_t* _InternalSerialize(::uint8_t* target, + io::EpsCopyOutputStream* stream) const final; + + protected: + constexpr ZeroFieldsBase() {} + explicit ZeroFieldsBase(Arena* arena, bool is_message_owned) + : Message(arena, is_message_owned) {} + ZeroFieldsBase(const ZeroFieldsBase&) = delete; + ZeroFieldsBase& operator=(const ZeroFieldsBase&) = delete; + ~ZeroFieldsBase() override; + + void SetCachedSize(int size) const final { _cached_size_.Set(size); } + + static void MergeImpl(Message* to, const Message& from); + static void CopyImpl(Message* to, const Message& from); + void InternalSwap(ZeroFieldsBase* other); + + mutable internal::CachedSize _cached_size_; +}; + +} // namespace internal +} // namespace protobuf +} // namespace google + +#include <google/protobuf/port_undef.inc> + +#endif // GOOGLE_PROTOBUF_GENERATED_MESSAGE_BASES_H__ diff --git a/contrib/libs/protobuf_old/src/google/protobuf/generated_message_reflection.cc b/contrib/libs/protobuf_old/src/google/protobuf/generated_message_reflection.cc new file mode 100644 index 0000000000..dae6e8feae --- /dev/null +++ b/contrib/libs/protobuf_old/src/google/protobuf/generated_message_reflection.cc @@ -0,0 +1,3041 @@ +// 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: kenton@google.com (Kenton Varda) +// Based on original Protocol Buffers design by +// Sanjay Ghemawat, Jeff Dean, and others. + +#include <google/protobuf/generated_message_reflection.h> + +#include <algorithm> +#include <set> + +#include <google/protobuf/stubs/logging.h> +#include <google/protobuf/stubs/common.h> +#include <google/protobuf/descriptor.pb.h> +#include <google/protobuf/descriptor.h> +#include <google/protobuf/extension_set.h> +#include <google/protobuf/generated_message_util.h> +#include <google/protobuf/inlined_string_field.h> +#include <google/protobuf/map_field.h> +#include <google/protobuf/map_field_inl.h> +#include <google/protobuf/stubs/mutex.h> +#include <google/protobuf/repeated_field.h> +#include <google/protobuf/unknown_field_set.h> +#include <google/protobuf/wire_format.h> +#include <google/protobuf/stubs/casts.h> +#include <google/protobuf/stubs/strutil.h> + + +// clang-format off +#include <google/protobuf/port_def.inc> +// clang-format on + +#define GOOGLE_PROTOBUF_HAS_ONEOF + +using google::protobuf::internal::ArenaStringPtr; +using google::protobuf::internal::DescriptorTable; +using google::protobuf::internal::ExtensionSet; +using google::protobuf::internal::GenericTypeHandler; +using google::protobuf::internal::GetEmptyString; +using google::protobuf::internal::InlinedStringField; +using google::protobuf::internal::InternalMetadata; +using google::protobuf::internal::LazyField; +using google::protobuf::internal::MapFieldBase; +using google::protobuf::internal::MigrationSchema; +using google::protobuf::internal::OnShutdownDelete; +using google::protobuf::internal::ReflectionSchema; +using google::protobuf::internal::RepeatedPtrFieldBase; +using google::protobuf::internal::StringSpaceUsedExcludingSelfLong; +using google::protobuf::internal::WrappedMutex; + +namespace google { +namespace protobuf { + +namespace { +bool IsMapFieldInApi(const FieldDescriptor* field) { return field->is_map(); } + +#ifdef PROTOBUF_FORCE_COPY_IN_RELEASE +Message* MaybeForceCopy(Arena* arena, Message* msg) { + if (arena != nullptr || msg == nullptr) return msg; + + Message* copy = msg->New(); + copy->MergeFrom(*msg); + delete msg; + return copy; +} +#endif // PROTOBUF_FORCE_COPY_IN_RELEASE +} // anonymous namespace + +namespace internal { + +bool ParseNamedEnum(const EnumDescriptor* descriptor, ConstStringParam name, + int* value) { + const EnumValueDescriptor* d = descriptor->FindValueByName(name); + if (d == nullptr) return false; + *value = d->number(); + return true; +} + +const TProtoStringType& NameOfEnum(const EnumDescriptor* descriptor, int value) { + const EnumValueDescriptor* d = descriptor->FindValueByNumber(value); + return (d == nullptr ? GetEmptyString() : d->name()); +} + +} // namespace internal + +// =================================================================== +// Helpers for reporting usage errors (e.g. trying to use GetInt32() on +// a string field). + +namespace { + +using internal::GetConstPointerAtOffset; +using internal::GetConstRefAtOffset; +using internal::GetPointerAtOffset; + +void ReportReflectionUsageError(const Descriptor* descriptor, + const FieldDescriptor* field, + const char* method, const char* description) { + GOOGLE_LOG(FATAL) << "Protocol Buffer reflection usage error:\n" + " Method : google::protobuf::Reflection::" + << method + << "\n" + " Message type: " + << descriptor->full_name() + << "\n" + " Field : " + << field->full_name() + << "\n" + " Problem : " + << description; +} + +const char* cpptype_names_[FieldDescriptor::MAX_CPPTYPE + 1] = { + "INVALID_CPPTYPE", "CPPTYPE_INT32", "CPPTYPE_INT64", "CPPTYPE_UINT32", + "CPPTYPE_UINT64", "CPPTYPE_DOUBLE", "CPPTYPE_FLOAT", "CPPTYPE_BOOL", + "CPPTYPE_ENUM", "CPPTYPE_STRING", "CPPTYPE_MESSAGE"}; + +static void ReportReflectionUsageTypeError( + const Descriptor* descriptor, const FieldDescriptor* field, + const char* method, FieldDescriptor::CppType expected_type) { + GOOGLE_LOG(FATAL) + << "Protocol Buffer reflection usage error:\n" + " Method : google::protobuf::Reflection::" + << method + << "\n" + " Message type: " + << descriptor->full_name() + << "\n" + " Field : " + << field->full_name() + << "\n" + " Problem : Field is not the right type for this message:\n" + " Expected : " + << cpptype_names_[expected_type] + << "\n" + " Field type: " + << cpptype_names_[field->cpp_type()]; +} + +static void ReportReflectionUsageEnumTypeError( + const Descriptor* descriptor, const FieldDescriptor* field, + const char* method, const EnumValueDescriptor* value) { + GOOGLE_LOG(FATAL) << "Protocol Buffer reflection usage error:\n" + " Method : google::protobuf::Reflection::" + << method + << "\n" + " Message type: " + << descriptor->full_name() + << "\n" + " Field : " + << field->full_name() + << "\n" + " Problem : Enum value did not match field type:\n" + " Expected : " + << field->enum_type()->full_name() + << "\n" + " Actual : " + << value->full_name(); +} + +inline void CheckInvalidAccess(const internal::ReflectionSchema& schema, + const FieldDescriptor* field) { + GOOGLE_CHECK(!schema.IsFieldStripped(field)) + << "invalid access to a stripped field " << field->full_name(); +} + +#define USAGE_CHECK(CONDITION, METHOD, ERROR_DESCRIPTION) \ + if (!(CONDITION)) \ + ReportReflectionUsageError(descriptor_, field, #METHOD, ERROR_DESCRIPTION) +#define USAGE_CHECK_EQ(A, B, METHOD, ERROR_DESCRIPTION) \ + USAGE_CHECK((A) == (B), METHOD, ERROR_DESCRIPTION) +#define USAGE_CHECK_NE(A, B, METHOD, ERROR_DESCRIPTION) \ + USAGE_CHECK((A) != (B), METHOD, ERROR_DESCRIPTION) + +#define USAGE_CHECK_TYPE(METHOD, CPPTYPE) \ + if (field->cpp_type() != FieldDescriptor::CPPTYPE_##CPPTYPE) \ + ReportReflectionUsageTypeError(descriptor_, field, #METHOD, \ + FieldDescriptor::CPPTYPE_##CPPTYPE) + +#define USAGE_CHECK_ENUM_VALUE(METHOD) \ + if (value->type() != field->enum_type()) \ + ReportReflectionUsageEnumTypeError(descriptor_, field, #METHOD, value) + +#define USAGE_CHECK_MESSAGE_TYPE(METHOD) \ + USAGE_CHECK_EQ(field->containing_type(), descriptor_, METHOD, \ + "Field does not match message type."); +#define USAGE_CHECK_SINGULAR(METHOD) \ + USAGE_CHECK_NE(field->label(), FieldDescriptor::LABEL_REPEATED, METHOD, \ + "Field is repeated; the method requires a singular field.") +#define USAGE_CHECK_REPEATED(METHOD) \ + USAGE_CHECK_EQ(field->label(), FieldDescriptor::LABEL_REPEATED, METHOD, \ + "Field is singular; the method requires a repeated field.") + +#define USAGE_CHECK_ALL(METHOD, LABEL, CPPTYPE) \ + USAGE_CHECK_MESSAGE_TYPE(METHOD); \ + USAGE_CHECK_##LABEL(METHOD); \ + USAGE_CHECK_TYPE(METHOD, CPPTYPE) + +} // namespace + +// =================================================================== + +Reflection::Reflection(const Descriptor* descriptor, + const internal::ReflectionSchema& schema, + const DescriptorPool* pool, MessageFactory* factory) + : descriptor_(descriptor), + schema_(schema), + descriptor_pool_( + (pool == nullptr) ? DescriptorPool::internal_generated_pool() : pool), + message_factory_(factory), + last_non_weak_field_index_(-1) { + last_non_weak_field_index_ = descriptor_->field_count() - 1; +} + +const UnknownFieldSet& Reflection::GetUnknownFields( + const Message& message) const { + return GetInternalMetadata(message).unknown_fields<UnknownFieldSet>( + UnknownFieldSet::default_instance); +} + +UnknownFieldSet* Reflection::MutableUnknownFields(Message* message) const { + return MutableInternalMetadata(message) + ->mutable_unknown_fields<UnknownFieldSet>(); +} + +bool Reflection::IsLazyExtension(const Message& message, + const FieldDescriptor* field) const { + return field->is_extension() && + GetExtensionSet(message).HasLazy(field->number()); +} + +bool Reflection::IsLazilyVerifiedLazyField(const FieldDescriptor* field) const { + return field->options().lazy(); +} + +bool Reflection::IsEagerlyVerifiedLazyField( + const FieldDescriptor* field) const { + return (field->type() == FieldDescriptor::TYPE_MESSAGE && + schema_.IsEagerlyVerifiedLazyField(field)); +} + +bool Reflection::IsInlined(const FieldDescriptor* field) const { + return schema_.IsFieldInlined(field); +} + +size_t Reflection::SpaceUsedLong(const Message& message) const { + // object_size_ already includes the in-memory representation of each field + // in the message, so we only need to account for additional memory used by + // the fields. + size_t total_size = schema_.GetObjectSize(); + + total_size += GetUnknownFields(message).SpaceUsedExcludingSelfLong(); + + if (schema_.HasExtensionSet()) { + total_size += GetExtensionSet(message).SpaceUsedExcludingSelfLong(); + } + for (int i = 0; i <= last_non_weak_field_index_; i++) { + const FieldDescriptor* field = descriptor_->field(i); + if (field->is_repeated()) { + switch (field->cpp_type()) { +#define HANDLE_TYPE(UPPERCASE, LOWERCASE) \ + case FieldDescriptor::CPPTYPE_##UPPERCASE: \ + total_size += GetRaw<RepeatedField<LOWERCASE> >(message, field) \ + .SpaceUsedExcludingSelfLong(); \ + break + + HANDLE_TYPE(INT32, arc_i32); + HANDLE_TYPE(INT64, arc_i64); + HANDLE_TYPE(UINT32, arc_ui32); + HANDLE_TYPE(UINT64, arc_ui64); + HANDLE_TYPE(DOUBLE, double); + HANDLE_TYPE(FLOAT, float); + HANDLE_TYPE(BOOL, bool); + HANDLE_TYPE(ENUM, int); +#undef HANDLE_TYPE + + case FieldDescriptor::CPPTYPE_STRING: + switch (field->options().ctype()) { + default: // TODO(kenton): Support other string reps. + case FieldOptions::STRING: + total_size += + GetRaw<RepeatedPtrField<TProtoStringType> >(message, field) + .SpaceUsedExcludingSelfLong(); + break; + } + break; + + case FieldDescriptor::CPPTYPE_MESSAGE: + if (IsMapFieldInApi(field)) { + total_size += GetRaw<internal::MapFieldBase>(message, field) + .SpaceUsedExcludingSelfLong(); + } else { + // We don't know which subclass of RepeatedPtrFieldBase the type is, + // so we use RepeatedPtrFieldBase directly. + total_size += + GetRaw<RepeatedPtrFieldBase>(message, field) + .SpaceUsedExcludingSelfLong<GenericTypeHandler<Message> >(); + } + + break; + } + } else { + if (schema_.InRealOneof(field) && !HasOneofField(message, field)) { + continue; + } + switch (field->cpp_type()) { + case FieldDescriptor::CPPTYPE_INT32: + case FieldDescriptor::CPPTYPE_INT64: + case FieldDescriptor::CPPTYPE_UINT32: + case FieldDescriptor::CPPTYPE_UINT64: + case FieldDescriptor::CPPTYPE_DOUBLE: + case FieldDescriptor::CPPTYPE_FLOAT: + case FieldDescriptor::CPPTYPE_BOOL: + case FieldDescriptor::CPPTYPE_ENUM: + // Field is inline, so we've already counted it. + break; + + case FieldDescriptor::CPPTYPE_STRING: { + switch (field->options().ctype()) { + default: // TODO(kenton): Support other string reps. + case FieldOptions::STRING: { + if (IsInlined(field)) { + const TProtoStringType* ptr = + &GetField<InlinedStringField>(message, field).GetNoArena(); + total_size += StringSpaceUsedExcludingSelfLong(*ptr); + break; + } + + const TProtoStringType* ptr = + GetField<ArenaStringPtr>(message, field).GetPointer(); + + // Initially, the string points to the default value stored + // in the prototype. Only count the string if it has been + // changed from the default value. + // Except oneof fields, those never point to a default instance, + // and there is no default instance to point to. + if (schema_.InRealOneof(field) || + ptr != DefaultRaw<ArenaStringPtr>(field).GetPointer()) { + // string fields are represented by just a pointer, so also + // include sizeof(string) as well. + total_size += + sizeof(*ptr) + StringSpaceUsedExcludingSelfLong(*ptr); + } + break; + } + } + break; + } + + case FieldDescriptor::CPPTYPE_MESSAGE: + if (schema_.IsDefaultInstance(message)) { + // For singular fields, the prototype just stores a pointer to the + // external type's prototype, so there is no extra memory usage. + } else { + const Message* sub_message = GetRaw<const Message*>(message, field); + if (sub_message != nullptr) { + total_size += sub_message->SpaceUsedLong(); + } + } + break; + } + } + } + return total_size; +} + +namespace { + +template <bool unsafe_shallow_swap> +struct OneofFieldMover { + template <typename FromType, typename ToType> + void operator()(const FieldDescriptor* field, FromType* from, ToType* to) { + switch (field->cpp_type()) { + case FieldDescriptor::CPPTYPE_INT32: + to->SetInt32(from->GetInt32()); + break; + case FieldDescriptor::CPPTYPE_INT64: + to->SetInt64(from->GetInt64()); + break; + case FieldDescriptor::CPPTYPE_UINT32: + to->SetUint32(from->GetUint32()); + break; + case FieldDescriptor::CPPTYPE_UINT64: + to->SetUint64(from->GetUint64()); + break; + case FieldDescriptor::CPPTYPE_FLOAT: + to->SetFloat(from->GetFloat()); + break; + case FieldDescriptor::CPPTYPE_DOUBLE: + to->SetDouble(from->GetDouble()); + break; + case FieldDescriptor::CPPTYPE_BOOL: + to->SetBool(from->GetBool()); + break; + case FieldDescriptor::CPPTYPE_ENUM: + to->SetEnum(from->GetEnum()); + break; + case FieldDescriptor::CPPTYPE_MESSAGE: + if (!unsafe_shallow_swap) { + to->SetMessage(from->GetMessage()); + } else { + to->UnsafeSetMessage(from->UnsafeGetMessage()); + } + break; + case FieldDescriptor::CPPTYPE_STRING: + if (!unsafe_shallow_swap) { + to->SetString(from->GetString()); + break; + } + switch (field->options().ctype()) { + default: + case FieldOptions::STRING: { + to->SetArenaStringPtr(from->GetArenaStringPtr()); + break; + } + } + break; + default: + GOOGLE_LOG(FATAL) << "unimplemented type: " << field->cpp_type(); + } + if (unsafe_shallow_swap) { + // Not clearing oneof case after move may cause unwanted "ClearOneof" + // where the residual message or string value is deleted and causes + // use-after-free (only for unsafe swap). + from->ClearOneofCase(); + } + } +}; + +} // namespace + +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 SwapInlinedStrings(const Reflection* r, Message* lhs, + Message* rhs, const FieldDescriptor* field); + + template <bool unsafe_shallow_swap> + static void SwapNonInlinedStrings(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 TProtoStringType* 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<TProtoStringType>>(rhs_string); + } + break; + } + } +} + +template <bool unsafe_shallow_swap> +void SwapFieldHelper::SwapInlinedStrings(const Reflection* r, Message* lhs, + Message* rhs, + const FieldDescriptor* field) { + // Inlined string field. + Arena* lhs_arena = lhs->GetArenaForAllocation(); + Arena* rhs_arena = rhs->GetArenaForAllocation(); + auto* lhs_string = r->MutableRaw<InlinedStringField>(lhs, field); + auto* rhs_string = r->MutableRaw<InlinedStringField>(rhs, field); + const uint32 index = r->schema_.InlinedStringIndex(field); + uint32* lhs_state = &r->MutableInlinedStringDonatedArray(lhs)[index / 32]; + uint32* rhs_state = &r->MutableInlinedStringDonatedArray(rhs)[index / 32]; + const uint32 mask = ~(static_cast<uint32>(1) << (index % 32)); + if (unsafe_shallow_swap || lhs_arena == rhs_arena) { + lhs_string->Swap(rhs_string, /*default_value=*/nullptr, lhs_arena, + r->IsInlinedStringDonated(*lhs, field), + r->IsInlinedStringDonated(*rhs, field), + /*donating_states=*/lhs_state, rhs_state, mask); + } else { + const TProtoStringType temp = lhs_string->Get(); + lhs_string->Set(nullptr, rhs_string->Get(), lhs_arena, + r->IsInlinedStringDonated(*lhs, field), lhs_state, mask); + rhs_string->Set(nullptr, temp, rhs_arena, + r->IsInlinedStringDonated(*rhs, field), rhs_state, mask); + } +} + +template <bool unsafe_shallow_swap> +void SwapFieldHelper::SwapNonInlinedStrings(const Reflection* r, Message* lhs, + Message* rhs, + const FieldDescriptor* field) { + 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()); + } +} + +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: { + if (r->IsInlined(field)) { + SwapFieldHelper::SwapInlinedStrings<unsafe_shallow_swap>(r, lhs, rhs, + field); + } else { + SwapFieldHelper::SwapNonInlinedStrings<unsafe_shallow_swap>(r, lhs, rhs, + field); + } + break; + } + } +} + +void SwapFieldHelper::SwapArenaStringPtr(const TProtoStringType* 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 { + TProtoStringType 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 && r->HasBit(*rhs, field)) { + *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 if (*rhs_sub == nullptr && r->HasBit(*lhs, field)) { + *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()) { + switch (field->cpp_type()) { +#define SWAP_ARRAYS(CPPTYPE, TYPE) \ + case FieldDescriptor::CPPTYPE_##CPPTYPE: \ + MutableRaw<RepeatedField<TYPE> >(message1, field) \ + ->Swap(MutableRaw<RepeatedField<TYPE> >(message2, field)); \ + break; + + SWAP_ARRAYS(INT32, arc_i32); + SWAP_ARRAYS(INT64, arc_i64); + SWAP_ARRAYS(UINT32, arc_ui32); + SWAP_ARRAYS(UINT64, arc_ui64); + SWAP_ARRAYS(FLOAT, float); + SWAP_ARRAYS(DOUBLE, double); + SWAP_ARRAYS(BOOL, bool); + SWAP_ARRAYS(ENUM, int); +#undef SWAP_ARRAYS + + case FieldDescriptor::CPPTYPE_STRING: + internal::SwapFieldHelper::SwapRepeatedStringField<false>( + this, message1, message2, field); + break; + case FieldDescriptor::CPPTYPE_MESSAGE: + internal::SwapFieldHelper::SwapRepeatedMessageField<false>( + this, message1, message2, field); + break; + + default: + GOOGLE_LOG(FATAL) << "Unimplemented type: " << field->cpp_type(); + } + } else { + switch (field->cpp_type()) { +#define SWAP_VALUES(CPPTYPE, TYPE) \ + case FieldDescriptor::CPPTYPE_##CPPTYPE: \ + std::swap(*MutableRaw<TYPE>(message1, field), \ + *MutableRaw<TYPE>(message2, field)); \ + break; + + SWAP_VALUES(INT32, arc_i32); + SWAP_VALUES(INT64, arc_i64); + SWAP_VALUES(UINT32, arc_ui32); + SWAP_VALUES(UINT64, arc_ui64); + SWAP_VALUES(FLOAT, float); + SWAP_VALUES(DOUBLE, double); + SWAP_VALUES(BOOL, bool); + SWAP_VALUES(ENUM, int); +#undef SWAP_VALUES + case FieldDescriptor::CPPTYPE_MESSAGE: + internal::SwapFieldHelper::SwapMessageField<false>(this, message1, + message2, field); + break; + + case FieldDescriptor::CPPTYPE_STRING: + internal::SwapFieldHelper::SwapStringField<false>(this, message1, + message2, field); + break; + + default: + GOOGLE_LOG(FATAL) << "Unimplemented type: " << field->cpp_type(); + } + } +} + +void Reflection::UnsafeShallowSwapField(Message* message1, Message* message2, + const FieldDescriptor* field) const { + 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, arc_i32); + SHALLOW_SWAP_ARRAYS(INT64, arc_i64); + SHALLOW_SWAP_ARRAYS(UINT32, arc_ui32); + SHALLOW_SWAP_ARRAYS(UINT64, arc_ui64); + 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(); + } +} + +// Swaps oneof field between lhs and rhs. If unsafe_shallow_swap is true, it +// directly swaps oneof values; otherwise, it may involve copy/delete. Note that +// two messages may have different oneof cases. So, it has to be done in three +// steps (i.e. lhs -> temp, rhs -> lhs, temp -> rhs). +template <bool unsafe_shallow_swap> +void Reflection::SwapOneofField(Message* lhs, Message* rhs, + const OneofDescriptor* oneof_descriptor) const { + // Wraps a local variable to temporarily store oneof value. + struct LocalVarWrapper { +#define LOCAL_VAR_ACCESSOR(type, var, name) \ + type Get##name() const { return oneof_val.type_##var; } \ + void Set##name(type v) { oneof_val.type_##var = v; } + + LOCAL_VAR_ACCESSOR(arc_i32, int32, Int32); + LOCAL_VAR_ACCESSOR(arc_i64, int64, Int64); + LOCAL_VAR_ACCESSOR(arc_ui32, uint32, Uint32); + LOCAL_VAR_ACCESSOR(arc_ui64, uint64, Uint64); + LOCAL_VAR_ACCESSOR(float, float, Float); + LOCAL_VAR_ACCESSOR(double, double, Double); + LOCAL_VAR_ACCESSOR(bool, bool, Bool); + LOCAL_VAR_ACCESSOR(int, enum, Enum); + LOCAL_VAR_ACCESSOR(Message*, message, Message); + LOCAL_VAR_ACCESSOR(ArenaStringPtr, arena_string_ptr, ArenaStringPtr); + const TProtoStringType& GetString() const { return string_val; } + void SetString(const TProtoStringType& v) { string_val = v; } + Message* UnsafeGetMessage() const { return GetMessage(); } + void UnsafeSetMessage(Message* v) { SetMessage(v); } + void ClearOneofCase() {} + + union { + arc_i32 type_int32; + arc_i64 type_int64; + arc_ui32 type_uint32; + arc_ui64 type_uint64; + float type_float; + double type_double; + bool type_bool; + int type_enum; + Message* type_message; + internal::ArenaStringPtr type_arena_string_ptr; + } oneof_val; + + // TProtoStringType cannot be in union. + TProtoStringType string_val; + }; + + // Wraps a message pointer to read and write a field. + struct MessageWrapper { +#define MESSAGE_FIELD_ACCESSOR(type, var, name) \ + type Get##name() const { \ + return reflection->GetField<type>(*message, field); \ + } \ + void Set##name(type v) { reflection->SetField<type>(message, field, v); } + + MESSAGE_FIELD_ACCESSOR(arc_i32, int32, Int32); + MESSAGE_FIELD_ACCESSOR(arc_i64, int64, Int64); + MESSAGE_FIELD_ACCESSOR(arc_ui32, uint32, Uint32); + MESSAGE_FIELD_ACCESSOR(arc_ui64, uint64, Uint64); + MESSAGE_FIELD_ACCESSOR(float, float, Float); + MESSAGE_FIELD_ACCESSOR(double, double, Double); + MESSAGE_FIELD_ACCESSOR(bool, bool, Bool); + MESSAGE_FIELD_ACCESSOR(int, enum, Enum); + MESSAGE_FIELD_ACCESSOR(ArenaStringPtr, arena_string_ptr, ArenaStringPtr); + TProtoStringType GetString() const { + return reflection->GetString(*message, field); + } + void SetString(const TProtoStringType& v) { + reflection->SetString(message, field, v); + } + Message* GetMessage() const { + return reflection->ReleaseMessage(message, field); + } + void SetMessage(Message* v) { + reflection->SetAllocatedMessage(message, v, field); + } + Message* UnsafeGetMessage() const { + return reflection->UnsafeArenaReleaseMessage(message, field); + } + void UnsafeSetMessage(Message* v) { + reflection->UnsafeArenaSetAllocatedMessage(message, v, field); + } + void ClearOneofCase() { + *reflection->MutableOneofCase(message, field->containing_oneof()) = 0; + } + + const Reflection* reflection; + Message* message; + const FieldDescriptor* field; + }; + + GOOGLE_DCHECK(!oneof_descriptor->is_synthetic()); + uint32 oneof_case_lhs = GetOneofCase(*lhs, oneof_descriptor); + uint32 oneof_case_rhs = GetOneofCase(*rhs, oneof_descriptor); + + LocalVarWrapper temp; + MessageWrapper lhs_wrapper, rhs_wrapper; + const FieldDescriptor* field_lhs = nullptr; + OneofFieldMover<unsafe_shallow_swap> mover; + // lhs --> temp + if (oneof_case_lhs > 0) { + field_lhs = descriptor_->FindFieldByNumber(oneof_case_lhs); + lhs_wrapper = {this, lhs, field_lhs}; + mover(field_lhs, &lhs_wrapper, &temp); + } + // rhs --> lhs + if (oneof_case_rhs > 0) { + const FieldDescriptor* f = descriptor_->FindFieldByNumber(oneof_case_rhs); + lhs_wrapper = {this, lhs, f}; + rhs_wrapper = {this, rhs, f}; + mover(f, &rhs_wrapper, &lhs_wrapper); + } else if (!unsafe_shallow_swap) { + ClearOneof(lhs, oneof_descriptor); + } + // temp --> rhs + if (oneof_case_lhs > 0) { + rhs_wrapper = {this, rhs, field_lhs}; + mover(field_lhs, &temp, &rhs_wrapper); + } else if (!unsafe_shallow_swap) { + ClearOneof(rhs, oneof_descriptor); + } + + if (unsafe_shallow_swap) { + *MutableOneofCase(lhs, oneof_descriptor) = oneof_case_rhs; + *MutableOneofCase(rhs, oneof_descriptor) = oneof_case_lhs; + } +} + +void Reflection::Swap(Message* message1, Message* message2) const { + if (message1 == message2) return; + + // TODO(kenton): Other Reflection methods should probably check this too. + GOOGLE_CHECK_EQ(message1->GetReflection(), this) + << "First argument to Swap() (of type \"" + << message1->GetDescriptor()->full_name() + << "\") is not compatible with this reflection object (which is for type " + "\"" + << descriptor_->full_name() + << "\"). Note that the exact same class is required; not just the same " + "descriptor."; + GOOGLE_CHECK_EQ(message2->GetReflection(), this) + << "Second argument to Swap() (of type \"" + << message2->GetDescriptor()->full_name() + << "\") is not compatible with this reflection object (which is for type " + "\"" + << descriptor_->full_name() + << "\"). Note that the exact same class is required; not just the same " + "descriptor."; + + // 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(); + if (arena == nullptr) { + arena = message2->GetOwningArena(); + std::swap(message1, message2); // Swapping names for pointers! + } + + 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; + } + + GOOGLE_DCHECK_EQ(message1->GetOwningArena(), message2->GetOwningArena()); + + UnsafeArenaSwap(message1, message2); +} + +template <bool unsafe_shallow_swap> +void Reflection::SwapFieldsImpl( + Message* message1, Message* message2, + const std::vector<const FieldDescriptor*>& fields) const { + if (message1 == message2) return; + + // TODO(kenton): Other Reflection methods should probably check this too. + GOOGLE_CHECK_EQ(message1->GetReflection(), this) + << "First argument to SwapFields() (of type \"" + << message1->GetDescriptor()->full_name() + << "\") is not compatible with this reflection object (which is for type " + "\"" + << descriptor_->full_name() + << "\"). Note that the exact same class is required; not just the same " + "descriptor."; + GOOGLE_CHECK_EQ(message2->GetReflection(), this) + << "Second argument to SwapFields() (of type \"" + << message2->GetDescriptor()->full_name() + << "\") is not compatible with this reflection object (which is for type " + "\"" + << descriptor_->full_name() + << "\"). Note that the exact same class is required; not just the same " + "descriptor."; + + std::set<int> swapped_oneof; + + GOOGLE_DCHECK(!unsafe_shallow_swap || message1->GetArenaForAllocation() == + message2->GetArenaForAllocation()); + + const Message* prototype = + message_factory_->GetPrototype(message1->GetDescriptor()); + for (const auto* field : fields) { + CheckInvalidAccess(schema_, field); + if (field->is_extension()) { + if (unsafe_shallow_swap) { + MutableExtensionSet(message1)->UnsafeShallowSwapExtension( + MutableExtensionSet(message2), field->number()); + } else { + MutableExtensionSet(message1)->SwapExtension( + prototype, MutableExtensionSet(message2), field->number()); + } + } else { + if (schema_.InRealOneof(field)) { + int oneof_index = field->containing_oneof()->index(); + // Only swap the oneof field once. + if (swapped_oneof.find(oneof_index) != swapped_oneof.end()) { + continue; + } + swapped_oneof.insert(oneof_index); + SwapOneofField<unsafe_shallow_swap>(message1, message2, + field->containing_oneof()); + } else { + // Swap 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. + if (!field->is_repeated()) { + SwapBit(message1, message2, field); + } + } + } + } +} + +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); +} + +void Reflection::UnsafeArenaSwapFields( + Message* lhs, Message* rhs, + const std::vector<const FieldDescriptor*>& fields) const { + GOOGLE_DCHECK_EQ(lhs->GetArenaForAllocation(), rhs->GetArenaForAllocation()); + UnsafeShallowSwapFields(lhs, rhs, fields); +} + +// ------------------------------------------------------------------- + +bool Reflection::HasField(const Message& message, + const FieldDescriptor* field) const { + USAGE_CHECK_MESSAGE_TYPE(HasField); + USAGE_CHECK_SINGULAR(HasField); + CheckInvalidAccess(schema_, field); + + if (field->is_extension()) { + return GetExtensionSet(message).Has(field->number()); + } else { + if (schema_.InRealOneof(field)) { + return HasOneofField(message, field); + } else { + return HasBit(message, field); + } + } +} + +void Reflection::UnsafeArenaSwap(Message* lhs, Message* rhs) const { + if (lhs == rhs) return; + + MutableInternalMetadata(lhs)->InternalSwap(MutableInternalMetadata(rhs)); + + for (int i = 0; i <= last_non_weak_field_index_; i++) { + const FieldDescriptor* field = descriptor_->field(i); + if (schema_.InRealOneof(field)) continue; + if (schema_.IsFieldStripped(field)) continue; + UnsafeShallowSwapField(lhs, rhs, field); + } + const int oneof_decl_count = descriptor_->oneof_decl_count(); + for (int i = 0; i < oneof_decl_count; i++) { + const OneofDescriptor* oneof = descriptor_->oneof_decl(i); + if (!oneof->is_synthetic()) { + SwapOneofField<true>(lhs, rhs, oneof); + } + } + + // Swapping bits need to happen after swapping fields, because the latter may + // depend on the has bit information. + if (schema_.HasHasbits()) { + uint32* lhs_has_bits = MutableHasBits(lhs); + uint32* rhs_has_bits = MutableHasBits(rhs); + + int fields_with_has_bits = 0; + for (int i = 0; i < descriptor_->field_count(); i++) { + const FieldDescriptor* field = descriptor_->field(i); + if (field->is_repeated() || schema_.InRealOneof(field)) { + continue; + } + fields_with_has_bits++; + } + + int has_bits_size = (fields_with_has_bits + 31) / 32; + + for (int i = 0; i < has_bits_size; i++) { + std::swap(lhs_has_bits[i], rhs_has_bits[i]); + } + } + + if (schema_.HasExtensionSet()) { + MutableExtensionSet(lhs)->InternalSwap(MutableExtensionSet(rhs)); + } +} + +int Reflection::FieldSize(const Message& message, + const FieldDescriptor* field) const { + USAGE_CHECK_MESSAGE_TYPE(FieldSize); + USAGE_CHECK_REPEATED(FieldSize); + CheckInvalidAccess(schema_, field); + + if (field->is_extension()) { + return GetExtensionSet(message).ExtensionSize(field->number()); + } else { + switch (field->cpp_type()) { +#define HANDLE_TYPE(UPPERCASE, LOWERCASE) \ + case FieldDescriptor::CPPTYPE_##UPPERCASE: \ + return GetRaw<RepeatedField<LOWERCASE> >(message, field).size() + + HANDLE_TYPE(INT32, arc_i32); + HANDLE_TYPE(INT64, arc_i64); + HANDLE_TYPE(UINT32, arc_ui32); + HANDLE_TYPE(UINT64, arc_ui64); + HANDLE_TYPE(DOUBLE, double); + HANDLE_TYPE(FLOAT, float); + HANDLE_TYPE(BOOL, bool); + HANDLE_TYPE(ENUM, int); +#undef HANDLE_TYPE + + case FieldDescriptor::CPPTYPE_STRING: + case FieldDescriptor::CPPTYPE_MESSAGE: + if (IsMapFieldInApi(field)) { + const internal::MapFieldBase& map = + GetRaw<MapFieldBase>(message, field); + if (map.IsRepeatedFieldValid()) { + return map.GetRepeatedField().size(); + } else { + // No need to materialize the repeated field if it is out of sync: + // its size will be the same as the map's size. + return map.size(); + } + } else { + return GetRaw<RepeatedPtrFieldBase>(message, field).size(); + } + } + + GOOGLE_LOG(FATAL) << "Can't get here."; + return 0; + } +} + +void Reflection::ClearField(Message* message, + const FieldDescriptor* field) const { + USAGE_CHECK_MESSAGE_TYPE(ClearField); + CheckInvalidAccess(schema_, field); + + if (field->is_extension()) { + MutableExtensionSet(message)->ClearExtension(field->number()); + } else if (!field->is_repeated()) { + if (schema_.InRealOneof(field)) { + ClearOneofField(message, field); + return; + } + if (HasBit(*message, field)) { + ClearBit(message, field); + + // We need to set the field back to its default value. + switch (field->cpp_type()) { +#define CLEAR_TYPE(CPPTYPE, TYPE) \ + case FieldDescriptor::CPPTYPE_##CPPTYPE: \ + *MutableRaw<TYPE>(message, field) = field->default_value_##TYPE(); \ + break; + + CLEAR_TYPE(INT32, arc_i32); + CLEAR_TYPE(INT64, arc_i64); + CLEAR_TYPE(UINT32, arc_ui32); + CLEAR_TYPE(UINT64, arc_ui64); + CLEAR_TYPE(FLOAT, float); + CLEAR_TYPE(DOUBLE, double); + CLEAR_TYPE(BOOL, bool); +#undef CLEAR_TYPE + + case FieldDescriptor::CPPTYPE_ENUM: + *MutableRaw<int>(message, field) = + field->default_value_enum()->number(); + break; + + case FieldDescriptor::CPPTYPE_STRING: { + switch (field->options().ctype()) { + default: // TODO(kenton): Support other string reps. + case FieldOptions::STRING: { + if (IsInlined(field)) { + // Currently, string with default value can't be inlined. So we + // don't have to handle default value here. + MutableRaw<InlinedStringField>(message, field)->ClearToEmpty(); + break; + } + const TProtoStringType* default_ptr = + DefaultRaw<ArenaStringPtr>(field).GetPointer(); + MutableRaw<ArenaStringPtr>(message, field) + ->SetAllocated(default_ptr, nullptr, + message->GetArenaForAllocation()); + break; + } + } + break; + } + + case FieldDescriptor::CPPTYPE_MESSAGE: + if (schema_.HasBitIndex(field) == static_cast<arc_ui32>(-1)) { + // Proto3 does not have has-bits and we need to set a message field + // to nullptr in order to indicate its un-presence. + if (message->GetArenaForAllocation() == nullptr) { + delete *MutableRaw<Message*>(message, field); + } + *MutableRaw<Message*>(message, field) = nullptr; + } else { + (*MutableRaw<Message*>(message, field))->Clear(); + } + break; + } + } + } else { + switch (field->cpp_type()) { +#define HANDLE_TYPE(UPPERCASE, LOWERCASE) \ + case FieldDescriptor::CPPTYPE_##UPPERCASE: \ + MutableRaw<RepeatedField<LOWERCASE> >(message, field)->Clear(); \ + break + + HANDLE_TYPE(INT32, arc_i32); + HANDLE_TYPE(INT64, arc_i64); + HANDLE_TYPE(UINT32, arc_ui32); + HANDLE_TYPE(UINT64, arc_ui64); + HANDLE_TYPE(DOUBLE, double); + HANDLE_TYPE(FLOAT, float); + HANDLE_TYPE(BOOL, bool); + HANDLE_TYPE(ENUM, int); +#undef HANDLE_TYPE + + case FieldDescriptor::CPPTYPE_STRING: { + switch (field->options().ctype()) { + default: // TODO(kenton): Support other string reps. + case FieldOptions::STRING: + MutableRaw<RepeatedPtrField<TProtoStringType> >(message, field)->Clear(); + break; + } + break; + } + + case FieldDescriptor::CPPTYPE_MESSAGE: { + if (IsMapFieldInApi(field)) { + MutableRaw<MapFieldBase>(message, field)->Clear(); + } else { + // We don't know which subclass of RepeatedPtrFieldBase the type is, + // so we use RepeatedPtrFieldBase directly. + MutableRaw<RepeatedPtrFieldBase>(message, field) + ->Clear<GenericTypeHandler<Message> >(); + } + break; + } + } + } +} + +void Reflection::RemoveLast(Message* message, + const FieldDescriptor* field) const { + USAGE_CHECK_MESSAGE_TYPE(RemoveLast); + USAGE_CHECK_REPEATED(RemoveLast); + CheckInvalidAccess(schema_, field); + + if (field->is_extension()) { + MutableExtensionSet(message)->RemoveLast(field->number()); + } else { + switch (field->cpp_type()) { +#define HANDLE_TYPE(UPPERCASE, LOWERCASE) \ + case FieldDescriptor::CPPTYPE_##UPPERCASE: \ + MutableRaw<RepeatedField<LOWERCASE> >(message, field)->RemoveLast(); \ + break + + HANDLE_TYPE(INT32, arc_i32); + HANDLE_TYPE(INT64, arc_i64); + HANDLE_TYPE(UINT32, arc_ui32); + HANDLE_TYPE(UINT64, arc_ui64); + HANDLE_TYPE(DOUBLE, double); + HANDLE_TYPE(FLOAT, float); + HANDLE_TYPE(BOOL, bool); + HANDLE_TYPE(ENUM, int); +#undef HANDLE_TYPE + + case FieldDescriptor::CPPTYPE_STRING: + switch (field->options().ctype()) { + default: // TODO(kenton): Support other string reps. + case FieldOptions::STRING: + MutableRaw<RepeatedPtrField<TProtoStringType> >(message, field) + ->RemoveLast(); + break; + } + break; + + case FieldDescriptor::CPPTYPE_MESSAGE: + if (IsMapFieldInApi(field)) { + MutableRaw<MapFieldBase>(message, field) + ->MutableRepeatedField() + ->RemoveLast<GenericTypeHandler<Message> >(); + } else { + MutableRaw<RepeatedPtrFieldBase>(message, field) + ->RemoveLast<GenericTypeHandler<Message> >(); + } + break; + } + } +} + +Message* Reflection::ReleaseLast(Message* message, + const FieldDescriptor* field) const { + USAGE_CHECK_ALL(ReleaseLast, REPEATED, MESSAGE); + CheckInvalidAccess(schema_, field); + + Message* released; + if (field->is_extension()) { + released = static_cast<Message*>( + MutableExtensionSet(message)->ReleaseLast(field->number())); + } else { + if (IsMapFieldInApi(field)) { + released = MutableRaw<MapFieldBase>(message, field) + ->MutableRepeatedField() + ->ReleaseLast<GenericTypeHandler<Message>>(); + } else { + released = MutableRaw<RepeatedPtrFieldBase>(message, field) + ->ReleaseLast<GenericTypeHandler<Message>>(); + } + } +#ifdef PROTOBUF_FORCE_COPY_IN_RELEASE + return MaybeForceCopy(message->GetArenaForAllocation(), released); +#else // PROTOBUF_FORCE_COPY_IN_RELEASE + return released; +#endif // !PROTOBUF_FORCE_COPY_IN_RELEASE +} + +Message* Reflection::UnsafeArenaReleaseLast( + Message* message, const FieldDescriptor* field) const { + USAGE_CHECK_ALL(UnsafeArenaReleaseLast, REPEATED, MESSAGE); + CheckInvalidAccess(schema_, field); + + if (field->is_extension()) { + return static_cast<Message*>( + MutableExtensionSet(message)->UnsafeArenaReleaseLast(field->number())); + } else { + if (IsMapFieldInApi(field)) { + return MutableRaw<MapFieldBase>(message, field) + ->MutableRepeatedField() + ->UnsafeArenaReleaseLast<GenericTypeHandler<Message>>(); + } else { + return MutableRaw<RepeatedPtrFieldBase>(message, field) + ->UnsafeArenaReleaseLast<GenericTypeHandler<Message>>(); + } + } +} + +void Reflection::SwapElements(Message* message, const FieldDescriptor* field, + int index1, int index2) const { + USAGE_CHECK_MESSAGE_TYPE(Swap); + USAGE_CHECK_REPEATED(Swap); + CheckInvalidAccess(schema_, field); + + if (field->is_extension()) { + MutableExtensionSet(message)->SwapElements(field->number(), index1, index2); + } else { + switch (field->cpp_type()) { +#define HANDLE_TYPE(UPPERCASE, LOWERCASE) \ + case FieldDescriptor::CPPTYPE_##UPPERCASE: \ + MutableRaw<RepeatedField<LOWERCASE> >(message, field) \ + ->SwapElements(index1, index2); \ + break + + HANDLE_TYPE(INT32, arc_i32); + HANDLE_TYPE(INT64, arc_i64); + HANDLE_TYPE(UINT32, arc_ui32); + HANDLE_TYPE(UINT64, arc_ui64); + HANDLE_TYPE(DOUBLE, double); + HANDLE_TYPE(FLOAT, float); + HANDLE_TYPE(BOOL, bool); + HANDLE_TYPE(ENUM, int); +#undef HANDLE_TYPE + + case FieldDescriptor::CPPTYPE_STRING: + case FieldDescriptor::CPPTYPE_MESSAGE: + if (IsMapFieldInApi(field)) { + MutableRaw<MapFieldBase>(message, field) + ->MutableRepeatedField() + ->SwapElements(index1, index2); + } else { + MutableRaw<RepeatedPtrFieldBase>(message, field) + ->SwapElements(index1, index2); + } + break; + } + } +} + +namespace { +// Comparison functor for sorting FieldDescriptors by field number. +struct FieldNumberSorter { + bool operator()(const FieldDescriptor* left, + const FieldDescriptor* right) const { + return left->number() < right->number(); + } +}; + +bool IsIndexInHasBitSet(const arc_ui32* has_bit_set, arc_ui32 has_bit_index) { + GOOGLE_DCHECK_NE(has_bit_index, ~0u); + return ((has_bit_set[has_bit_index / 32] >> (has_bit_index % 32)) & + static_cast<arc_ui32>(1)) != 0; +} + +bool CreateUnknownEnumValues(const FileDescriptor* file) { + return file->syntax() == FileDescriptor::SYNTAX_PROTO3; +} +} // namespace + +namespace internal { +bool CreateUnknownEnumValues(const FieldDescriptor* field) { + bool open_enum = false; + return field->file()->syntax() == FileDescriptor::SYNTAX_PROTO3 || open_enum; +} +} // namespace internal +using internal::CreateUnknownEnumValues; + +void Reflection::ListFieldsMayFailOnStripped( + const Message& message, bool should_fail, + std::vector<const FieldDescriptor*>* output) const { + output->clear(); + + // Optimization: The default instance never has any fields set. + if (schema_.IsDefaultInstance(message)) return; + + // Optimization: Avoid calling GetHasBits() and HasOneofField() many times + // within the field loop. We allow this violation of ReflectionSchema + // encapsulation because this function takes a noticeable about of CPU + // fleetwide and properly allowing this optimization through public interfaces + // seems more trouble than it is worth. + const arc_ui32* const has_bits = + schema_.HasHasbits() ? GetHasBits(message) : nullptr; + const arc_ui32* const has_bits_indices = schema_.has_bit_indices_; + output->reserve(descriptor_->field_count()); + const int last_non_weak_field_index = last_non_weak_field_index_; + for (int i = 0; i <= last_non_weak_field_index; i++) { + const FieldDescriptor* field = descriptor_->field(i); + if (!should_fail && schema_.IsFieldStripped(field)) { + continue; + } + if (field->is_repeated()) { + if (FieldSize(message, field) > 0) { + output->push_back(field); + } + } else { + const OneofDescriptor* containing_oneof = field->containing_oneof(); + if (schema_.InRealOneof(field)) { + const arc_ui32* const oneof_case_array = + GetConstPointerAtOffset<arc_ui32>(&message, + schema_.oneof_case_offset_); + // Equivalent to: HasOneofField(message, field) + if (static_cast<arc_i64>(oneof_case_array[containing_oneof->index()]) == + field->number()) { + output->push_back(field); + } + } else if (has_bits && has_bits_indices[i] != static_cast<arc_ui32>(-1)) { + CheckInvalidAccess(schema_, field); + // Equivalent to: HasBit(message, field) + if (IsIndexInHasBitSet(has_bits, has_bits_indices[i])) { + output->push_back(field); + } + } else if (HasBit(message, field)) { // Fall back on proto3-style HasBit. + output->push_back(field); + } + } + } + if (schema_.HasExtensionSet()) { + GetExtensionSet(message).AppendToList(descriptor_, descriptor_pool_, + output); + } + + // ListFields() must sort output by field number. + std::sort(output->begin(), output->end(), FieldNumberSorter()); +} + +void Reflection::ListFields(const Message& message, + std::vector<const FieldDescriptor*>* output) const { + ListFieldsMayFailOnStripped(message, true, output); +} + +void Reflection::ListFieldsOmitStripped( + const Message& message, std::vector<const FieldDescriptor*>* output) const { + ListFieldsMayFailOnStripped(message, false, output); +} + +// ------------------------------------------------------------------- + +#undef DEFINE_PRIMITIVE_ACCESSORS +#define DEFINE_PRIMITIVE_ACCESSORS(TYPENAME, TYPE, PASSTYPE, CPPTYPE) \ + PASSTYPE Reflection::Get##TYPENAME(const Message& message, \ + const FieldDescriptor* field) const { \ + USAGE_CHECK_ALL(Get##TYPENAME, SINGULAR, CPPTYPE); \ + if (field->is_extension()) { \ + return GetExtensionSet(message).Get##TYPENAME( \ + field->number(), field->default_value_##PASSTYPE()); \ + } else if (schema_.InRealOneof(field) && !HasOneofField(message, field)) { \ + return field->default_value_##PASSTYPE(); \ + } else { \ + return GetField<TYPE>(message, field); \ + } \ + } \ + \ + void Reflection::Set##TYPENAME( \ + Message* message, const FieldDescriptor* field, PASSTYPE value) const { \ + USAGE_CHECK_ALL(Set##TYPENAME, SINGULAR, CPPTYPE); \ + if (field->is_extension()) { \ + return MutableExtensionSet(message)->Set##TYPENAME( \ + field->number(), field->type(), value, field); \ + } else { \ + SetField<TYPE>(message, field, value); \ + } \ + } \ + \ + PASSTYPE Reflection::GetRepeated##TYPENAME( \ + const Message& message, const FieldDescriptor* field, int index) const { \ + USAGE_CHECK_ALL(GetRepeated##TYPENAME, REPEATED, CPPTYPE); \ + if (field->is_extension()) { \ + return GetExtensionSet(message).GetRepeated##TYPENAME(field->number(), \ + index); \ + } else { \ + return GetRepeatedField<TYPE>(message, field, index); \ + } \ + } \ + \ + void Reflection::SetRepeated##TYPENAME(Message* message, \ + const FieldDescriptor* field, \ + int index, PASSTYPE value) const { \ + USAGE_CHECK_ALL(SetRepeated##TYPENAME, REPEATED, CPPTYPE); \ + if (field->is_extension()) { \ + MutableExtensionSet(message)->SetRepeated##TYPENAME(field->number(), \ + index, value); \ + } else { \ + SetRepeatedField<TYPE>(message, field, index, value); \ + } \ + } \ + \ + void Reflection::Add##TYPENAME( \ + Message* message, const FieldDescriptor* field, PASSTYPE value) const { \ + USAGE_CHECK_ALL(Add##TYPENAME, REPEATED, CPPTYPE); \ + if (field->is_extension()) { \ + MutableExtensionSet(message)->Add##TYPENAME( \ + field->number(), field->type(), field->options().packed(), value, \ + field); \ + } else { \ + AddField<TYPE>(message, field, value); \ + } \ + } + +DEFINE_PRIMITIVE_ACCESSORS(Int32, arc_i32, arc_i32, INT32) +DEFINE_PRIMITIVE_ACCESSORS(Int64, arc_i64, arc_i64, INT64) +DEFINE_PRIMITIVE_ACCESSORS(UInt32, arc_ui32, arc_ui32, UINT32) +DEFINE_PRIMITIVE_ACCESSORS(UInt64, arc_ui64, arc_ui64, UINT64) +DEFINE_PRIMITIVE_ACCESSORS(Float, float, float, FLOAT) +DEFINE_PRIMITIVE_ACCESSORS(Double, double, double, DOUBLE) +DEFINE_PRIMITIVE_ACCESSORS(Bool, bool, bool, BOOL) +#undef DEFINE_PRIMITIVE_ACCESSORS + +// ------------------------------------------------------------------- + +TProtoStringType Reflection::GetString(const Message& message, + const FieldDescriptor* field) const { + USAGE_CHECK_ALL(GetString, SINGULAR, STRING); + if (field->is_extension()) { + return GetExtensionSet(message).GetString(field->number(), + field->default_value_string()); + } else { + if (schema_.InRealOneof(field) && !HasOneofField(message, field)) { + return field->default_value_string(); + } + switch (field->options().ctype()) { + default: // TODO(kenton): Support other string reps. + case FieldOptions::STRING: { + if (IsInlined(field)) { + return GetField<InlinedStringField>(message, field).GetNoArena(); + } + + if (auto* value = + GetField<ArenaStringPtr>(message, field).GetPointer()) { + return *value; + } + return field->default_value_string(); + } + } + } +} + +const TProtoStringType& Reflection::GetStringReference(const Message& message, + const FieldDescriptor* field, + TProtoStringType* scratch) const { + (void)scratch; // Parameter is used by Google-internal code. + USAGE_CHECK_ALL(GetStringReference, SINGULAR, STRING); + if (field->is_extension()) { + return GetExtensionSet(message).GetString(field->number(), + field->default_value_string()); + } else { + if (schema_.InRealOneof(field) && !HasOneofField(message, field)) { + return field->default_value_string(); + } + switch (field->options().ctype()) { + default: // TODO(kenton): Support other string reps. + case FieldOptions::STRING: { + if (IsInlined(field)) { + return GetField<InlinedStringField>(message, field).GetNoArena(); + } + + if (auto* value = + GetField<ArenaStringPtr>(message, field).GetPointer()) { + return *value; + } + return field->default_value_string(); + } + } + } +} + + +void Reflection::SetString(Message* message, const FieldDescriptor* field, + TProtoStringType value) const { + USAGE_CHECK_ALL(SetString, SINGULAR, STRING); + if (field->is_extension()) { + return MutableExtensionSet(message)->SetString( + field->number(), field->type(), std::move(value), field); + } else { + switch (field->options().ctype()) { + default: // TODO(kenton): Support other string reps. + case FieldOptions::STRING: { + if (IsInlined(field)) { + const arc_ui32 index = schema_.InlinedStringIndex(field); + arc_ui32* states = + &MutableInlinedStringDonatedArray(message)[index / 32]; + arc_ui32 mask = ~(static_cast<arc_ui32>(1) << (index % 32)); + MutableField<InlinedStringField>(message, field) + ->Set(nullptr, value, message->GetArenaForAllocation(), + IsInlinedStringDonated(*message, field), states, mask); + break; + } + + // Oneof string fields are never set as a default instance. + // We just need to pass some arbitrary default string to make it work. + // This allows us to not have the real default accessible from + // reflection. + const TProtoStringType* default_ptr = + schema_.InRealOneof(field) + ? nullptr + : DefaultRaw<ArenaStringPtr>(field).GetPointer(); + if (schema_.InRealOneof(field) && !HasOneofField(*message, field)) { + ClearOneof(message, field->containing_oneof()); + MutableField<ArenaStringPtr>(message, field) + ->UnsafeSetDefault(default_ptr); + } + MutableField<ArenaStringPtr>(message, field) + ->Set(default_ptr, std::move(value), + message->GetArenaForAllocation()); + break; + } + } + } +} + + +TProtoStringType Reflection::GetRepeatedString(const Message& message, + const FieldDescriptor* field, + int index) const { + USAGE_CHECK_ALL(GetRepeatedString, REPEATED, STRING); + if (field->is_extension()) { + return GetExtensionSet(message).GetRepeatedString(field->number(), index); + } else { + switch (field->options().ctype()) { + default: // TODO(kenton): Support other string reps. + case FieldOptions::STRING: + return GetRepeatedPtrField<TProtoStringType>(message, field, index); + } + } +} + +const TProtoStringType& Reflection::GetRepeatedStringReference( + const Message& message, const FieldDescriptor* field, int index, + TProtoStringType* scratch) const { + (void)scratch; // Parameter is used by Google-internal code. + USAGE_CHECK_ALL(GetRepeatedStringReference, REPEATED, STRING); + if (field->is_extension()) { + return GetExtensionSet(message).GetRepeatedString(field->number(), index); + } else { + switch (field->options().ctype()) { + default: // TODO(kenton): Support other string reps. + case FieldOptions::STRING: + return GetRepeatedPtrField<TProtoStringType>(message, field, index); + } + } +} + + +void Reflection::SetRepeatedString(Message* message, + const FieldDescriptor* field, int index, + TProtoStringType value) const { + USAGE_CHECK_ALL(SetRepeatedString, REPEATED, STRING); + if (field->is_extension()) { + MutableExtensionSet(message)->SetRepeatedString(field->number(), index, + std::move(value)); + } else { + switch (field->options().ctype()) { + default: // TODO(kenton): Support other string reps. + case FieldOptions::STRING: + MutableRepeatedField<TProtoStringType>(message, field, index) + ->assign(std::move(value)); + break; + } + } +} + + +void Reflection::AddString(Message* message, const FieldDescriptor* field, + TProtoStringType value) const { + USAGE_CHECK_ALL(AddString, REPEATED, STRING); + if (field->is_extension()) { + MutableExtensionSet(message)->AddString(field->number(), field->type(), + std::move(value), field); + } else { + switch (field->options().ctype()) { + default: // TODO(kenton): Support other string reps. + case FieldOptions::STRING: + AddField<TProtoStringType>(message, field)->assign(std::move(value)); + break; + } + } +} + + +// ------------------------------------------------------------------- + +const EnumValueDescriptor* Reflection::GetEnum( + const Message& message, const FieldDescriptor* field) const { + // Usage checked by GetEnumValue. + int value = GetEnumValue(message, field); + return field->enum_type()->FindValueByNumberCreatingIfUnknown(value); +} + +int Reflection::GetEnumValue(const Message& message, + const FieldDescriptor* field) const { + USAGE_CHECK_ALL(GetEnumValue, SINGULAR, ENUM); + + arc_i32 value; + if (field->is_extension()) { + value = GetExtensionSet(message).GetEnum( + field->number(), field->default_value_enum()->number()); + } else if (schema_.InRealOneof(field) && !HasOneofField(message, field)) { + value = field->default_value_enum()->number(); + } else { + value = GetField<int>(message, field); + } + return value; +} + +void Reflection::SetEnum(Message* message, const FieldDescriptor* field, + const EnumValueDescriptor* value) const { + // Usage checked by SetEnumValue. + USAGE_CHECK_ENUM_VALUE(SetEnum); + SetEnumValueInternal(message, field, value->number()); +} + +void Reflection::SetEnumValue(Message* message, const FieldDescriptor* field, + int value) const { + USAGE_CHECK_ALL(SetEnumValue, SINGULAR, ENUM); + if (!CreateUnknownEnumValues(field)) { + // Check that the value is valid if we don't support direct storage of + // unknown enum values. + const EnumValueDescriptor* value_desc = + field->enum_type()->FindValueByNumber(value); + if (value_desc == nullptr) { + MutableUnknownFields(message)->AddVarint(field->number(), value); + return; + } + } + SetEnumValueInternal(message, field, value); +} + +void Reflection::SetEnumValueInternal(Message* message, + const FieldDescriptor* field, + int value) const { + if (field->is_extension()) { + MutableExtensionSet(message)->SetEnum(field->number(), field->type(), value, + field); + } else { + SetField<int>(message, field, value); + } +} + +const EnumValueDescriptor* Reflection::GetRepeatedEnum( + const Message& message, const FieldDescriptor* field, int index) const { + // Usage checked by GetRepeatedEnumValue. + int value = GetRepeatedEnumValue(message, field, index); + return field->enum_type()->FindValueByNumberCreatingIfUnknown(value); +} + +int Reflection::GetRepeatedEnumValue(const Message& message, + const FieldDescriptor* field, + int index) const { + USAGE_CHECK_ALL(GetRepeatedEnumValue, REPEATED, ENUM); + + int value; + if (field->is_extension()) { + value = GetExtensionSet(message).GetRepeatedEnum(field->number(), index); + } else { + value = GetRepeatedField<int>(message, field, index); + } + return value; +} + +void Reflection::SetRepeatedEnum(Message* message, const FieldDescriptor* field, + int index, + const EnumValueDescriptor* value) const { + // Usage checked by SetRepeatedEnumValue. + USAGE_CHECK_ENUM_VALUE(SetRepeatedEnum); + SetRepeatedEnumValueInternal(message, field, index, value->number()); +} + +void Reflection::SetRepeatedEnumValue(Message* message, + const FieldDescriptor* field, int index, + int value) const { + USAGE_CHECK_ALL(SetRepeatedEnum, REPEATED, ENUM); + if (!CreateUnknownEnumValues(field)) { + // Check that the value is valid if we don't support direct storage of + // unknown enum values. + const EnumValueDescriptor* value_desc = + field->enum_type()->FindValueByNumber(value); + if (value_desc == nullptr) { + MutableUnknownFields(message)->AddVarint(field->number(), value); + return; + } + } + SetRepeatedEnumValueInternal(message, field, index, value); +} + +void Reflection::SetRepeatedEnumValueInternal(Message* message, + const FieldDescriptor* field, + int index, int value) const { + if (field->is_extension()) { + MutableExtensionSet(message)->SetRepeatedEnum(field->number(), index, + value); + } else { + SetRepeatedField<int>(message, field, index, value); + } +} + +void Reflection::AddEnum(Message* message, const FieldDescriptor* field, + const EnumValueDescriptor* value) const { + // Usage checked by AddEnumValue. + USAGE_CHECK_ENUM_VALUE(AddEnum); + AddEnumValueInternal(message, field, value->number()); +} + +void Reflection::AddEnumValue(Message* message, const FieldDescriptor* field, + int value) const { + USAGE_CHECK_ALL(AddEnum, REPEATED, ENUM); + if (!CreateUnknownEnumValues(field)) { + // Check that the value is valid if we don't support direct storage of + // unknown enum values. + const EnumValueDescriptor* value_desc = + field->enum_type()->FindValueByNumber(value); + if (value_desc == nullptr) { + MutableUnknownFields(message)->AddVarint(field->number(), value); + return; + } + } + AddEnumValueInternal(message, field, value); +} + +void Reflection::AddEnumValueInternal(Message* message, + const FieldDescriptor* field, + int value) const { + if (field->is_extension()) { + MutableExtensionSet(message)->AddEnum(field->number(), field->type(), + field->options().packed(), value, + field); + } else { + AddField<int>(message, field, value); + } +} + +// ------------------------------------------------------------------- + +const Message* Reflection::GetDefaultMessageInstance( + const FieldDescriptor* field) const { + // If we are using the generated factory, we cache the prototype in the field + // descriptor for faster access. + // The default instances of generated messages are not cross-linked, which + // means they contain null pointers on their message fields and can't be used + // to get the default of submessages. + if (message_factory_ == MessageFactory::generated_factory()) { + auto& ptr = field->default_generated_instance_; + auto* res = ptr.load(std::memory_order_acquire); + if (res == nullptr) { + // First time asking for this field's default. Load it and cache it. + res = message_factory_->GetPrototype(field->message_type()); + ptr.store(res, std::memory_order_release); + } + return res; + } + + // For other factories, we try the default's object field. + // In particular, the DynamicMessageFactory will cross link the default + // instances to allow for this. But only do this for real fields. + // This is an optimization to avoid going to GetPrototype() below, as that + // requires a lock and a map lookup. + if (!field->is_extension() && !field->options().weak() && + !IsLazyField(field) && !schema_.InRealOneof(field)) { + auto* res = DefaultRaw<const Message*>(field); + if (res != nullptr) { + return res; + } + } + // Otherwise, just go to the factory. + return message_factory_->GetPrototype(field->message_type()); +} + +const Message& Reflection::GetMessage(const Message& message, + const FieldDescriptor* field, + MessageFactory* factory) const { + USAGE_CHECK_ALL(GetMessage, SINGULAR, MESSAGE); + CheckInvalidAccess(schema_, field); + + if (factory == nullptr) factory = message_factory_; + + if (field->is_extension()) { + return static_cast<const Message&>(GetExtensionSet(message).GetMessage( + field->number(), field->message_type(), factory)); + } else { + if (schema_.InRealOneof(field) && !HasOneofField(message, field)) { + return *GetDefaultMessageInstance(field); + } + const Message* result = GetRaw<const Message*>(message, field); + if (result == nullptr) { + result = GetDefaultMessageInstance(field); + } + return *result; + } +} + +Message* Reflection::MutableMessage(Message* message, + const FieldDescriptor* field, + MessageFactory* factory) const { + USAGE_CHECK_ALL(MutableMessage, SINGULAR, MESSAGE); + CheckInvalidAccess(schema_, field); + + if (factory == nullptr) factory = message_factory_; + + if (field->is_extension()) { + return static_cast<Message*>( + MutableExtensionSet(message)->MutableMessage(field, factory)); + } else { + Message* result; + + Message** result_holder = MutableRaw<Message*>(message, field); + + if (schema_.InRealOneof(field)) { + if (!HasOneofField(*message, field)) { + ClearOneof(message, field->containing_oneof()); + result_holder = MutableField<Message*>(message, field); + const Message* default_message = GetDefaultMessageInstance(field); + *result_holder = default_message->New(message->GetArenaForAllocation()); + } + } else { + SetBit(message, field); + } + + if (*result_holder == nullptr) { + const Message* default_message = GetDefaultMessageInstance(field); + *result_holder = default_message->New(message->GetArenaForAllocation()); + } + result = *result_holder; + return result; + } +} + +void Reflection::UnsafeArenaSetAllocatedMessage( + Message* message, Message* sub_message, + const FieldDescriptor* field) const { + USAGE_CHECK_ALL(SetAllocatedMessage, SINGULAR, MESSAGE); + CheckInvalidAccess(schema_, field); + + + if (field->is_extension()) { + MutableExtensionSet(message)->UnsafeArenaSetAllocatedMessage( + field->number(), field->type(), field, sub_message); + } else { + if (schema_.InRealOneof(field)) { + if (sub_message == nullptr) { + ClearOneof(message, field->containing_oneof()); + return; + } + ClearOneof(message, field->containing_oneof()); + *MutableRaw<Message*>(message, field) = sub_message; + SetOneofCase(message, field); + return; + } + + if (sub_message == nullptr) { + ClearBit(message, field); + } else { + SetBit(message, field); + } + Message** sub_message_holder = MutableRaw<Message*>(message, field); + if (message->GetArenaForAllocation() == nullptr) { + delete *sub_message_holder; + } + *sub_message_holder = sub_message; + } +} + +void Reflection::SetAllocatedMessage(Message* message, Message* sub_message, + const FieldDescriptor* field) const { + GOOGLE_DCHECK(sub_message == nullptr || sub_message->GetOwningArena() == nullptr || + sub_message->GetOwningArena() == message->GetArenaForAllocation()); + CheckInvalidAccess(schema_, field); + + // If message and sub-message are in different memory ownership domains + // (different arenas, or one is on heap and one is not), then we may need to + // do a copy. + if (sub_message != nullptr && + sub_message->GetOwningArena() != message->GetArenaForAllocation()) { + if (sub_message->GetOwningArena() == nullptr && + message->GetArenaForAllocation() != nullptr) { + // Case 1: parent is on an arena and child is heap-allocated. We can add + // the child to the arena's Own() list to free on arena destruction, then + // set our pointer. + message->GetArenaForAllocation()->Own(sub_message); + UnsafeArenaSetAllocatedMessage(message, sub_message, field); + } else { + // Case 2: all other cases. We need to make a copy. MutableMessage() will + // either get the existing message object, or instantiate a new one as + // appropriate w.r.t. our arena. + Message* sub_message_copy = MutableMessage(message, field); + sub_message_copy->CopyFrom(*sub_message); + } + } else { + // Same memory ownership domains. + UnsafeArenaSetAllocatedMessage(message, sub_message, field); + } +} + +Message* Reflection::UnsafeArenaReleaseMessage(Message* message, + const FieldDescriptor* field, + MessageFactory* factory) const { + USAGE_CHECK_ALL(ReleaseMessage, SINGULAR, MESSAGE); + CheckInvalidAccess(schema_, field); + + if (factory == nullptr) factory = message_factory_; + + if (field->is_extension()) { + return static_cast<Message*>( + MutableExtensionSet(message)->UnsafeArenaReleaseMessage(field, + factory)); + } else { + if (!(field->is_repeated() || schema_.InRealOneof(field))) { + ClearBit(message, field); + } + if (schema_.InRealOneof(field)) { + if (HasOneofField(*message, field)) { + *MutableOneofCase(message, field->containing_oneof()) = 0; + } else { + return nullptr; + } + } + Message** result = MutableRaw<Message*>(message, field); + Message* ret = *result; + *result = nullptr; + return ret; + } +} + +Message* Reflection::ReleaseMessage(Message* message, + const FieldDescriptor* field, + MessageFactory* factory) const { + CheckInvalidAccess(schema_, field); + + Message* released = UnsafeArenaReleaseMessage(message, field, factory); +#ifdef PROTOBUF_FORCE_COPY_IN_RELEASE + released = MaybeForceCopy(message->GetArenaForAllocation(), released); +#endif // PROTOBUF_FORCE_COPY_IN_RELEASE + if (message->GetArenaForAllocation() != nullptr && released != nullptr) { + Message* copy_from_arena = released->New(); + copy_from_arena->CopyFrom(*released); + released = copy_from_arena; + } + return released; +} + +const Message& Reflection::GetRepeatedMessage(const Message& message, + const FieldDescriptor* field, + int index) const { + USAGE_CHECK_ALL(GetRepeatedMessage, REPEATED, MESSAGE); + CheckInvalidAccess(schema_, field); + + if (field->is_extension()) { + return static_cast<const Message&>( + GetExtensionSet(message).GetRepeatedMessage(field->number(), index)); + } else { + if (IsMapFieldInApi(field)) { + return GetRaw<MapFieldBase>(message, field) + .GetRepeatedField() + .Get<GenericTypeHandler<Message> >(index); + } else { + return GetRaw<RepeatedPtrFieldBase>(message, field) + .Get<GenericTypeHandler<Message> >(index); + } + } +} + +Message* Reflection::MutableRepeatedMessage(Message* message, + const FieldDescriptor* field, + int index) const { + USAGE_CHECK_ALL(MutableRepeatedMessage, REPEATED, MESSAGE); + CheckInvalidAccess(schema_, field); + + if (field->is_extension()) { + return static_cast<Message*>( + MutableExtensionSet(message)->MutableRepeatedMessage(field->number(), + index)); + } else { + if (IsMapFieldInApi(field)) { + return MutableRaw<MapFieldBase>(message, field) + ->MutableRepeatedField() + ->Mutable<GenericTypeHandler<Message> >(index); + } else { + return MutableRaw<RepeatedPtrFieldBase>(message, field) + ->Mutable<GenericTypeHandler<Message> >(index); + } + } +} + +Message* Reflection::AddMessage(Message* message, const FieldDescriptor* field, + MessageFactory* factory) const { + USAGE_CHECK_ALL(AddMessage, REPEATED, MESSAGE); + CheckInvalidAccess(schema_, field); + + if (factory == nullptr) factory = message_factory_; + + if (field->is_extension()) { + return static_cast<Message*>( + MutableExtensionSet(message)->AddMessage(field, factory)); + } else { + Message* result = nullptr; + + // We can't use AddField<Message>() because RepeatedPtrFieldBase doesn't + // know how to allocate one. + RepeatedPtrFieldBase* repeated = nullptr; + if (IsMapFieldInApi(field)) { + repeated = + MutableRaw<MapFieldBase>(message, field)->MutableRepeatedField(); + } else { + repeated = MutableRaw<RepeatedPtrFieldBase>(message, field); + } + result = repeated->AddFromCleared<GenericTypeHandler<Message> >(); + if (result == nullptr) { + // We must allocate a new object. + const Message* prototype; + if (repeated->size() == 0) { + prototype = factory->GetPrototype(field->message_type()); + } else { + prototype = &repeated->Get<GenericTypeHandler<Message> >(0); + } + result = prototype->New(message->GetArenaForAllocation()); + // We can guarantee here that repeated and result are either both heap + // allocated or arena owned. So it is safe to call the unsafe version + // of AddAllocated. + repeated->UnsafeArenaAddAllocated<GenericTypeHandler<Message> >(result); + } + + return result; + } +} + +void Reflection::AddAllocatedMessage(Message* message, + const FieldDescriptor* field, + Message* new_entry) const { + USAGE_CHECK_ALL(AddAllocatedMessage, REPEATED, MESSAGE); + CheckInvalidAccess(schema_, field); + + if (field->is_extension()) { + MutableExtensionSet(message)->AddAllocatedMessage(field, new_entry); + } else { + RepeatedPtrFieldBase* repeated = nullptr; + if (IsMapFieldInApi(field)) { + repeated = + MutableRaw<MapFieldBase>(message, field)->MutableRepeatedField(); + } else { + repeated = MutableRaw<RepeatedPtrFieldBase>(message, field); + } + repeated->AddAllocated<GenericTypeHandler<Message> >(new_entry); + } +} + +void Reflection::UnsafeArenaAddAllocatedMessage(Message* message, + const FieldDescriptor* field, + Message* new_entry) const { + USAGE_CHECK_ALL(UnsafeArenaAddAllocatedMessage, REPEATED, MESSAGE); + CheckInvalidAccess(schema_, field); + + if (field->is_extension()) { + MutableExtensionSet(message)->UnsafeArenaAddAllocatedMessage(field, + new_entry); + } else { + RepeatedPtrFieldBase* repeated = nullptr; + if (IsMapFieldInApi(field)) { + repeated = + MutableRaw<MapFieldBase>(message, field)->MutableRepeatedField(); + } else { + repeated = MutableRaw<RepeatedPtrFieldBase>(message, field); + } + repeated->UnsafeArenaAddAllocated<GenericTypeHandler<Message>>(new_entry); + } +} + +void* Reflection::MutableRawRepeatedField(Message* message, + const FieldDescriptor* field, + FieldDescriptor::CppType cpptype, + int ctype, + const Descriptor* desc) const { + (void)ctype; // Parameter is used by Google-internal code. + USAGE_CHECK_REPEATED("MutableRawRepeatedField"); + CheckInvalidAccess(schema_, field); + + if (field->cpp_type() != cpptype && + (field->cpp_type() != FieldDescriptor::CPPTYPE_ENUM || + cpptype != FieldDescriptor::CPPTYPE_INT32)) + ReportReflectionUsageTypeError(descriptor_, field, + "MutableRawRepeatedField", cpptype); + if (desc != nullptr) + GOOGLE_CHECK_EQ(field->message_type(), desc) << "wrong submessage type"; + if (field->is_extension()) { + return MutableExtensionSet(message)->MutableRawRepeatedField( + field->number(), field->type(), field->is_packed(), field); + } else { + // Trigger transform for MapField + if (IsMapFieldInApi(field)) { + return MutableRawNonOneof<MapFieldBase>(message, field) + ->MutableRepeatedField(); + } + return MutableRawNonOneof<void>(message, field); + } +} + +const void* Reflection::GetRawRepeatedField(const Message& message, + const FieldDescriptor* field, + FieldDescriptor::CppType cpptype, + int ctype, + const Descriptor* desc) const { + USAGE_CHECK_REPEATED("GetRawRepeatedField"); + if (field->cpp_type() != cpptype) + ReportReflectionUsageTypeError(descriptor_, field, "GetRawRepeatedField", + cpptype); + if (ctype >= 0) + GOOGLE_CHECK_EQ(field->options().ctype(), ctype) << "subtype mismatch"; + if (desc != nullptr) + GOOGLE_CHECK_EQ(field->message_type(), desc) << "wrong submessage type"; + if (field->is_extension()) { + // Should use extension_set::GetRawRepeatedField. However, the required + // parameter "default repeated value" is not very easy to get here. + // Map is not supported in extensions, it is acceptable to use + // extension_set::MutableRawRepeatedField which does not change the message. + return MutableExtensionSet(const_cast<Message*>(&message)) + ->MutableRawRepeatedField(field->number(), field->type(), + field->is_packed(), field); + } else { + // Trigger transform for MapField + if (IsMapFieldInApi(field)) { + return &(GetRawNonOneof<MapFieldBase>(message, field).GetRepeatedField()); + } + return &GetRawNonOneof<char>(message, field); + } +} + +const FieldDescriptor* Reflection::GetOneofFieldDescriptor( + const Message& message, const OneofDescriptor* oneof_descriptor) const { + if (oneof_descriptor->is_synthetic()) { + const FieldDescriptor* field = oneof_descriptor->field(0); + return HasField(message, field) ? field : nullptr; + } + arc_ui32 field_number = GetOneofCase(message, oneof_descriptor); + if (field_number == 0) { + return nullptr; + } + return descriptor_->FindFieldByNumber(field_number); +} + +bool Reflection::ContainsMapKey(const Message& message, + const FieldDescriptor* field, + const MapKey& key) const { + USAGE_CHECK(IsMapFieldInApi(field), "LookupMapValue", + "Field is not a map field."); + return GetRaw<MapFieldBase>(message, field).ContainsMapKey(key); +} + +bool Reflection::InsertOrLookupMapValue(Message* message, + const FieldDescriptor* field, + const MapKey& key, + MapValueRef* val) const { + USAGE_CHECK(IsMapFieldInApi(field), "InsertOrLookupMapValue", + "Field is not a map field."); + val->SetType(field->message_type()->FindFieldByName("value")->cpp_type()); + return MutableRaw<MapFieldBase>(message, field) + ->InsertOrLookupMapValue(key, val); +} + +bool Reflection::LookupMapValue(const Message& message, + const FieldDescriptor* field, const MapKey& key, + MapValueConstRef* val) const { + USAGE_CHECK(IsMapFieldInApi(field), "LookupMapValue", + "Field is not a map field."); + val->SetType(field->message_type()->FindFieldByName("value")->cpp_type()); + return GetRaw<MapFieldBase>(message, field).LookupMapValue(key, val); +} + +bool Reflection::DeleteMapValue(Message* message, const FieldDescriptor* field, + const MapKey& key) const { + USAGE_CHECK(IsMapFieldInApi(field), "DeleteMapValue", + "Field is not a map field."); + return MutableRaw<MapFieldBase>(message, field)->DeleteMapValue(key); +} + +MapIterator Reflection::MapBegin(Message* message, + const FieldDescriptor* field) const { + USAGE_CHECK(IsMapFieldInApi(field), "MapBegin", "Field is not a map field."); + MapIterator iter(message, field); + GetRaw<MapFieldBase>(*message, field).MapBegin(&iter); + return iter; +} + +MapIterator Reflection::MapEnd(Message* message, + const FieldDescriptor* field) const { + USAGE_CHECK(IsMapFieldInApi(field), "MapEnd", "Field is not a map field."); + MapIterator iter(message, field); + GetRaw<MapFieldBase>(*message, field).MapEnd(&iter); + return iter; +} + +int Reflection::MapSize(const Message& message, + const FieldDescriptor* field) const { + USAGE_CHECK(IsMapFieldInApi(field), "MapSize", "Field is not a map field."); + return GetRaw<MapFieldBase>(message, field).size(); +} + +// ----------------------------------------------------------------------------- + +const FieldDescriptor* Reflection::FindKnownExtensionByName( + const TProtoStringType& name) const { + if (!schema_.HasExtensionSet()) return nullptr; + return descriptor_pool_->FindExtensionByPrintableName(descriptor_, name); +} + +const FieldDescriptor* Reflection::FindKnownExtensionByNumber( + int number) const { + if (!schema_.HasExtensionSet()) return nullptr; + return descriptor_pool_->FindExtensionByNumber(descriptor_, number); +} + +bool Reflection::SupportsUnknownEnumValues() const { + return CreateUnknownEnumValues(descriptor_->file()); +} + +// =================================================================== +// Some private helpers. + +// These simple template accessors obtain pointers (or references) to +// the given field. + +template <class Type> +const Type& Reflection::GetRawNonOneof(const Message& message, + const FieldDescriptor* field) const { + return GetConstRefAtOffset<Type>(message, + schema_.GetFieldOffsetNonOneof(field)); +} + +template <class Type> +Type* Reflection::MutableRawNonOneof(Message* message, + const FieldDescriptor* field) const { + return GetPointerAtOffset<Type>(message, + schema_.GetFieldOffsetNonOneof(field)); +} + +template <typename Type> +Type* Reflection::MutableRaw(Message* message, + const FieldDescriptor* field) const { + return GetPointerAtOffset<Type>(message, schema_.GetFieldOffset(field)); +} + +const arc_ui32* Reflection::GetHasBits(const Message& message) const { + GOOGLE_DCHECK(schema_.HasHasbits()); + return &GetConstRefAtOffset<arc_ui32>(message, schema_.HasBitsOffset()); +} + +arc_ui32* Reflection::MutableHasBits(Message* message) const { + GOOGLE_DCHECK(schema_.HasHasbits()); + return GetPointerAtOffset<arc_ui32>(message, schema_.HasBitsOffset()); +} + +arc_ui32* Reflection::MutableOneofCase( + Message* message, const OneofDescriptor* oneof_descriptor) const { + GOOGLE_DCHECK(!oneof_descriptor->is_synthetic()); + return GetPointerAtOffset<arc_ui32>( + message, schema_.GetOneofCaseOffset(oneof_descriptor)); +} + +const ExtensionSet& Reflection::GetExtensionSet(const Message& message) const { + return GetConstRefAtOffset<ExtensionSet>(message, + schema_.GetExtensionSetOffset()); +} + +ExtensionSet* Reflection::MutableExtensionSet(Message* message) const { + return GetPointerAtOffset<ExtensionSet>(message, + schema_.GetExtensionSetOffset()); +} + +const InternalMetadata& Reflection::GetInternalMetadata( + const Message& message) const { + return GetConstRefAtOffset<InternalMetadata>(message, + schema_.GetMetadataOffset()); +} + +InternalMetadata* Reflection::MutableInternalMetadata(Message* message) const { + return GetPointerAtOffset<InternalMetadata>(message, + schema_.GetMetadataOffset()); +} + +const arc_ui32* Reflection::GetInlinedStringDonatedArray( + const Message& message) const { + GOOGLE_DCHECK(schema_.HasInlinedString()); + return &GetConstRefAtOffset<arc_ui32>(message, + schema_.InlinedStringDonatedOffset()); +} + +arc_ui32* Reflection::MutableInlinedStringDonatedArray(Message* message) const { + GOOGLE_DCHECK(schema_.HasHasbits()); + return GetPointerAtOffset<arc_ui32>(message, + schema_.InlinedStringDonatedOffset()); +} + +// Simple accessors for manipulating _inlined_string_donated_; +bool Reflection::IsInlinedStringDonated(const Message& message, + const FieldDescriptor* field) const { + return IsIndexInHasBitSet(GetInlinedStringDonatedArray(message), + schema_.InlinedStringIndex(field)); +} + +// Simple accessors for manipulating has_bits_. +bool Reflection::HasBit(const Message& message, + const FieldDescriptor* field) const { + GOOGLE_DCHECK(!field->options().weak()); + if (schema_.HasBitIndex(field) != static_cast<arc_ui32>(-1)) { + return IsIndexInHasBitSet(GetHasBits(message), schema_.HasBitIndex(field)); + } + + // Intentionally check here because HasBitIndex(field) != -1 means valid. + CheckInvalidAccess(schema_, field); + + // proto3: no has-bits. All fields present except messages, which are + // present only if their message-field pointer is non-null. + if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) { + return !schema_.IsDefaultInstance(message) && + GetRaw<const Message*>(message, field) != nullptr; + } else { + // Non-message field (and non-oneof, since that was handled in HasField() + // before calling us), and singular (again, checked in HasField). So, this + // field must be a scalar. + + // Scalar primitive (numeric or string/bytes) fields are present if + // their value is non-zero (numeric) or non-empty (string/bytes). N.B.: + // we must use this definition here, rather than the "scalar fields + // always present" in the proto3 docs, because MergeFrom() semantics + // require presence as "present on wire", and reflection-based merge + // (which uses HasField()) needs to be consistent with this. + switch (field->cpp_type()) { + case FieldDescriptor::CPPTYPE_STRING: + switch (field->options().ctype()) { + default: { + if (IsInlined(field)) { + return !GetField<InlinedStringField>(message, field) + .GetNoArena() + .empty(); + } + + return GetField<ArenaStringPtr>(message, field).Get().size() > 0; + } + } + return false; + case FieldDescriptor::CPPTYPE_BOOL: + return GetRaw<bool>(message, field) != false; + case FieldDescriptor::CPPTYPE_INT32: + return GetRaw<arc_i32>(message, field) != 0; + case FieldDescriptor::CPPTYPE_INT64: + return GetRaw<arc_i64>(message, field) != 0; + case FieldDescriptor::CPPTYPE_UINT32: + return GetRaw<arc_ui32>(message, field) != 0; + case FieldDescriptor::CPPTYPE_UINT64: + return GetRaw<arc_ui64>(message, field) != 0; + case FieldDescriptor::CPPTYPE_FLOAT: + static_assert(sizeof(arc_ui32) == sizeof(float), + "Code assumes arc_ui32 and float are the same size."); + return GetRaw<arc_ui32>(message, field) != 0; + case FieldDescriptor::CPPTYPE_DOUBLE: + static_assert(sizeof(arc_ui64) == sizeof(double), + "Code assumes arc_ui64 and double are the same size."); + return GetRaw<arc_ui64>(message, field) != 0; + case FieldDescriptor::CPPTYPE_ENUM: + return GetRaw<int>(message, field) != 0; + case FieldDescriptor::CPPTYPE_MESSAGE: + // handled above; avoid warning + break; + } + GOOGLE_LOG(FATAL) << "Reached impossible case in HasBit()."; + return false; + } +} + +void Reflection::SetBit(Message* message, const FieldDescriptor* field) const { + GOOGLE_DCHECK(!field->options().weak()); + const arc_ui32 index = schema_.HasBitIndex(field); + if (index == static_cast<arc_ui32>(-1)) return; + MutableHasBits(message)[index / 32] |= + (static_cast<arc_ui32>(1) << (index % 32)); +} + +void Reflection::ClearBit(Message* message, + const FieldDescriptor* field) const { + GOOGLE_DCHECK(!field->options().weak()); + const arc_ui32 index = schema_.HasBitIndex(field); + if (index == static_cast<arc_ui32>(-1)) return; + MutableHasBits(message)[index / 32] &= + ~(static_cast<arc_ui32>(1) << (index % 32)); +} + +void Reflection::SwapBit(Message* message1, Message* message2, + const FieldDescriptor* field) const { + GOOGLE_DCHECK(!field->options().weak()); + if (!schema_.HasHasbits()) { + return; + } + bool temp_has_bit = HasBit(*message1, field); + if (HasBit(*message2, field)) { + SetBit(message1, field); + } else { + ClearBit(message1, field); + } + if (temp_has_bit) { + SetBit(message2, field); + } else { + ClearBit(message2, field); + } +} + +bool Reflection::HasOneof(const Message& message, + const OneofDescriptor* oneof_descriptor) const { + if (oneof_descriptor->is_synthetic()) { + return HasField(message, oneof_descriptor->field(0)); + } + return (GetOneofCase(message, oneof_descriptor) > 0); +} + +void Reflection::SetOneofCase(Message* message, + const FieldDescriptor* field) const { + *MutableOneofCase(message, field->containing_oneof()) = field->number(); +} + +void Reflection::ClearOneofField(Message* message, + const FieldDescriptor* field) const { + if (HasOneofField(*message, field)) { + ClearOneof(message, field->containing_oneof()); + } +} + +void Reflection::ClearOneof(Message* message, + const OneofDescriptor* oneof_descriptor) const { + if (oneof_descriptor->is_synthetic()) { + ClearField(message, oneof_descriptor->field(0)); + return; + } + // TODO(jieluo): Consider to cache the unused object instead of deleting + // it. It will be much faster if an application switches a lot from + // a few oneof fields. Time/space tradeoff + arc_ui32 oneof_case = GetOneofCase(*message, oneof_descriptor); + if (oneof_case > 0) { + const FieldDescriptor* field = descriptor_->FindFieldByNumber(oneof_case); + if (message->GetArenaForAllocation() == nullptr) { + switch (field->cpp_type()) { + case FieldDescriptor::CPPTYPE_STRING: { + switch (field->options().ctype()) { + default: // TODO(kenton): Support other string reps. + case FieldOptions::STRING: { + // Oneof string fields are never set as a default instance. + // We just need to pass some arbitrary default string to make it + // work. This allows us to not have the real default accessible + // from reflection. + MutableField<ArenaStringPtr>(message, field) + ->Destroy(nullptr, message->GetArenaForAllocation()); + break; + } + } + break; + } + + case FieldDescriptor::CPPTYPE_MESSAGE: + delete *MutableRaw<Message*>(message, field); + break; + default: + break; + } + } + + *MutableOneofCase(message, oneof_descriptor) = 0; + } +} + +#define HANDLE_TYPE(TYPE, CPPTYPE, CTYPE) \ + template <> \ + const RepeatedField<TYPE>& Reflection::GetRepeatedFieldInternal<TYPE>( \ + const Message& message, const FieldDescriptor* field) const { \ + return *static_cast<RepeatedField<TYPE>*>(MutableRawRepeatedField( \ + const_cast<Message*>(&message), field, CPPTYPE, CTYPE, nullptr)); \ + } \ + \ + template <> \ + RepeatedField<TYPE>* Reflection::MutableRepeatedFieldInternal<TYPE>( \ + Message * message, const FieldDescriptor* field) const { \ + return static_cast<RepeatedField<TYPE>*>( \ + MutableRawRepeatedField(message, field, CPPTYPE, CTYPE, nullptr)); \ + } + +HANDLE_TYPE(arc_i32, FieldDescriptor::CPPTYPE_INT32, -1); +HANDLE_TYPE(arc_i64, FieldDescriptor::CPPTYPE_INT64, -1); +HANDLE_TYPE(arc_ui32, FieldDescriptor::CPPTYPE_UINT32, -1); +HANDLE_TYPE(arc_ui64, FieldDescriptor::CPPTYPE_UINT64, -1); +HANDLE_TYPE(float, FieldDescriptor::CPPTYPE_FLOAT, -1); +HANDLE_TYPE(double, FieldDescriptor::CPPTYPE_DOUBLE, -1); +HANDLE_TYPE(bool, FieldDescriptor::CPPTYPE_BOOL, -1); + + +#undef HANDLE_TYPE + +void* Reflection::MutableRawRepeatedString(Message* message, + const FieldDescriptor* field, + bool is_string) const { + (void)is_string; // Parameter is used by Google-internal code. + return MutableRawRepeatedField(message, field, + FieldDescriptor::CPPTYPE_STRING, + FieldOptions::STRING, nullptr); +} + +// Template implementations of basic accessors. Inline because each +// template instance is only called from one location. These are +// used for all types except messages. +template <typename Type> +const Type& Reflection::GetField(const Message& message, + const FieldDescriptor* field) const { + return GetRaw<Type>(message, field); +} + +template <typename Type> +void Reflection::SetField(Message* message, const FieldDescriptor* field, + const Type& value) const { + bool real_oneof = schema_.InRealOneof(field); + if (real_oneof && !HasOneofField(*message, field)) { + ClearOneof(message, field->containing_oneof()); + } + *MutableRaw<Type>(message, field) = value; + real_oneof ? SetOneofCase(message, field) : SetBit(message, field); +} + +template <typename Type> +Type* Reflection::MutableField(Message* message, + const FieldDescriptor* field) const { + schema_.InRealOneof(field) ? SetOneofCase(message, field) + : SetBit(message, field); + return MutableRaw<Type>(message, field); +} + +template <typename Type> +const Type& Reflection::GetRepeatedField(const Message& message, + const FieldDescriptor* field, + int index) const { + return GetRaw<RepeatedField<Type> >(message, field).Get(index); +} + +template <typename Type> +const Type& Reflection::GetRepeatedPtrField(const Message& message, + const FieldDescriptor* field, + int index) const { + return GetRaw<RepeatedPtrField<Type> >(message, field).Get(index); +} + +template <typename Type> +void Reflection::SetRepeatedField(Message* message, + const FieldDescriptor* field, int index, + Type value) const { + MutableRaw<RepeatedField<Type> >(message, field)->Set(index, value); +} + +template <typename Type> +Type* Reflection::MutableRepeatedField(Message* message, + const FieldDescriptor* field, + int index) const { + RepeatedPtrField<Type>* repeated = + MutableRaw<RepeatedPtrField<Type> >(message, field); + return repeated->Mutable(index); +} + +template <typename Type> +void Reflection::AddField(Message* message, const FieldDescriptor* field, + const Type& value) const { + MutableRaw<RepeatedField<Type> >(message, field)->Add(value); +} + +template <typename Type> +Type* Reflection::AddField(Message* message, + const FieldDescriptor* field) const { + RepeatedPtrField<Type>* repeated = + MutableRaw<RepeatedPtrField<Type> >(message, field); + return repeated->Add(); +} + +MessageFactory* Reflection::GetMessageFactory() const { + return message_factory_; +} + +void* Reflection::RepeatedFieldData(Message* message, + const FieldDescriptor* field, + FieldDescriptor::CppType cpp_type, + const Descriptor* message_type) const { + GOOGLE_CHECK(field->is_repeated()); + GOOGLE_CHECK(field->cpp_type() == cpp_type || + (field->cpp_type() == FieldDescriptor::CPPTYPE_ENUM && + cpp_type == FieldDescriptor::CPPTYPE_INT32)) + << "The type parameter T in RepeatedFieldRef<T> API doesn't match " + << "the actual field type (for enums T should be the generated enum " + << "type or arc_i32)."; + if (message_type != nullptr) { + GOOGLE_CHECK_EQ(message_type, field->message_type()); + } + if (field->is_extension()) { + return MutableExtensionSet(message)->MutableRawRepeatedField( + field->number(), field->type(), field->is_packed(), field); + } else { + return MutableRawNonOneof<char>(message, field); + } +} + +MapFieldBase* Reflection::MutableMapData(Message* message, + const FieldDescriptor* field) const { + USAGE_CHECK(IsMapFieldInApi(field), "GetMapData", + "Field is not a map field."); + return MutableRaw<MapFieldBase>(message, field); +} + +const MapFieldBase* Reflection::GetMapData(const Message& message, + const FieldDescriptor* field) const { + USAGE_CHECK(IsMapFieldInApi(field), "GetMapData", + "Field is not a map field."); + return &(GetRaw<MapFieldBase>(message, field)); +} + +namespace { + +// Helper function to transform migration schema into reflection schema. +ReflectionSchema MigrationToReflectionSchema( + const Message* const* default_instance, const arc_ui32* offsets, + MigrationSchema migration_schema) { + ReflectionSchema result; + result.default_instance_ = *default_instance; + // First 7 offsets are offsets to the special fields. The following offsets + // are the proto fields. + result.offsets_ = offsets + migration_schema.offsets_index + 6; + result.has_bit_indices_ = offsets + migration_schema.has_bit_indices_index; + result.has_bits_offset_ = offsets[migration_schema.offsets_index + 0]; + result.metadata_offset_ = offsets[migration_schema.offsets_index + 1]; + result.extensions_offset_ = offsets[migration_schema.offsets_index + 2]; + result.oneof_case_offset_ = offsets[migration_schema.offsets_index + 3]; + result.object_size_ = migration_schema.object_size; + result.weak_field_map_offset_ = offsets[migration_schema.offsets_index + 4]; + result.inlined_string_donated_offset_ = + offsets[migration_schema.offsets_index + 5]; + result.inlined_string_indices_ = + offsets + migration_schema.inlined_string_indices_index; + return result; +} + +} // namespace + +class AssignDescriptorsHelper { + public: + AssignDescriptorsHelper(MessageFactory* factory, + Metadata* file_level_metadata, + const EnumDescriptor** file_level_enum_descriptors, + const MigrationSchema* schemas, + const Message* const* default_instance_data, + const arc_ui32* offsets) + : factory_(factory), + file_level_metadata_(file_level_metadata), + file_level_enum_descriptors_(file_level_enum_descriptors), + schemas_(schemas), + default_instance_data_(default_instance_data), + offsets_(offsets) {} + + void AssignMessageDescriptor(const Descriptor* descriptor) { + for (int i = 0; i < descriptor->nested_type_count(); i++) { + AssignMessageDescriptor(descriptor->nested_type(i)); + } + + file_level_metadata_->descriptor = descriptor; + + file_level_metadata_->reflection = + new Reflection(descriptor, + MigrationToReflectionSchema(default_instance_data_, + offsets_, *schemas_), + DescriptorPool::internal_generated_pool(), factory_); + for (int i = 0; i < descriptor->enum_type_count(); i++) { + AssignEnumDescriptor(descriptor->enum_type(i)); + } + schemas_++; + default_instance_data_++; + file_level_metadata_++; + } + + void AssignEnumDescriptor(const EnumDescriptor* descriptor) { + *file_level_enum_descriptors_ = descriptor; + file_level_enum_descriptors_++; + } + + const Metadata* GetCurrentMetadataPtr() const { return file_level_metadata_; } + + private: + MessageFactory* factory_; + Metadata* file_level_metadata_; + const EnumDescriptor** file_level_enum_descriptors_; + const MigrationSchema* schemas_; + const Message* const* default_instance_data_; + const arc_ui32* offsets_; +}; + +namespace { + +// We have the routines that assign descriptors and build reflection +// automatically delete the allocated reflection. MetadataOwner owns +// all the allocated reflection instances. +struct MetadataOwner { + ~MetadataOwner() { + for (auto range : metadata_arrays_) { + for (const Metadata* m = range.first; m < range.second; m++) { + delete m->reflection; + } + } + } + + void AddArray(const Metadata* begin, const Metadata* end) { + mu_.Lock(); + metadata_arrays_.push_back(std::make_pair(begin, end)); + mu_.Unlock(); + } + + static MetadataOwner* Instance() { + static MetadataOwner* res = OnShutdownDelete(new MetadataOwner); + return res; + } + + private: + MetadataOwner() = default; // private because singleton + + WrappedMutex mu_; + std::vector<std::pair<const Metadata*, const Metadata*> > metadata_arrays_; +}; + +void AddDescriptors(const DescriptorTable* table); + +void AssignDescriptorsImpl(const DescriptorTable* table, bool eager) { + // Ensure the file descriptor is added to the pool. + { + // This only happens once per proto file. So a global mutex to serialize + // calls to AddDescriptors. + static WrappedMutex mu{GOOGLE_PROTOBUF_LINKER_INITIALIZED}; + mu.Lock(); + AddDescriptors(table); + mu.Unlock(); + } + if (eager) { + // Normally we do not want to eagerly build descriptors of our deps. + // However if this proto is optimized for code size (ie using reflection) + // and it has a message extending a custom option of a descriptor with that + // message being optimized for code size as well. Building the descriptors + // in this file requires parsing the serialized file descriptor, which now + // requires parsing the message extension, which potentially requires + // building the descriptor of the message extending one of the options. + // However we are already updating descriptor pool under a lock. To prevent + // this the compiler statically looks for this case and we just make sure we + // first build the descriptors of all our dependencies, preventing the + // deadlock. + int num_deps = table->num_deps; + for (int i = 0; i < num_deps; i++) { + // In case of weak fields deps[i] could be null. + if (table->deps[i]) AssignDescriptors(table->deps[i], true); + } + } + + // Fill the arrays with pointers to descriptors and reflection classes. + const FileDescriptor* file = + DescriptorPool::internal_generated_pool()->FindFileByName( + table->filename); + GOOGLE_CHECK(file != nullptr); + + MessageFactory* factory = MessageFactory::generated_factory(); + + AssignDescriptorsHelper helper( + factory, table->file_level_metadata, table->file_level_enum_descriptors, + table->schemas, table->default_instances, table->offsets); + + for (int i = 0; i < file->message_type_count(); i++) { + helper.AssignMessageDescriptor(file->message_type(i)); + } + + for (int i = 0; i < file->enum_type_count(); i++) { + helper.AssignEnumDescriptor(file->enum_type(i)); + } + if (file->options().cc_generic_services()) { + for (int i = 0; i < file->service_count(); i++) { + table->file_level_service_descriptors[i] = file->service(i); + } + } + MetadataOwner::Instance()->AddArray(table->file_level_metadata, + helper.GetCurrentMetadataPtr()); +} + +void AddDescriptorsImpl(const DescriptorTable* table) { + // Reflection refers to the default fields so make sure they are initialized. + internal::InitProtobufDefaults(); + + // Ensure all dependent descriptors are registered to the generated descriptor + // pool and message factory. + int num_deps = table->num_deps; + for (int i = 0; i < num_deps; i++) { + // In case of weak fields deps[i] could be null. + if (table->deps[i]) AddDescriptors(table->deps[i]); + } + + // Register the descriptor of this file. + DescriptorPool::InternalAddGeneratedFile(table->descriptor, table->size); + MessageFactory::InternalRegisterGeneratedFile(table); +} + +void AddDescriptors(const DescriptorTable* table) { + // AddDescriptors is not thread safe. Callers need to ensure calls are + // properly serialized. This function is only called pre-main by global + // descriptors and we can assume single threaded access or it's called + // by AssignDescriptorImpl which uses a mutex to sequence calls. + if (table->is_initialized) return; + table->is_initialized = true; + AddDescriptorsImpl(table); +} + +} // namespace + +// Separate function because it needs to be a friend of +// Reflection +void RegisterAllTypesInternal(const Metadata* file_level_metadata, int size) { + for (int i = 0; i < size; i++) { + const Reflection* reflection = file_level_metadata[i].reflection; + MessageFactory::InternalRegisterGeneratedMessage( + file_level_metadata[i].descriptor, + reflection->schema_.default_instance_); + } +} + +namespace internal { + +Metadata AssignDescriptors(const DescriptorTable* (*table)(), + internal::once_flag* once, + const Metadata& metadata) { + call_once(*once, [=] { + auto* t = table(); + AssignDescriptorsImpl(t, t->is_eager); + }); + + return metadata; +} + +void AssignDescriptors(const DescriptorTable* table, bool eager) { + if (!eager) eager = table->is_eager; + call_once(*table->once, AssignDescriptorsImpl, table, eager); +} + +AddDescriptorsRunner::AddDescriptorsRunner(const DescriptorTable* table) { + AddDescriptors(table); +} + +void RegisterFileLevelMetadata(const DescriptorTable* table) { + AssignDescriptors(table); + RegisterAllTypesInternal(table->file_level_metadata, table->num_messages); +} + +void UnknownFieldSetSerializer(const uint8_t* base, arc_ui32 offset, + arc_ui32 /*tag*/, arc_ui32 /*has_offset*/, + io::CodedOutputStream* output) { + const void* ptr = base + offset; + const InternalMetadata* metadata = static_cast<const InternalMetadata*>(ptr); + if (metadata->have_unknown_fields()) { + internal::WireFormat::SerializeUnknownFields( + metadata->unknown_fields<UnknownFieldSet>( + UnknownFieldSet::default_instance), + output); + } +} + +} // namespace internal +} // namespace protobuf +} // namespace google + +#include <google/protobuf/port_undef.inc> diff --git a/contrib/libs/protobuf_old/src/google/protobuf/generated_message_reflection.h b/contrib/libs/protobuf_old/src/google/protobuf/generated_message_reflection.h new file mode 100644 index 0000000000..502881f876 --- /dev/null +++ b/contrib/libs/protobuf_old/src/google/protobuf/generated_message_reflection.h @@ -0,0 +1,362 @@ +// 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: kenton@google.com (Kenton Varda) +// Based on original Protocol Buffers design by +// Sanjay Ghemawat, Jeff Dean, and others. +// +// This header is logically internal, but is made public because it is used +// from protocol-compiler-generated code, which may reside in other components. + +#ifndef GOOGLE_PROTOBUF_GENERATED_MESSAGE_REFLECTION_H__ +#define GOOGLE_PROTOBUF_GENERATED_MESSAGE_REFLECTION_H__ + +#include <string> +#include <vector> +#include <google/protobuf/stubs/casts.h> +#include <google/protobuf/stubs/common.h> +#include <google/protobuf/descriptor.h> +#include <google/protobuf/generated_enum_reflection.h> +#include <google/protobuf/stubs/once.h> +#include <google/protobuf/port.h> +#include <google/protobuf/unknown_field_set.h> + + +#include <google/protobuf/port_def.inc> + +#ifdef SWIG +#error "You cannot SWIG proto headers" +#endif + +namespace google { +namespace protobuf { +class MapKey; +class MapValueRef; +class MessageLayoutInspector; +class Message; +struct Metadata; +} // namespace protobuf +} // namespace google + +namespace google { +namespace protobuf { +namespace internal { +class DefaultEmptyOneof; +// Defined in other files. +class ExtensionSet; // extension_set.h +class WeakFieldMap; // weak_field_map.h + +// This struct describes the internal layout of the message, hence this is +// used to act on the message reflectively. +// default_instance: The default instance of the message. This is only +// used to obtain pointers to default instances of embedded +// messages, which GetMessage() will return if the particular +// sub-message has not been initialized yet. (Thus, all +// embedded message fields *must* have non-null pointers +// in the default instance.) +// offsets: An array of ints giving the byte offsets. +// For each oneof or weak field, the offset is relative to the +// default_instance. These can be computed at compile time +// using the +// PROTO2_GENERATED_DEFAULT_ONEOF_FIELD_OFFSET() +// macro. For each none oneof field, the offset is related to +// the start of the message object. These can be computed at +// compile time using the +// PROTO2_GENERATED_MESSAGE_FIELD_OFFSET() macro. +// Besides offsets for all fields, this array also contains +// offsets for oneof unions. The offset of the i-th oneof union +// is offsets[descriptor->field_count() + i]. +// has_bit_indices: Mapping from field indexes to their index in the has +// bit array. +// has_bits_offset: Offset in the message of an array of uint32s of size +// descriptor->field_count()/32, rounded up. This is a +// bitfield where each bit indicates whether or not the +// corresponding field of the message has been initialized. +// The bit for field index i is obtained by the expression: +// has_bits[i / 32] & (1 << (i % 32)) +// unknown_fields_offset: Offset in the message of the UnknownFieldSet for +// the message. +// extensions_offset: Offset in the message of the ExtensionSet for the +// message, or -1 if the message type has no extension +// ranges. +// oneof_case_offset: Offset in the message of an array of uint32s of +// size descriptor->oneof_decl_count(). Each arc_ui32 +// indicates what field is set for each oneof. +// object_size: The size of a message object of this type, as measured +// by sizeof(). +// arena_offset: If a message doesn't have a unknown_field_set that stores +// the arena, it must have a direct pointer to the arena. +// weak_field_map_offset: If the message proto has weak fields, this is the +// offset of _weak_field_map_ in the generated proto. Otherwise +// -1. +struct ReflectionSchema { + public: + // Size of a google::protobuf::Message object of this type. + arc_ui32 GetObjectSize() const { return static_cast<arc_ui32>(object_size_); } + + bool InRealOneof(const FieldDescriptor* field) const { + return field->containing_oneof() && + !field->containing_oneof()->is_synthetic(); + } + + // Offset of a non-oneof field. Getting a field offset is slightly more + // efficient when we know statically that it is not a oneof field. + arc_ui32 GetFieldOffsetNonOneof(const FieldDescriptor* field) const { + GOOGLE_DCHECK(!InRealOneof(field)); + return OffsetValue(offsets_[field->index()], field->type()); + } + + // Offset of any field. + arc_ui32 GetFieldOffset(const FieldDescriptor* field) const { + if (InRealOneof(field)) { + size_t offset = + static_cast<size_t>(field->containing_type()->field_count() + + field->containing_oneof()->index()); + return OffsetValue(offsets_[offset], field->type()); + } else { + return GetFieldOffsetNonOneof(field); + } + } + + bool IsFieldInlined(const FieldDescriptor* field) const { + return Inlined(offsets_[field->index()], field->type()); + } + + arc_ui32 GetOneofCaseOffset(const OneofDescriptor* oneof_descriptor) const { + return static_cast<arc_ui32>(oneof_case_offset_) + + static_cast<arc_ui32>( + static_cast<size_t>(oneof_descriptor->index()) * + sizeof(arc_ui32)); + } + + bool HasHasbits() const { return has_bits_offset_ != -1; } + + // Bit index within the bit array of hasbits. Bit order is low-to-high. + arc_ui32 HasBitIndex(const FieldDescriptor* field) const { + if (has_bits_offset_ == -1) return static_cast<arc_ui32>(-1); + GOOGLE_DCHECK(HasHasbits()); + return has_bit_indices_[field->index()]; + } + + // Byte offset of the hasbits array. + arc_ui32 HasBitsOffset() const { + GOOGLE_DCHECK(HasHasbits()); + return static_cast<arc_ui32>(has_bits_offset_); + } + + bool HasInlinedString() const { return inlined_string_donated_offset_ != -1; } + + // Bit index within the bit array of _inlined_string_donated_. Bit order is + // low-to-high. + arc_ui32 InlinedStringIndex(const FieldDescriptor* field) const { + GOOGLE_DCHECK(HasInlinedString()); + return inlined_string_indices_[field->index()]; + } + + // Byte offset of the _inlined_string_donated_ array. + arc_ui32 InlinedStringDonatedOffset() const { + GOOGLE_DCHECK(HasInlinedString()); + return static_cast<arc_ui32>(inlined_string_donated_offset_); + } + + // The offset of the InternalMetadataWithArena member. + // For Lite this will actually be an InternalMetadataWithArenaLite. + // The schema doesn't contain enough information to distinguish between + // these two cases. + arc_ui32 GetMetadataOffset() const { + return static_cast<arc_ui32>(metadata_offset_); + } + + // Whether this message has an ExtensionSet. + bool HasExtensionSet() const { return extensions_offset_ != -1; } + + // The offset of the ExtensionSet in this message. + arc_ui32 GetExtensionSetOffset() const { + GOOGLE_DCHECK(HasExtensionSet()); + return static_cast<arc_ui32>(extensions_offset_); + } + + // The off set of WeakFieldMap when the message contains weak fields. + // The default is 0 for now. + int GetWeakFieldMapOffset() const { return weak_field_map_offset_; } + + bool IsDefaultInstance(const Message& message) const { + return &message == default_instance_; + } + + // Returns a pointer to the default value for this field. The size and type + // of the underlying data depends on the field's type. + const void* GetFieldDefault(const FieldDescriptor* field) const { + return reinterpret_cast<const uint8_t*>(default_instance_) + + OffsetValue(offsets_[field->index()], field->type()); + } + + // Returns true if the field is implicitly backed by LazyField. + bool IsEagerlyVerifiedLazyField(const FieldDescriptor* field) const { + GOOGLE_DCHECK_EQ(field->type(), FieldDescriptor::TYPE_MESSAGE); + (void)field; + return false; + } + + // Returns true if the field's accessor is called by any external code (aka, + // non proto library code). + bool IsFieldUsed(const FieldDescriptor* field) const { + (void)field; + return true; + } + + bool IsFieldStripped(const FieldDescriptor* field) const { + (void)field; + return false; + } + + bool IsMessageStripped(const Descriptor* descriptor) const { + (void)descriptor; + return false; + } + + + bool HasWeakFields() const { return weak_field_map_offset_ > 0; } + + // These members are intended to be private, but we cannot actually make them + // private because this prevents us from using aggregate initialization of + // them, ie. + // + // ReflectionSchema schema = {a, b, c, d, e, ...}; + // private: + const Message* default_instance_; + const arc_ui32* offsets_; + const arc_ui32* has_bit_indices_; + int has_bits_offset_; + int metadata_offset_; + int extensions_offset_; + int oneof_case_offset_; + int object_size_; + int weak_field_map_offset_; + const arc_ui32* inlined_string_indices_; + int inlined_string_donated_offset_; + + // We tag offset values to provide additional data about fields (such as + // "unused" or "lazy" or "inlined"). + static arc_ui32 OffsetValue(arc_ui32 v, FieldDescriptor::Type type) { + if (type == FieldDescriptor::TYPE_MESSAGE || + type == FieldDescriptor::TYPE_STRING || + type == FieldDescriptor::TYPE_BYTES) { + return v & 0x7FFFFFFEu; + } + return v & 0x7FFFFFFFu; + } + + static bool Inlined(arc_ui32 v, FieldDescriptor::Type type) { + if (type == FieldDescriptor::TYPE_STRING || + type == FieldDescriptor::TYPE_BYTES) { + return (v & 1u) != 0u; + } else { + // Non string/byte fields are not inlined. + return false; + } + } +}; + +// Structs that the code generator emits directly to describe a message. +// These should never used directly except to build a ReflectionSchema +// object. +// +// EXPERIMENTAL: these are changing rapidly, and may completely disappear +// or merge with ReflectionSchema. +struct MigrationSchema { + arc_i32 offsets_index; + arc_i32 has_bit_indices_index; + arc_i32 inlined_string_indices_index; + int object_size; +}; + +// This struct tries to reduce unnecessary padding. +// The num_xxx might not be close to their respective pointer, but this saves +// padding. +struct PROTOBUF_EXPORT DescriptorTable { + mutable bool is_initialized; + bool is_eager; + int size; // of serialized descriptor + const char* descriptor; + const char* filename; + once_flag* once; + const DescriptorTable* const* deps; + int num_deps; + int num_messages; + const MigrationSchema* schemas; + const Message* const* default_instances; + const arc_ui32* offsets; + // update the following descriptor arrays. + Metadata* file_level_metadata; + const EnumDescriptor** file_level_enum_descriptors; + const ServiceDescriptor** file_level_service_descriptors; +}; + +enum { + // Tag used on offsets for fields that don't have a real offset. + // For example, weak message fields go into the WeakFieldMap and not in an + // actual field. + kInvalidFieldOffsetTag = 0x40000000u, +}; + +// AssignDescriptors() pulls the compiled FileDescriptor from the DescriptorPool +// and uses it to populate all of the global variables which store pointers to +// the descriptor objects. It also constructs the reflection objects. It is +// called the first time anyone calls descriptor() or GetReflection() on one of +// the types defined in the file. AssignDescriptors() is thread-safe. +void PROTOBUF_EXPORT AssignDescriptors(const DescriptorTable* table, + bool eager = false); + +// Overload used to implement GetMetadataStatic in the generated code. +// See comments in compiler/cpp/internal/file.cc as to why. +// It takes a `Metadata` and returns it to allow for tail calls and reduce +// binary size. +Metadata PROTOBUF_EXPORT AssignDescriptors(const DescriptorTable* (*table)(), + internal::once_flag* once, + const Metadata& metadata); + +// These cannot be in lite so we put them in the reflection. +PROTOBUF_EXPORT void UnknownFieldSetSerializer(const uint8_t* base, + arc_ui32 offset, arc_ui32 tag, + arc_ui32 has_offset, + io::CodedOutputStream* output); + +struct PROTOBUF_EXPORT AddDescriptorsRunner { + explicit AddDescriptorsRunner(const DescriptorTable* table); +}; + +} // namespace internal +} // namespace protobuf +} // namespace google + +#include <google/protobuf/port_undef.inc> + +#endif // GOOGLE_PROTOBUF_GENERATED_MESSAGE_REFLECTION_H__ diff --git a/contrib/libs/protobuf_old/src/google/protobuf/generated_message_table_driven.cc b/contrib/libs/protobuf_old/src/google/protobuf/generated_message_table_driven.cc new file mode 100644 index 0000000000..8db7780c88 --- /dev/null +++ b/contrib/libs/protobuf_old/src/google/protobuf/generated_message_table_driven.cc @@ -0,0 +1,103 @@ +// 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 <google/protobuf/generated_message_table_driven.h> + +#include <type_traits> + +#include <google/protobuf/stubs/casts.h> +#include <google/protobuf/generated_message_table_driven_lite.h> +#include <google/protobuf/io/zero_copy_stream_impl_lite.h> +#include <google/protobuf/repeated_field.h> +#include <google/protobuf/wire_format.h> +#include <google/protobuf/wire_format_lite.h> + +namespace google { +namespace protobuf { +namespace internal { + +namespace { + +UnknownFieldSet* MutableUnknownFields(MessageLite* msg, arc_i64 arena_offset) { + return Raw<InternalMetadata>(msg, arena_offset) + ->mutable_unknown_fields<UnknownFieldSet>(); +} + +struct UnknownFieldHandler { + // TODO(mvels): consider renaming UnknownFieldHandler to (TableDrivenTraits?), + // and conflating InternalMetaData into it, simplifying the template. + static constexpr bool IsLite() { return false; } + + static bool Skip(MessageLite* msg, const ParseTable& table, + io::CodedInputStream* input, int tag) { + GOOGLE_DCHECK(table.unknown_field_set); + + return WireFormat::SkipField(input, tag, + MutableUnknownFields(msg, table.arena_offset)); + } + + static void Varint(MessageLite* msg, const ParseTable& table, int tag, + int value) { + GOOGLE_DCHECK(table.unknown_field_set); + + MutableUnknownFields(msg, table.arena_offset) + ->AddVarint(WireFormatLite::GetTagFieldNumber(tag), value); + } + + static bool ParseExtension(MessageLite* msg, const ParseTable& table, + io::CodedInputStream* input, int tag) { + ExtensionSet* extensions = GetExtensionSet(msg, table.extension_offset); + if (extensions == nullptr) { + return false; + } + + const Message* prototype = + down_cast<const Message*>(table.default_instance()); + + GOOGLE_DCHECK(prototype != nullptr); + GOOGLE_DCHECK(table.unknown_field_set); + UnknownFieldSet* unknown_fields = + MutableUnknownFields(msg, table.arena_offset); + + return extensions->ParseField(tag, input, prototype, unknown_fields); + } +}; + +} // namespace + +bool MergePartialFromCodedStream(MessageLite* msg, const ParseTable& table, + io::CodedInputStream* input) { + return MergePartialFromCodedStreamImpl<UnknownFieldHandler>(msg, table, + input); +} + +} // namespace internal +} // namespace protobuf +} // namespace google diff --git a/contrib/libs/protobuf_old/src/google/protobuf/generated_message_table_driven.h b/contrib/libs/protobuf_old/src/google/protobuf/generated_message_table_driven.h new file mode 100644 index 0000000000..462fb28c25 --- /dev/null +++ b/contrib/libs/protobuf_old/src/google/protobuf/generated_message_table_driven.h @@ -0,0 +1,351 @@ +// 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_TABLE_DRIVEN_H__ +#define GOOGLE_PROTOBUF_GENERATED_MESSAGE_TABLE_DRIVEN_H__ + +#include <google/protobuf/map.h> +#include <google/protobuf/map_entry_lite.h> +#include <google/protobuf/map_field_lite.h> +#include <google/protobuf/message_lite.h> +#include <google/protobuf/wire_format_lite.h> + +// We require C++11 and Clang to use constexpr for variables, as GCC 4.8 +// requires constexpr to be consistent between declarations of variables +// unnecessarily (see https://gcc.gnu.org/bugzilla/show_bug.cgi?id=58541). +// VS 2017 Update 3 also supports this usage of constexpr. +#if defined(__clang__) || (defined(_MSC_VER) && _MSC_VER >= 1911) +#define PROTOBUF_CONSTEXPR_VAR constexpr +#else // !__clang__ +#define PROTOBUF_CONSTEXPR_VAR +#endif // !_clang + +#ifdef SWIG +#error "You cannot SWIG proto headers" +#endif + +#include <google/protobuf/port_def.inc> + +namespace google { +namespace protobuf { +namespace internal { + +// Processing-type masks. +static constexpr const unsigned char kOneofMask = 0x40; +static constexpr const unsigned char kRepeatedMask = 0x20; +// Mask for the raw type: either a WireFormatLite::FieldType or one of the +// ProcessingTypes below, without the oneof or repeated flag. +static constexpr const unsigned char kTypeMask = 0x1f; + +// Wire type masks. +static constexpr const unsigned char kNotPackedMask = 0x10; +static constexpr const unsigned char kInvalidMask = 0x20; + +enum ProcessingTypes { + TYPE_STRING_CORD = 19, + TYPE_STRING_STRING_PIECE = 20, + TYPE_BYTES_CORD = 21, + TYPE_BYTES_STRING_PIECE = 22, + TYPE_STRING_INLINED = 23, + TYPE_BYTES_INLINED = 24, + TYPE_MAP = 25, +}; + +static_assert(TYPE_MAP < kRepeatedMask, "Invalid enum"); + +struct PROTOBUF_EXPORT FieldMetadata { + arc_ui32 offset; // offset of this field in the struct + arc_ui32 tag; // field * 8 + wire_type + // byte offset * 8 + bit_offset; + // if the high bit is set then this is the byte offset of the oneof_case + // for this field. + arc_ui32 has_offset; + arc_ui32 type; // the type of this field. + const void* ptr; // auxiliary data + + // From the serializer point of view each fundamental type can occur in + // 4 different ways. For simplicity we treat all combinations as a cartesion + // product although not all combinations are allowed. + enum FieldTypeClass { + kPresence, + kNoPresence, + kRepeated, + kPacked, + kOneOf, + kNumTypeClasses // must be last enum + }; + // C++ protobuf has 20 fundamental types, were we added Cord and StringPiece + // and also distinguish the same types if they have different wire format. + enum { + kCordType = 19, + kStringPieceType = 20, + kInlinedType = 21, + kNumTypes = 21, + kSpecial = kNumTypes * kNumTypeClasses, + }; + + static int CalculateType(int fundamental_type, FieldTypeClass type_class); +}; + +// TODO(ckennelly): Add a static assertion to ensure that these masks do not +// conflict with wiretypes. + +// ParseTableField is kept small to help simplify instructions for computing +// offsets, as we will always need this information to parse a field. +// Additional data, needed for some types, is stored in +// AuxiliaryParseTableField. +struct ParseTableField { + arc_ui32 offset; + // The presence_index ordinarily represents a has_bit index, but for fields + // inside a oneof it represents the index in _oneof_case_. + arc_ui32 presence_index; + unsigned char normal_wiretype; + unsigned char packed_wiretype; + + // processing_type is given by: + // (FieldDescriptor->type() << 1) | FieldDescriptor->is_packed() + unsigned char processing_type; + + unsigned char tag_size; +}; + +struct ParseTable; + +union AuxiliaryParseTableField { + typedef bool (*EnumValidator)(int); + + // Enums + struct enum_aux { + EnumValidator validator; + }; + enum_aux enums; + // Group, messages + struct message_aux { + // ExplicitlyInitialized<T> -> T requires a reinterpret_cast, which prevents + // the tables from being constructed as a constexpr. We use void to avoid + // the cast. + const void* default_message_void; + const MessageLite* default_message() const { + return static_cast<const MessageLite*>(default_message_void); + } + }; + message_aux messages; + // Strings + struct string_aux { + const void* default_ptr; + const char* field_name; + }; + string_aux strings; + + struct map_aux { + bool (*parse_map)(io::CodedInputStream*, void*); + }; + map_aux maps; + + AuxiliaryParseTableField() = default; + constexpr AuxiliaryParseTableField(AuxiliaryParseTableField::enum_aux e) + : enums(e) {} + constexpr AuxiliaryParseTableField(AuxiliaryParseTableField::message_aux m) + : messages(m) {} + constexpr AuxiliaryParseTableField(AuxiliaryParseTableField::string_aux s) + : strings(s) {} + constexpr AuxiliaryParseTableField(AuxiliaryParseTableField::map_aux m) + : maps(m) {} +}; + +struct ParseTable { + const ParseTableField* fields; + const AuxiliaryParseTableField* aux; + int max_field_number; + // TODO(ckennelly): Do something with this padding. + + // TODO(ckennelly): Vet these for sign extension. + arc_i64 has_bits_offset; + arc_i64 oneof_case_offset; + arc_i64 extension_offset; + arc_i64 arena_offset; + + // ExplicitlyInitialized<T> -> T requires a reinterpret_cast, which prevents + // the tables from being constructed as a constexpr. We use void to avoid + // the cast. + const void* default_instance_void; + const MessageLite* default_instance() const { + return static_cast<const MessageLite*>(default_instance_void); + } + + bool unknown_field_set; +}; + +static_assert(sizeof(ParseTableField) <= 16, "ParseTableField is too large"); +// The tables must be composed of POD components to ensure link-time +// initialization. +static_assert(std::is_standard_layout<ParseTableField>::value, ""); +static_assert(std::is_trivial<ParseTableField>::value, ""); +static_assert(std::is_standard_layout<AuxiliaryParseTableField>::value, ""); +static_assert(std::is_trivial<AuxiliaryParseTableField>::value, ""); +static_assert( + std::is_standard_layout<AuxiliaryParseTableField::enum_aux>::value, ""); +static_assert(std::is_trivial<AuxiliaryParseTableField::enum_aux>::value, ""); +static_assert( + std::is_standard_layout<AuxiliaryParseTableField::message_aux>::value, ""); +static_assert(std::is_trivial<AuxiliaryParseTableField::message_aux>::value, + ""); +static_assert( + std::is_standard_layout<AuxiliaryParseTableField::string_aux>::value, ""); +static_assert(std::is_trivial<AuxiliaryParseTableField::string_aux>::value, ""); +static_assert(std::is_standard_layout<ParseTable>::value, ""); +static_assert(std::is_trivial<ParseTable>::value, ""); + +// TODO(ckennelly): Consolidate these implementations into a single one, using +// dynamic dispatch to the appropriate unknown field handler. +bool MergePartialFromCodedStream(MessageLite* msg, const ParseTable& table, + io::CodedInputStream* input); +bool MergePartialFromCodedStreamLite(MessageLite* msg, const ParseTable& table, + io::CodedInputStream* input); + +template <typename Entry> +bool ParseMap(io::CodedInputStream* input, void* map_field) { + typedef typename MapEntryToMapField<Entry>::MapFieldType MapFieldType; + typedef Map<typename Entry::EntryKeyType, typename Entry::EntryValueType> + MapType; + typedef typename Entry::template Parser<MapFieldType, MapType> ParserType; + + ParserType parser(static_cast<MapFieldType*>(map_field)); + return WireFormatLite::ReadMessageNoVirtual(input, &parser); +} + +struct SerializationTable { + int num_fields; + const FieldMetadata* field_table; +}; + +PROTOBUF_EXPORT void SerializeInternal(const uint8_t* base, + const FieldMetadata* table, + arc_i32 num_fields, + io::CodedOutputStream* output); + +inline void TableSerialize(const MessageLite& msg, + const SerializationTable* table, + io::CodedOutputStream* output) { + const FieldMetadata* field_table = table->field_table; + int num_fields = table->num_fields - 1; + const uint8_t* base = reinterpret_cast<const uint8_t*>(&msg); + // TODO(gerbens) This skips the first test if we could use the fast + // array serialization path, we should make this + // int cached_size = + // *reinterpret_cast<const arc_i32*>(base + field_table->offset); + // SerializeWithCachedSize(msg, field_table + 1, num_fields, cached_size, ...) + // But we keep conformance with the old way for now. + SerializeInternal(base, field_table + 1, num_fields, output); +} + +PROTOBUF_EXPORT uint8_t* SerializeInternalToArray(const uint8_t* base, + const FieldMetadata* table, + arc_i32 num_fields, + bool is_deterministic, + uint8_t* buffer); + +inline uint8_t* TableSerializeToArray(const MessageLite& msg, + const SerializationTable* table, + bool is_deterministic, uint8_t* buffer) { + const uint8_t* base = reinterpret_cast<const uint8_t*>(&msg); + const FieldMetadata* field_table = table->field_table + 1; + int num_fields = table->num_fields - 1; + return SerializeInternalToArray(base, field_table, num_fields, + is_deterministic, buffer); +} + +template <typename T> +struct CompareHelper { + bool operator()(const T& a, const T& b) const { return a < b; } +}; + +template <> +struct CompareHelper<ArenaStringPtr> { + bool operator()(const ArenaStringPtr& a, const ArenaStringPtr& b) const { + return a.Get() < b.Get(); + } +}; + +struct CompareMapKey { + template <typename T> + bool operator()(const MapEntryHelper<T>& a, + const MapEntryHelper<T>& b) const { + return Compare(a.key_, b.key_); + } + template <typename T> + bool Compare(const T& a, const T& b) const { + return CompareHelper<T>()(a, b); + } +}; + +template <typename MapFieldType, const SerializationTable* table> +void MapFieldSerializer(const uint8_t* base, arc_ui32 offset, arc_ui32 tag, + arc_ui32 has_offset, io::CodedOutputStream* output) { + typedef MapEntryHelper<typename MapFieldType::EntryTypeTrait> Entry; + typedef typename MapFieldType::MapType::const_iterator Iter; + + const MapFieldType& map_field = + *reinterpret_cast<const MapFieldType*>(base + offset); + const SerializationTable* t = + table + + has_offset; // has_offset is overloaded for maps to mean table offset + if (!output->IsSerializationDeterministic()) { + for (Iter it = map_field.GetMap().begin(); it != map_field.GetMap().end(); + ++it) { + Entry map_entry(*it); + output->WriteVarint32(tag); + output->WriteVarint32(map_entry._cached_size_); + SerializeInternal(reinterpret_cast<const uint8_t*>(&map_entry), + t->field_table, t->num_fields, output); + } + } else { + std::vector<Entry> v; + for (Iter it = map_field.GetMap().begin(); it != map_field.GetMap().end(); + ++it) { + v.push_back(Entry(*it)); + } + std::sort(v.begin(), v.end(), CompareMapKey()); + for (int i = 0; i < v.size(); i++) { + output->WriteVarint32(tag); + output->WriteVarint32(v[i]._cached_size_); + SerializeInternal(reinterpret_cast<const uint8_t*>(&v[i]), t->field_table, + t->num_fields, output); + } + } +} + +} // namespace internal +} // namespace protobuf +} // namespace google + +#include <google/protobuf/port_undef.inc> + +#endif // GOOGLE_PROTOBUF_GENERATED_MESSAGE_TABLE_DRIVEN_H__ diff --git a/contrib/libs/protobuf_old/src/google/protobuf/generated_message_table_driven_lite.cc b/contrib/libs/protobuf_old/src/google/protobuf/generated_message_table_driven_lite.cc new file mode 100644 index 0000000000..ed0a3d4d19 --- /dev/null +++ b/contrib/libs/protobuf_old/src/google/protobuf/generated_message_table_driven_lite.cc @@ -0,0 +1,106 @@ +// 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 <google/protobuf/generated_message_table_driven_lite.h> + +#include <type_traits> + +#include <google/protobuf/io/zero_copy_stream_impl_lite.h> +#include <google/protobuf/metadata_lite.h> +#include <google/protobuf/repeated_field.h> +#include <google/protobuf/wire_format_lite.h> + +namespace google { +namespace protobuf { +namespace internal { + +namespace { + +TProtoStringType* MutableUnknownFields(MessageLite* msg, arc_i64 arena_offset) { + return Raw<InternalMetadata>(msg, arena_offset) + ->mutable_unknown_fields<TProtoStringType>(); +} + +struct UnknownFieldHandlerLite { + // TODO(mvels): consider renaming UnknownFieldHandler to (TableDrivenTraits?), + // and conflating InternalMetaData into it, simplifying the template. + static constexpr bool IsLite() { return true; } + + static bool Skip(MessageLite* msg, const ParseTable& table, + io::CodedInputStream* input, int tag) { + GOOGLE_DCHECK(!table.unknown_field_set); + io::StringOutputStream unknown_fields_string( + MutableUnknownFields(msg, table.arena_offset)); + io::CodedOutputStream unknown_fields_stream(&unknown_fields_string, false); + + return internal::WireFormatLite::SkipField(input, tag, + &unknown_fields_stream); + } + + static void Varint(MessageLite* msg, const ParseTable& table, int tag, + int value) { + GOOGLE_DCHECK(!table.unknown_field_set); + + io::StringOutputStream unknown_fields_string( + MutableUnknownFields(msg, table.arena_offset)); + io::CodedOutputStream unknown_fields_stream(&unknown_fields_string, false); + unknown_fields_stream.WriteVarint32(tag); + unknown_fields_stream.WriteVarint32(value); + } + + static bool ParseExtension(MessageLite* msg, const ParseTable& table, + io::CodedInputStream* input, int tag) { + ExtensionSet* extensions = GetExtensionSet(msg, table.extension_offset); + if (extensions == nullptr) { + return false; + } + + const MessageLite* prototype = table.default_instance(); + + GOOGLE_DCHECK(!table.unknown_field_set); + io::StringOutputStream unknown_fields_string( + MutableUnknownFields(msg, table.arena_offset)); + io::CodedOutputStream unknown_fields_stream(&unknown_fields_string, false); + return extensions->ParseField(tag, input, prototype, + &unknown_fields_stream); + } +}; + +} // namespace + +bool MergePartialFromCodedStreamLite(MessageLite* msg, const ParseTable& table, + io::CodedInputStream* input) { + return MergePartialFromCodedStreamImpl<UnknownFieldHandlerLite>(msg, table, + input); +} + +} // namespace internal +} // namespace protobuf +} // namespace google diff --git a/contrib/libs/protobuf_old/src/google/protobuf/generated_message_table_driven_lite.h b/contrib/libs/protobuf_old/src/google/protobuf/generated_message_table_driven_lite.h new file mode 100644 index 0000000000..50a619ee93 --- /dev/null +++ b/contrib/libs/protobuf_old/src/google/protobuf/generated_message_table_driven_lite.h @@ -0,0 +1,874 @@ +// 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_TABLE_DRIVEN_LITE_H__ +#define GOOGLE_PROTOBUF_GENERATED_MESSAGE_TABLE_DRIVEN_LITE_H__ + +#include <google/protobuf/io/zero_copy_stream_impl_lite.h> +#include <google/protobuf/extension_set.h> +#include <google/protobuf/generated_message_table_driven.h> +#include <google/protobuf/implicit_weak_message.h> +#include <google/protobuf/inlined_string_field.h> +#include <google/protobuf/repeated_field.h> +#include <google/protobuf/wire_format_lite.h> +#include <type_traits> + + +#include <google/protobuf/port_def.inc> + +namespace google { +namespace protobuf { +namespace internal { + + +enum StringType { + StringType_STRING = 0, + StringType_INLINED = 3 +}; + +// Logically a superset of StringType, consisting of all field types that +// require special initialization. +enum ProcessingType { + ProcessingType_STRING = 0, + ProcessingType_CORD = 1, + ProcessingType_STRING_PIECE = 2, + ProcessingType_INLINED = 3, + ProcessingType_MESSAGE = 4, +}; + +enum Cardinality { + Cardinality_SINGULAR = 0, + Cardinality_REPEATED = 1, + Cardinality_ONEOF = 3 +}; + +template <typename Type> +inline Type* Raw(MessageLite* msg, arc_i64 offset) { + return reinterpret_cast<Type*>(reinterpret_cast<uint8_t*>(msg) + offset); +} + +template <typename Type> +inline const Type* Raw(const MessageLite* msg, arc_i64 offset) { + return reinterpret_cast<const Type*>(reinterpret_cast<const uint8_t*>(msg) + + offset); +} + +inline ExtensionSet* GetExtensionSet(MessageLite* msg, + arc_i64 extension_offset) { + if (extension_offset == -1) { + return nullptr; + } + + return Raw<ExtensionSet>(msg, extension_offset); +} + +template <typename Type> +inline Type* AddField(MessageLite* msg, arc_i64 offset) { + static_assert(std::is_trivial<Type>::value || + std::is_same<Type, InlinedStringField>::value, + "Do not assign"); + + RepeatedField<Type>* repeated = Raw<RepeatedField<Type>>(msg, offset); + return repeated->Add(); +} + +template <> +inline TProtoStringType* AddField<TProtoStringType>(MessageLite* msg, arc_i64 offset) { + RepeatedPtrField<TProtoStringType>* repeated = + Raw<RepeatedPtrField<TProtoStringType>>(msg, offset); + return repeated->Add(); +} + + +template <typename Type> +inline void AddField(MessageLite* msg, arc_i64 offset, Type value) { + static_assert(std::is_trivial<Type>::value, "Do not assign"); + *AddField<Type>(msg, offset) = value; +} + +inline void SetBit(arc_ui32* has_bits, arc_ui32 has_bit_index) { + GOOGLE_DCHECK(has_bits != nullptr); + + arc_ui32 mask = static_cast<arc_ui32>(1u) << (has_bit_index % 32); + has_bits[has_bit_index / 32u] |= mask; +} + +template <typename Type> +inline Type* MutableField(MessageLite* msg, arc_ui32* has_bits, + arc_ui32 has_bit_index, arc_i64 offset) { + SetBit(has_bits, has_bit_index); + return Raw<Type>(msg, offset); +} + +template <typename Type> +inline void SetField(MessageLite* msg, arc_ui32* has_bits, + arc_ui32 has_bit_index, arc_i64 offset, Type value) { + static_assert(std::is_trivial<Type>::value, "Do not assign"); + *MutableField<Type>(msg, has_bits, has_bit_index, offset) = value; +} + +template <typename Type> +inline void SetOneofField(MessageLite* msg, arc_ui32* oneof_case, + arc_ui32 oneof_case_index, arc_i64 offset, + int field_number, Type value) { + oneof_case[oneof_case_index] = field_number; + *Raw<Type>(msg, offset) = value; +} + +// Clears a oneof field. The field argument should correspond to the particular +// field that is currently set in the oneof. +inline void ClearOneofField(const ParseTableField& field, Arena* arena, + MessageLite* msg) { + switch (field.processing_type & kTypeMask) { + case WireFormatLite::TYPE_MESSAGE: + if (arena == nullptr) { + delete *Raw<MessageLite*>(msg, field.offset); + } + break; + + case WireFormatLite::TYPE_STRING: + case WireFormatLite::TYPE_BYTES: + Raw<ArenaStringPtr>(msg, field.offset) + ->Destroy(ArenaStringPtr::EmptyDefault{}, arena); + break; + + case TYPE_STRING_INLINED: + case TYPE_BYTES_INLINED: + Raw<InlinedStringField>(msg, field.offset)->DestroyNoArena(nullptr); + break; + + default: + // No cleanup needed. + break; + } +} + +// Clears and reinitializes a oneof field as necessary, in preparation for +// parsing a new value with type field_type and field number field_number. +// +// Note: the oneof_case argument should point directly to the _oneof_case_ +// element corresponding to this particular oneof, not to the beginning of the +// _oneof_case_ array. +template <ProcessingType field_type> +inline void ResetOneofField(const ParseTable& table, int field_number, + Arena* arena, MessageLite* msg, + arc_ui32* oneof_case, arc_i64 offset, + const void* default_ptr) { + if (static_cast<arc_i64>(*oneof_case) == field_number) { + // The oneof is already set to the right type, so there is no need to clear + // it. + return; + } + + if (*oneof_case != 0) { + ClearOneofField(table.fields[*oneof_case], arena, msg); + } + *oneof_case = field_number; + + switch (field_type) { + case ProcessingType_STRING: + Raw<ArenaStringPtr>(msg, offset) + ->UnsafeSetDefault(static_cast<const TProtoStringType*>(default_ptr)); + break; + case ProcessingType_INLINED: + new (Raw<InlinedStringField>(msg, offset)) + InlinedStringField(*static_cast<const TProtoStringType*>(default_ptr)); + break; + case ProcessingType_MESSAGE: + MessageLite** submessage = Raw<MessageLite*>(msg, offset); + const MessageLite* prototype = + table.aux[field_number].messages.default_message(); + *submessage = prototype->New(arena); + break; + } +} + +template <typename UnknownFieldHandler, Cardinality cardinality, + bool is_string_type, StringType ctype> +static inline bool HandleString(io::CodedInputStream* input, MessageLite* msg, + Arena* arena, arc_ui32* has_bits, + arc_ui32 has_bit_index, arc_i64 offset, + const void* default_ptr, + const char* field_name) { + StringPiece utf8_string_data; +#ifdef GOOGLE_PROTOBUF_UTF8_VALIDATION_ENABLED + constexpr bool kValidateUtf8 = is_string_type; +#else + constexpr bool kValidateUtf8 = false; +#endif // GOOGLE_PROTOBUF_UTF8_VALIDATION_ENABLED + + switch (ctype) { + case StringType_INLINED: { + TProtoStringType* value = nullptr; + switch (cardinality) { + case Cardinality_SINGULAR: { + // TODO(ckennelly): Is this optimal? + InlinedStringField* s = MutableField<InlinedStringField>( + msg, has_bits, has_bit_index, offset); + value = s->UnsafeMutablePointer(); + } break; + case Cardinality_REPEATED: { + value = AddField<TProtoStringType>(msg, offset); + } break; + case Cardinality_ONEOF: { + InlinedStringField* s = Raw<InlinedStringField>(msg, offset); + value = s->UnsafeMutablePointer(); + } break; + } + GOOGLE_DCHECK(value != nullptr); + if (PROTOBUF_PREDICT_FALSE(!WireFormatLite::ReadString(input, value))) { + return false; + } + utf8_string_data = *value; + break; + } + case StringType_STRING: { + switch (cardinality) { + case Cardinality_SINGULAR: { + ArenaStringPtr* field = MutableField<ArenaStringPtr>( + msg, has_bits, has_bit_index, offset); + TProtoStringType* value = field->MutableNoCopy( + static_cast<const TProtoStringType*>(default_ptr), arena); + if (PROTOBUF_PREDICT_FALSE( + !WireFormatLite::ReadString(input, value))) { + return false; + } + utf8_string_data = field->Get(); + } break; + case Cardinality_REPEATED: { + TProtoStringType* value = AddField<TProtoStringType>(msg, offset); + if (PROTOBUF_PREDICT_FALSE( + !WireFormatLite::ReadString(input, value))) { + return false; + } + utf8_string_data = *value; + } break; + case Cardinality_ONEOF: { + ArenaStringPtr* field = Raw<ArenaStringPtr>(msg, offset); + TProtoStringType* value = field->MutableNoCopy( + static_cast<const TProtoStringType*>(default_ptr), arena); + if (PROTOBUF_PREDICT_FALSE( + !WireFormatLite::ReadString(input, value))) { + return false; + } + utf8_string_data = field->Get(); + } break; + default: + PROTOBUF_ASSUME(false); + } + break; + } + default: + PROTOBUF_ASSUME(false); + } + + if (kValidateUtf8) { + // TODO(b/118759213): fail if proto3 + WireFormatLite::VerifyUtf8String(utf8_string_data.data(), + utf8_string_data.length(), + WireFormatLite::PARSE, field_name); + } + return true; +} + +template <typename UnknownFieldHandler, Cardinality cardinality> +inline bool HandleEnum(const ParseTable& table, io::CodedInputStream* input, + MessageLite* msg, arc_ui32* presence, + arc_ui32 presence_index, arc_i64 offset, arc_ui32 tag, + int field_number) { + int value; + if (PROTOBUF_PREDICT_FALSE( + (!WireFormatLite::ReadPrimitive<int, WireFormatLite::TYPE_ENUM>( + input, &value)))) { + return false; + } + + AuxiliaryParseTableField::EnumValidator validator = + table.aux[field_number].enums.validator; + if (validator == nullptr || validator(value)) { + switch (cardinality) { + case Cardinality_SINGULAR: + SetField(msg, presence, presence_index, offset, value); + break; + case Cardinality_REPEATED: + AddField(msg, offset, value); + break; + case Cardinality_ONEOF: + ClearOneofField(table.fields[presence[presence_index]], msg->GetArena(), + msg); + SetOneofField(msg, presence, presence_index, offset, field_number, + value); + break; + default: + PROTOBUF_ASSUME(false); + } + } else { + UnknownFieldHandler::Varint(msg, table, tag, value); + } + + return true; +} + +// RepeatedMessageTypeHandler allows us to operate on RepeatedPtrField fields +// without instantiating the specific template. +class RepeatedMessageTypeHandler { + public: + typedef MessageLite Type; + typedef MessageLite WeakType; + static Arena* GetArena(Type* t) { return t->GetArena(); } + static inline Type* NewFromPrototype(const Type* prototype, + Arena* arena = nullptr) { + return prototype->New(arena); + } + static void Delete(Type* t, Arena* arena = nullptr) { + if (arena == nullptr) { + delete t; + } + } +}; + +class MergePartialFromCodedStreamHelper { + public: + static MessageLite* Add(RepeatedPtrFieldBase* field, + const MessageLite* prototype) { + return field->Add<RepeatedMessageTypeHandler>( + const_cast<MessageLite*>(prototype)); + } +}; + +template <typename UnknownFieldHandler, arc_ui32 kMaxTag> +bool MergePartialFromCodedStreamInlined(MessageLite* msg, + const ParseTable& table, + io::CodedInputStream* input) { + // We require that has_bits are present, as to avoid having to check for them + // for every field. + // + // TODO(ckennelly): Make this a compile-time parameter with templates. + GOOGLE_DCHECK_GE(table.has_bits_offset, 0); + arc_ui32* has_bits = Raw<arc_ui32>(msg, table.has_bits_offset); + GOOGLE_DCHECK(has_bits != nullptr); + + while (true) { + arc_ui32 tag = input->ReadTagWithCutoffNoLastTag(kMaxTag).first; + const WireFormatLite::WireType wire_type = + WireFormatLite::GetTagWireType(tag); + const int field_number = WireFormatLite::GetTagFieldNumber(tag); + + if (PROTOBUF_PREDICT_FALSE(field_number > table.max_field_number)) { + // check for possible extensions + if (UnknownFieldHandler::ParseExtension(msg, table, input, tag)) { + // successfully parsed + continue; + } + + if (PROTOBUF_PREDICT_FALSE( + !UnknownFieldHandler::Skip(msg, table, input, tag))) { + return false; + } + + continue; + } + + // We implicitly verify that data points to a valid field as we check the + // wire types. Entries in table.fields[i] that do not correspond to valid + // field numbers have their normal_wiretype and packed_wiretype fields set + // with the kInvalidMask value. As wire_type cannot take on that value, we + // will never match. + const ParseTableField* data = table.fields + field_number; + + // TODO(ckennelly): Avoid sign extension + const arc_i64 presence_index = data->presence_index; + const arc_i64 offset = data->offset; + const unsigned char processing_type = data->processing_type; + + if (data->normal_wiretype == static_cast<unsigned char>(wire_type)) { + switch (processing_type) { +#define HANDLE_TYPE(TYPE, CPPTYPE) \ + case (WireFormatLite::TYPE_##TYPE): { \ + CPPTYPE value; \ + if (PROTOBUF_PREDICT_FALSE( \ + (!WireFormatLite::ReadPrimitive< \ + CPPTYPE, WireFormatLite::TYPE_##TYPE>(input, &value)))) { \ + return false; \ + } \ + SetField(msg, has_bits, presence_index, offset, value); \ + break; \ + } \ + case (WireFormatLite::TYPE_##TYPE) | kRepeatedMask: { \ + RepeatedField<CPPTYPE>* values = Raw<RepeatedField<CPPTYPE>>(msg, offset); \ + if (PROTOBUF_PREDICT_FALSE((!WireFormatLite::ReadRepeatedPrimitive< \ + CPPTYPE, WireFormatLite::TYPE_##TYPE>( \ + data->tag_size, tag, input, values)))) { \ + return false; \ + } \ + break; \ + } \ + case (WireFormatLite::TYPE_##TYPE) | kOneofMask: { \ + arc_ui32* oneof_case = Raw<arc_ui32>(msg, table.oneof_case_offset); \ + CPPTYPE value; \ + if (PROTOBUF_PREDICT_FALSE( \ + (!WireFormatLite::ReadPrimitive< \ + CPPTYPE, WireFormatLite::TYPE_##TYPE>(input, &value)))) { \ + return false; \ + } \ + ClearOneofField(table.fields[oneof_case[presence_index]], msg->GetArena(), \ + msg); \ + SetOneofField(msg, oneof_case, presence_index, offset, field_number, \ + value); \ + break; \ + } + + HANDLE_TYPE(INT32, arc_i32) + HANDLE_TYPE(INT64, arc_i64) + HANDLE_TYPE(SINT32, arc_i32) + HANDLE_TYPE(SINT64, arc_i64) + HANDLE_TYPE(UINT32, arc_ui32) + HANDLE_TYPE(UINT64, arc_ui64) + + HANDLE_TYPE(FIXED32, arc_ui32) + HANDLE_TYPE(FIXED64, arc_ui64) + HANDLE_TYPE(SFIXED32, arc_i32) + HANDLE_TYPE(SFIXED64, arc_i64) + + HANDLE_TYPE(FLOAT, float) + HANDLE_TYPE(DOUBLE, double) + + HANDLE_TYPE(BOOL, bool) +#undef HANDLE_TYPE + case WireFormatLite::TYPE_BYTES: +#ifndef GOOGLE_PROTOBUF_UTF8_VALIDATION_ENABLED + case WireFormatLite::TYPE_STRING: +#endif // GOOGLE_PROTOBUF_UTF8_VALIDATION_ENABLED + { + Arena* const arena = msg->GetArena(); + const void* default_ptr = table.aux[field_number].strings.default_ptr; + + if (PROTOBUF_PREDICT_FALSE( + (!HandleString<UnknownFieldHandler, Cardinality_SINGULAR, + false, StringType_STRING>( + input, msg, arena, has_bits, presence_index, offset, + default_ptr, nullptr)))) { + return false; + } + break; + } + case TYPE_BYTES_INLINED: +#ifndef GOOGLE_PROTOBUF_UTF8_VALIDATION_ENABLED + case TYPE_STRING_INLINED: +#endif // !GOOGLE_PROTOBUF_UTF8_VALIDATION_ENABLED + { + Arena* const arena = msg->GetArena(); + const void* default_ptr = table.aux[field_number].strings.default_ptr; + + if (PROTOBUF_PREDICT_FALSE( + (!HandleString<UnknownFieldHandler, Cardinality_SINGULAR, + false, StringType_INLINED>( + input, msg, arena, has_bits, presence_index, offset, + default_ptr, nullptr)))) { + return false; + } + break; + } + case WireFormatLite::TYPE_BYTES | kOneofMask: +#ifndef GOOGLE_PROTOBUF_UTF8_VALIDATION_ENABLED + case WireFormatLite::TYPE_STRING | kOneofMask: +#endif // !GOOGLE_PROTOBUF_UTF8_VALIDATION_ENABLED + { + Arena* const arena = msg->GetArena(); + arc_ui32* oneof_case = Raw<arc_ui32>(msg, table.oneof_case_offset); + const void* default_ptr = table.aux[field_number].strings.default_ptr; + + ResetOneofField<ProcessingType_STRING>( + table, field_number, arena, msg, oneof_case + presence_index, + offset, default_ptr); + + if (PROTOBUF_PREDICT_FALSE( + (!HandleString<UnknownFieldHandler, Cardinality_ONEOF, false, + StringType_STRING>(input, msg, arena, has_bits, + presence_index, offset, + default_ptr, nullptr)))) { + return false; + } + break; + } + case (WireFormatLite::TYPE_BYTES) | kRepeatedMask: + case TYPE_BYTES_INLINED | kRepeatedMask: +#ifndef GOOGLE_PROTOBUF_UTF8_VALIDATION_ENABLED + case (WireFormatLite::TYPE_STRING) | kRepeatedMask: + case TYPE_STRING_INLINED | kRepeatedMask: +#endif // !GOOGLE_PROTOBUF_UTF8_VALIDATION_ENABLED + { + Arena* const arena = msg->GetArena(); + const void* default_ptr = table.aux[field_number].strings.default_ptr; + + if (PROTOBUF_PREDICT_FALSE( + (!HandleString<UnknownFieldHandler, Cardinality_REPEATED, + false, StringType_STRING>( + input, msg, arena, has_bits, presence_index, offset, + default_ptr, nullptr)))) { + return false; + } + break; + } +#ifdef GOOGLE_PROTOBUF_UTF8_VALIDATION_ENABLED + case (WireFormatLite::TYPE_STRING): { + Arena* const arena = msg->GetArena(); + const void* default_ptr = table.aux[field_number].strings.default_ptr; + const char* field_name = table.aux[field_number].strings.field_name; + + if (PROTOBUF_PREDICT_FALSE( + (!HandleString<UnknownFieldHandler, Cardinality_SINGULAR, + true, StringType_STRING>( + input, msg, arena, has_bits, presence_index, offset, + default_ptr, field_name)))) { + return false; + } + break; + } + case TYPE_STRING_INLINED | kRepeatedMask: + case (WireFormatLite::TYPE_STRING) | kRepeatedMask: { + Arena* const arena = msg->GetArena(); + const void* default_ptr = table.aux[field_number].strings.default_ptr; + const char* field_name = table.aux[field_number].strings.field_name; + + if (PROTOBUF_PREDICT_FALSE( + (!HandleString<UnknownFieldHandler, Cardinality_REPEATED, + true, StringType_STRING>( + input, msg, arena, has_bits, presence_index, offset, + default_ptr, field_name)))) { + return false; + } + break; + } + case (WireFormatLite::TYPE_STRING) | kOneofMask: { + Arena* const arena = msg->GetArena(); + arc_ui32* oneof_case = Raw<arc_ui32>(msg, table.oneof_case_offset); + const void* default_ptr = table.aux[field_number].strings.default_ptr; + const char* field_name = table.aux[field_number].strings.field_name; + + ResetOneofField<ProcessingType_STRING>( + table, field_number, arena, msg, oneof_case + presence_index, + offset, default_ptr); + + if (PROTOBUF_PREDICT_FALSE( + (!HandleString<UnknownFieldHandler, Cardinality_ONEOF, true, + StringType_STRING>( + input, msg, arena, has_bits, presence_index, offset, + default_ptr, field_name)))) { + return false; + } + break; + } +#endif // GOOGLE_PROTOBUF_UTF8_VALIDATION_ENABLED + case WireFormatLite::TYPE_ENUM: { + if (PROTOBUF_PREDICT_FALSE( + (!HandleEnum<UnknownFieldHandler, Cardinality_SINGULAR>( + table, input, msg, has_bits, presence_index, offset, tag, + field_number)))) { + return false; + } + break; + } + case WireFormatLite::TYPE_ENUM | kRepeatedMask: { + if (PROTOBUF_PREDICT_FALSE( + (!HandleEnum<UnknownFieldHandler, Cardinality_REPEATED>( + table, input, msg, has_bits, presence_index, offset, tag, + field_number)))) { + return false; + } + break; + } + case WireFormatLite::TYPE_ENUM | kOneofMask: { + arc_ui32* oneof_case = Raw<arc_ui32>(msg, table.oneof_case_offset); + if (PROTOBUF_PREDICT_FALSE( + (!HandleEnum<UnknownFieldHandler, Cardinality_ONEOF>( + table, input, msg, oneof_case, presence_index, offset, + tag, field_number)))) { + return false; + } + break; + } + case WireFormatLite::TYPE_GROUP: { + MessageLite** submsg_holder = + MutableField<MessageLite*>(msg, has_bits, presence_index, offset); + MessageLite* submsg = *submsg_holder; + + if (submsg == nullptr) { + Arena* const arena = msg->GetArena(); + const MessageLite* prototype = + table.aux[field_number].messages.default_message(); + submsg = prototype->New(arena); + *submsg_holder = submsg; + } + + if (PROTOBUF_PREDICT_FALSE( + !WireFormatLite::ReadGroup(field_number, input, submsg))) { + return false; + } + + break; + } + case WireFormatLite::TYPE_GROUP | kRepeatedMask: { + RepeatedPtrFieldBase* field = Raw<RepeatedPtrFieldBase>(msg, offset); + const MessageLite* prototype = + table.aux[field_number].messages.default_message(); + GOOGLE_DCHECK(prototype != nullptr); + + MessageLite* submsg = + MergePartialFromCodedStreamHelper::Add(field, prototype); + + if (PROTOBUF_PREDICT_FALSE( + !WireFormatLite::ReadGroup(field_number, input, submsg))) { + return false; + } + + break; + } + case WireFormatLite::TYPE_MESSAGE: { + MessageLite** submsg_holder = + MutableField<MessageLite*>(msg, has_bits, presence_index, offset); + MessageLite* submsg = *submsg_holder; + + if (submsg == nullptr) { + Arena* const arena = msg->GetArena(); + const MessageLite* prototype = + table.aux[field_number].messages.default_message(); + if (prototype == nullptr) { + prototype = ImplicitWeakMessage::default_instance(); + } + submsg = prototype->New(arena); + *submsg_holder = submsg; + } + + if (PROTOBUF_PREDICT_FALSE( + !WireFormatLite::ReadMessage(input, submsg))) { + return false; + } + + break; + } + // TODO(ckennelly): Adapt ReadMessageNoVirtualNoRecursionDepth and + // manage input->IncrementRecursionDepth() here. + case WireFormatLite::TYPE_MESSAGE | kRepeatedMask: { + RepeatedPtrFieldBase* field = Raw<RepeatedPtrFieldBase>(msg, offset); + const MessageLite* prototype = + table.aux[field_number].messages.default_message(); + if (prototype == nullptr) { + prototype = ImplicitWeakMessage::default_instance(); + } + + MessageLite* submsg = + MergePartialFromCodedStreamHelper::Add(field, prototype); + + if (PROTOBUF_PREDICT_FALSE( + !WireFormatLite::ReadMessage(input, submsg))) { + return false; + } + + break; + } + case WireFormatLite::TYPE_MESSAGE | kOneofMask: { + Arena* const arena = msg->GetArena(); + arc_ui32* oneof_case = Raw<arc_ui32>(msg, table.oneof_case_offset); + MessageLite** submsg_holder = Raw<MessageLite*>(msg, offset); + ResetOneofField<ProcessingType_MESSAGE>( + table, field_number, arena, msg, oneof_case + presence_index, + offset, nullptr); + MessageLite* submsg = *submsg_holder; + + if (PROTOBUF_PREDICT_FALSE( + !WireFormatLite::ReadMessage(input, submsg))) { + return false; + } + + break; + } +#ifdef GOOGLE_PROTOBUF_UTF8_VALIDATION_ENABLED + case TYPE_STRING_INLINED: { + Arena* const arena = msg->GetArena(); + const void* default_ptr = table.aux[field_number].strings.default_ptr; + const char* field_name = table.aux[field_number].strings.field_name; + + if (PROTOBUF_PREDICT_FALSE( + (!HandleString<UnknownFieldHandler, Cardinality_SINGULAR, + true, StringType_INLINED>( + input, msg, arena, has_bits, presence_index, offset, + default_ptr, field_name)))) { + return false; + } + break; + } +#endif // GOOGLE_PROTOBUF_UTF8_VALIDATION_ENABLED + case TYPE_MAP: { + if (PROTOBUF_PREDICT_FALSE(!(*table.aux[field_number].maps.parse_map)( + input, Raw<void>(msg, offset)))) { + return false; + } + break; + } + case 0: { + // Done. + input->SetLastTag(tag); + return true; + } + default: + PROTOBUF_ASSUME(false); + } + } else if (data->packed_wiretype == static_cast<unsigned char>(wire_type)) { + // Non-packable fields have their packed_wiretype masked with + // kNotPackedMask, which is impossible to match here. + GOOGLE_DCHECK(processing_type & kRepeatedMask); + GOOGLE_DCHECK_NE(processing_type, kRepeatedMask); + GOOGLE_DCHECK_EQ(0, processing_type & kOneofMask); + + GOOGLE_DCHECK_NE(TYPE_BYTES_INLINED | kRepeatedMask, processing_type); + GOOGLE_DCHECK_NE(TYPE_STRING_INLINED | kRepeatedMask, processing_type); + + // Mask out kRepeatedMask bit, allowing the jump table to be smaller. + switch (static_cast<WireFormatLite::FieldType>(processing_type ^ + kRepeatedMask)) { +#define HANDLE_PACKED_TYPE(TYPE, CPPTYPE, CPPTYPE_METHOD) \ + case WireFormatLite::TYPE_##TYPE: { \ + RepeatedField<CPPTYPE>* values = Raw<RepeatedField<CPPTYPE>>(msg, offset); \ + if (PROTOBUF_PREDICT_FALSE( \ + (!WireFormatLite::ReadPackedPrimitive< \ + CPPTYPE, WireFormatLite::TYPE_##TYPE>(input, values)))) { \ + return false; \ + } \ + break; \ + } + + HANDLE_PACKED_TYPE(INT32, arc_i32, Int32) + HANDLE_PACKED_TYPE(INT64, arc_i64, Int64) + HANDLE_PACKED_TYPE(SINT32, arc_i32, Int32) + HANDLE_PACKED_TYPE(SINT64, arc_i64, Int64) + HANDLE_PACKED_TYPE(UINT32, arc_ui32, UInt32) + HANDLE_PACKED_TYPE(UINT64, arc_ui64, UInt64) + + HANDLE_PACKED_TYPE(FIXED32, arc_ui32, UInt32) + HANDLE_PACKED_TYPE(FIXED64, arc_ui64, UInt64) + HANDLE_PACKED_TYPE(SFIXED32, arc_i32, Int32) + HANDLE_PACKED_TYPE(SFIXED64, arc_i64, Int64) + + HANDLE_PACKED_TYPE(FLOAT, float, Float) + HANDLE_PACKED_TYPE(DOUBLE, double, Double) + + HANDLE_PACKED_TYPE(BOOL, bool, Bool) +#undef HANDLE_PACKED_TYPE + case WireFormatLite::TYPE_ENUM: { + // To avoid unnecessarily calling MutableUnknownFields (which mutates + // InternalMetadata) when all inputs in the repeated series + // are valid, we implement our own parser rather than call + // WireFormat::ReadPackedEnumPreserveUnknowns. + arc_ui32 length; + if (PROTOBUF_PREDICT_FALSE(!input->ReadVarint32(&length))) { + return false; + } + + AuxiliaryParseTableField::EnumValidator validator = + table.aux[field_number].enums.validator; + RepeatedField<int>* values = Raw<RepeatedField<int>>(msg, offset); + + io::CodedInputStream::Limit limit = input->PushLimit(length); + while (input->BytesUntilLimit() > 0) { + int value; + if (PROTOBUF_PREDICT_FALSE( + (!WireFormatLite::ReadPrimitive< + int, WireFormatLite::TYPE_ENUM>(input, &value)))) { + return false; + } + + if (validator == nullptr || validator(value)) { + values->Add(value); + } else { + // TODO(ckennelly): Consider caching here. + UnknownFieldHandler::Varint(msg, table, tag, value); + } + } + input->PopLimit(limit); + + break; + } + case WireFormatLite::TYPE_STRING: + case WireFormatLite::TYPE_GROUP: + case WireFormatLite::TYPE_MESSAGE: + case WireFormatLite::TYPE_BYTES: + GOOGLE_DCHECK(false); + return false; + default: + PROTOBUF_ASSUME(false); + } + } else { + if (wire_type == WireFormatLite::WIRETYPE_END_GROUP) { + // Must be the end of the message. + input->SetLastTag(tag); + return true; + } + + // check for possible extensions + if (UnknownFieldHandler::ParseExtension(msg, table, input, tag)) { + // successfully parsed + continue; + } + + // process unknown field. + if (PROTOBUF_PREDICT_FALSE( + !UnknownFieldHandler::Skip(msg, table, input, tag))) { + return false; + } + } + } +} // NOLINT(readability/fn_size) + +template <typename UnknownFieldHandler> +bool MergePartialFromCodedStreamImpl(MessageLite* msg, const ParseTable& table, + io::CodedInputStream* input) { + // The main beneficial cutoff values are 1 and 2 byte tags. + // Instantiate calls with the appropriate upper tag range + if (table.max_field_number <= (0x7F >> 3)) { + return MergePartialFromCodedStreamInlined<UnknownFieldHandler, 0x7F>( + msg, table, input); + } else if (table.max_field_number <= (0x3FFF >> 3)) { + return MergePartialFromCodedStreamInlined<UnknownFieldHandler, 0x3FFF>( + msg, table, input); + } else { + return MergePartialFromCodedStreamInlined< + UnknownFieldHandler, std::numeric_limits<arc_ui32>::max()>(msg, table, + input); + } +} + +} // namespace internal +} // namespace protobuf +} // namespace google + +#include <google/protobuf/port_undef.inc> + +#endif // GOOGLE_PROTOBUF_GENERATED_MESSAGE_TABLE_DRIVEN_LITE_H__ diff --git a/contrib/libs/protobuf_old/src/google/protobuf/generated_message_tctable_decl.h b/contrib/libs/protobuf_old/src/google/protobuf/generated_message_tctable_decl.h new file mode 100644 index 0000000000..84c3e715dd --- /dev/null +++ b/contrib/libs/protobuf_old/src/google/protobuf/generated_message_tctable_decl.h @@ -0,0 +1,139 @@ +// 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> + +// Must come last: +#include <google/protobuf/port_def.inc> + +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<arc_ui64>(offset) << 48 | + static_cast<arc_ui64>(hasbit_idx) << 16 | coded_tag) {} + + template <typename TagType = uint16_t> + TagType coded_tag() const { + return static_cast<TagType>(data); + } + uint8_t hasbit_idx() const { return static_cast<uint8_t>(data >> 16); } + uint16_t offset() const { return static_cast<uint16_t>(data >> 48); } + + arc_ui64 data; +}; + +struct TcParseTableBase; + +// TailCallParseFunc is the function pointer type used in the tailcall table. +typedef const char* (*TailCallParseFunc)(PROTOBUF_TC_PARAM_DECL); + +#if defined(_MSC_VER) && !defined(_WIN64) +#pragma warning(push) +// TcParseTableBase is intentionally overaligned on 32 bit targets. +#pragma warning(disable : 4324) +#endif + +// Base class for message-level table with info for the tail-call parser. +struct alignas(arc_ui64) TcParseTableBase { + // Common attributes for message layout: + uint16_t has_bits_offset; + uint16_t extension_offset; + arc_ui32 extension_range_low; + arc_ui32 extension_range_high; + uint8_t fast_idx_mask; + uint8_t reserved; + uint16_t num_fields; + 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 FastFieldEntry { + // Target function for dispatch: + TailCallParseFunc target; + // Field data used during parse: + TcFieldData bits; + }; + // There is always at least one table entry. + const FastFieldEntry* fast_entry(size_t idx) const { + return reinterpret_cast<const FastFieldEntry*>(this + 1) + idx; + } +}; + +#if defined(_MSC_VER) && !defined(_WIN64) +#pragma warning(pop) +#endif + +static_assert(sizeof(TcParseTableBase::FastFieldEntry) <= 16, + "Field entry is too big."); + +template <size_t kFastTableSizeLog2> +struct TcParseTable { + TcParseTableBase 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. + TcParseTableBase::FastFieldEntry entries[(1 << kFastTableSizeLog2)]; +}; + +static_assert(std::is_standard_layout<TcParseTable<1>>::value, + "TcParseTable must be standard layout."); + +static_assert(offsetof(TcParseTable<1>, entries) == sizeof(TcParseTableBase), + "Table entries must be laid out after TcParseTableBase."); + +} // namespace internal +} // namespace protobuf +} // namespace google + +#include <google/protobuf/port_undef.inc> + +#endif // GOOGLE_PROTOBUF_GENERATED_MESSAGE_TCTABLE_DECL_H__ diff --git a/contrib/libs/protobuf_old/src/google/protobuf/generated_message_tctable_full.cc b/contrib/libs/protobuf_old/src/google/protobuf/generated_message_tctable_full.cc new file mode 100644 index 0000000000..44dcddc796 --- /dev/null +++ b/contrib/libs/protobuf_old/src/google/protobuf/generated_message_tctable_full.cc @@ -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* TcParser::GenericFallback(PROTOBUF_TC_PARAM_DECL) { + return GenericFallbackImpl<Message, UnknownFieldSet>(PROTOBUF_TC_PARAM_PASS); +} + +} // namespace internal +} // namespace protobuf +} // namespace google diff --git a/contrib/libs/protobuf_old/src/google/protobuf/generated_message_tctable_impl.h b/contrib/libs/protobuf_old/src/google/protobuf/generated_message_tctable_impl.h new file mode 100644 index 0000000000..11c5c8660c --- /dev/null +++ b/contrib/libs/protobuf_old/src/google/protobuf/generated_message_tctable_impl.h @@ -0,0 +1,302 @@ +// 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, it is +// defined in port_def.inc. +// +// 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. + +// PROTOBUF_TC_PARAM_PASS passes values to match PROTOBUF_TC_PARAM_DECL. +#define PROTOBUF_TC_PARAM_PASS msg, ptr, ctx, table, hasbits, data + +// PROTOBUF_TC_PARSE_* decide which function is used to parse message-typed +// fields. The guard macros are defined in port_def.inc. +#if PROTOBUF_TC_STATIC_PARSE_SINGULAR1 +#define PROTOBUF_TC_PARSE_SINGULAR1(MESSAGE) MESSAGE::Tct_ParseS1 +#else +#define PROTOBUF_TC_PARSE_SINGULAR1(MESSAGE) \ + ::google::protobuf::internal::TcParser::SingularParseMessage<MESSAGE, uint8_t> +#endif // PROTOBUF_TC_STATIC_PARSE_SINGULAR1 + +#if PROTOBUF_TC_STATIC_PARSE_SINGULAR2 +#define PROTOBUF_TC_PARSE_SINGULAR2(MESSAGE) MESSAGE::Tct_ParseS2 +#else +#define PROTOBUF_TC_PARSE_SINGULAR2(MESSAGE) \ + ::google::protobuf::internal::TcParser::SingularParseMessage<MESSAGE, uint16_t> +#endif // PROTOBUF_TC_STATIC_PARSE_SINGULAR2 + +#if PROTOBUF_TC_STATIC_PARSE_REPEATED1 +#define PROTOBUF_TC_PARSE_REPEATED1(MESSAGE) MESSAGE::Tct_ParseR1 +#else +#define PROTOBUF_TC_PARSE_REPEATED1(MESSAGE) \ + ::google::protobuf::internal::TcParser::RepeatedParseMessage<MESSAGE, uint8_t> +#endif // PROTOBUF_TC_STATIC_PARSE_REPEATED1 + +#if PROTOBUF_TC_STATIC_PARSE_REPEATED2 +#define PROTOBUF_TC_PARSE_REPEATED2(MESSAGE) MESSAGE::Tct_ParseR2 +#else +#define PROTOBUF_TC_PARSE_REPEATED2(MESSAGE) \ + ::google::protobuf::internal::TcParser::RepeatedParseMessage<MESSAGE, uint16_t> +#endif // PROTOBUF_TC_STATIC_PARSE_REPEATED2 + +#ifndef NDEBUG +template <size_t align> +#ifndef _MSC_VER +[[noreturn]] +#endif +void AlignFail(uintptr_t address) { + GOOGLE_LOG(FATAL) << "Unaligned (" << align << ") access at " << address; +} + +extern template void AlignFail<4>(uintptr_t); +extern template void AlignFail<8>(uintptr_t); +#endif + +// TcParser implements most of the parsing logic for tailcall tables. +class TcParser final { + public: + static const char* GenericFallback(PROTOBUF_TC_PARAM_DECL); + static const char* GenericFallbackLite(PROTOBUF_TC_PARAM_DECL); + + // 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); + const size_t idx = coded_tag & table->fast_idx_mask; + PROTOBUF_ASSUME((idx & 7) == 0); + auto* fast_entry = table->fast_entry(idx >> 3); + data = fast_entry->bits; + data.data ^= coded_tag; + PROTOBUF_MUSTTAIL return fast_entry->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* ToTagDispatch(PROTOBUF_TC_PARAM_DECL) { + constexpr bool always_return = !PROTOBUF_TAILCALL; + if (always_return || !ctx->DataAvailable(ptr)) { + PROTOBUF_MUSTTAIL return ToParseLoop(PROTOBUF_TC_PARAM_PASS); + } + PROTOBUF_MUSTTAIL return TagDispatch(PROTOBUF_TC_PARAM_PASS); + } + + static const char* ParseLoop(MessageLite* msg, const char* ptr, + ParseContext* ctx, + const TcParseTableBase* table) { + ScopedArenaSwap saved(msg, ctx); + const arc_ui32 has_bits_offset = table->has_bits_offset; + while (!ctx->Done(&ptr)) { + arc_ui64 hasbits = 0; + if (has_bits_offset) hasbits = RefAt<arc_ui32>(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 FieldType, typename TagType> + PROTOBUF_NOINLINE static const char* SingularParseMessage( + PROTOBUF_TC_PARAM_DECL) { + if (PROTOBUF_PREDICT_FALSE(data.coded_tag<TagType>() != 0)) { + return table->fallback(PROTOBUF_TC_PARAM_PASS); + } + ptr += sizeof(TagType); + hasbits |= (arc_ui64{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(data.coded_tag<TagType>() != 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* SingularFixed(PROTOBUF_TC_PARAM_DECL); + 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); + + enum VarintDecode { kNoConversion = 0, kZigZag = 1 }; + template <typename FieldType, typename TagType, VarintDecode zigzag> + static const char* SingularVarint(PROTOBUF_TC_PARAM_DECL); + template <typename FieldType, typename TagType, VarintDecode zigzag> + static const char* RepeatedVarint(PROTOBUF_TC_PARAM_DECL); + template <typename FieldType, typename TagType, VarintDecode zigzag> + static const char* PackedVarint(PROTOBUF_TC_PARAM_DECL); + + enum Utf8Type { kNoUtf8 = 0, kUtf8 = 1, kUtf8ValidateOnly = 2 }; + template <typename TagType, Utf8Type utf8> + static const char* SingularString(PROTOBUF_TC_PARAM_DECL); + template <typename TagType, Utf8Type utf8> + static const char* RepeatedString(PROTOBUF_TC_PARAM_DECL); + + template <typename T> + static inline T& RefAt(void* x, size_t offset) { + T* target = reinterpret_cast<T*>(static_cast<char*>(x) + offset); +#ifndef NDEBUG + if (PROTOBUF_PREDICT_FALSE( + reinterpret_cast<uintptr_t>(target) % alignof(T) != 0)) { + AlignFail<alignof(T)>(reinterpret_cast<uintptr_t>(target)); + } +#endif + return *target; + } + + static inline PROTOBUF_ALWAYS_INLINE void SyncHasbits( + MessageLite* msg, arc_ui64 hasbits, const TcParseTableBase* table) { + const arc_ui32 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<arc_ui32>(msg, has_bits_offset) = static_cast<arc_ui32>(hasbits); + } + } + + protected: + static inline PROTOBUF_ALWAYS_INLINE const char* ToParseLoop( + PROTOBUF_TC_PARAM_DECL) { + (void)data; + (void)ctx; + SyncHasbits(msg, hasbits, table); + return ptr; + } + + static inline PROTOBUF_ALWAYS_INLINE const char* Error( + PROTOBUF_TC_PARAM_DECL) { + (void)data; + (void)ctx; + (void)ptr; + 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); + arc_ui32 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; + } + (void)data; + arc_ui32 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_ + } +}; + +// 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__ diff --git a/contrib/libs/protobuf_old/src/google/protobuf/generated_message_tctable_impl.inc b/contrib/libs/protobuf_old/src/google/protobuf/generated_message_tctable_impl.inc new file mode 100644 index 0000000000..a02e65e2c0 --- /dev/null +++ b/contrib/libs/protobuf_old/src/google/protobuf/generated_message_tctable_impl.inc @@ -0,0 +1,92 @@ +// 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 +#define PROTOBUF_TCT_EXTERN +#else +#define PROTOBUF_TCT_EXTERN extern +#endif +PROTOBUF_TCT_EXTERN template const char* TcParser::SingularFixed<arc_ui64, uint8_t>(PROTOBUF_TC_PARAM_DECL); +PROTOBUF_TCT_EXTERN template const char* TcParser::RepeatedFixed<arc_ui64, uint8_t>(PROTOBUF_TC_PARAM_DECL); +PROTOBUF_TCT_EXTERN template const char* TcParser::PackedFixed<arc_ui64, uint8_t>(PROTOBUF_TC_PARAM_DECL); +PROTOBUF_TCT_EXTERN template const char* TcParser::SingularFixed<arc_ui32, uint8_t>(PROTOBUF_TC_PARAM_DECL); +PROTOBUF_TCT_EXTERN template const char* TcParser::RepeatedFixed<arc_ui32, uint8_t>(PROTOBUF_TC_PARAM_DECL); +PROTOBUF_TCT_EXTERN template const char* TcParser::PackedFixed<arc_ui32, uint8_t>(PROTOBUF_TC_PARAM_DECL); +PROTOBUF_TCT_EXTERN template const char* TcParser::SingularVarint<arc_ui64, uint8_t, ::PROTOBUF_NAMESPACE_ID::internal::TcParser::kNoConversion>(PROTOBUF_TC_PARAM_DECL); +PROTOBUF_TCT_EXTERN template const char* TcParser::RepeatedVarint<arc_ui64, uint8_t, ::PROTOBUF_NAMESPACE_ID::internal::TcParser::kNoConversion>(PROTOBUF_TC_PARAM_DECL); +PROTOBUF_TCT_EXTERN template const char* TcParser::PackedVarint<arc_ui64, uint8_t, ::PROTOBUF_NAMESPACE_ID::internal::TcParser::kNoConversion>(PROTOBUF_TC_PARAM_DECL); +PROTOBUF_TCT_EXTERN template const char* TcParser::SingularVarint<arc_ui32, uint8_t, ::PROTOBUF_NAMESPACE_ID::internal::TcParser::kNoConversion>(PROTOBUF_TC_PARAM_DECL); +PROTOBUF_TCT_EXTERN template const char* TcParser::RepeatedVarint<arc_ui32, uint8_t, ::PROTOBUF_NAMESPACE_ID::internal::TcParser::kNoConversion>(PROTOBUF_TC_PARAM_DECL); +PROTOBUF_TCT_EXTERN template const char* TcParser::PackedVarint<arc_ui32, uint8_t, ::PROTOBUF_NAMESPACE_ID::internal::TcParser::kNoConversion>(PROTOBUF_TC_PARAM_DECL); +PROTOBUF_TCT_EXTERN template const char* TcParser::SingularVarint<arc_i64, uint8_t, ::PROTOBUF_NAMESPACE_ID::internal::TcParser::kZigZag>(PROTOBUF_TC_PARAM_DECL); +PROTOBUF_TCT_EXTERN template const char* TcParser::RepeatedVarint<arc_i64, uint8_t, ::PROTOBUF_NAMESPACE_ID::internal::TcParser::kZigZag>(PROTOBUF_TC_PARAM_DECL); +PROTOBUF_TCT_EXTERN template const char* TcParser::PackedVarint<arc_i64, uint8_t, ::PROTOBUF_NAMESPACE_ID::internal::TcParser::kZigZag>(PROTOBUF_TC_PARAM_DECL); +PROTOBUF_TCT_EXTERN template const char* TcParser::SingularVarint<arc_i32, uint8_t, ::PROTOBUF_NAMESPACE_ID::internal::TcParser::kZigZag>(PROTOBUF_TC_PARAM_DECL); +PROTOBUF_TCT_EXTERN template const char* TcParser::RepeatedVarint<arc_i32, uint8_t, ::PROTOBUF_NAMESPACE_ID::internal::TcParser::kZigZag>(PROTOBUF_TC_PARAM_DECL); +PROTOBUF_TCT_EXTERN template const char* TcParser::PackedVarint<arc_i32, uint8_t, ::PROTOBUF_NAMESPACE_ID::internal::TcParser::kZigZag>(PROTOBUF_TC_PARAM_DECL); +PROTOBUF_TCT_EXTERN template const char* TcParser::SingularVarint<bool, uint8_t, ::PROTOBUF_NAMESPACE_ID::internal::TcParser::kNoConversion>(PROTOBUF_TC_PARAM_DECL); +PROTOBUF_TCT_EXTERN template const char* TcParser::RepeatedVarint<bool, uint8_t, ::PROTOBUF_NAMESPACE_ID::internal::TcParser::kNoConversion>(PROTOBUF_TC_PARAM_DECL); +PROTOBUF_TCT_EXTERN template const char* TcParser::PackedVarint<bool, uint8_t, ::PROTOBUF_NAMESPACE_ID::internal::TcParser::kNoConversion>(PROTOBUF_TC_PARAM_DECL); +PROTOBUF_TCT_EXTERN template const char* TcParser::SingularString<uint8_t, ::PROTOBUF_NAMESPACE_ID::internal::TcParser::kNoUtf8>(PROTOBUF_TC_PARAM_DECL); +PROTOBUF_TCT_EXTERN template const char* TcParser::RepeatedString<uint8_t, ::PROTOBUF_NAMESPACE_ID::internal::TcParser::kNoUtf8>(PROTOBUF_TC_PARAM_DECL); +PROTOBUF_TCT_EXTERN template const char* TcParser::SingularString<uint8_t, ::PROTOBUF_NAMESPACE_ID::internal::TcParser::kUtf8>(PROTOBUF_TC_PARAM_DECL); +PROTOBUF_TCT_EXTERN template const char* TcParser::RepeatedString<uint8_t, ::PROTOBUF_NAMESPACE_ID::internal::TcParser::kUtf8>(PROTOBUF_TC_PARAM_DECL); +PROTOBUF_TCT_EXTERN template const char* TcParser::SingularString<uint8_t, ::PROTOBUF_NAMESPACE_ID::internal::TcParser::kUtf8ValidateOnly>(PROTOBUF_TC_PARAM_DECL); +PROTOBUF_TCT_EXTERN template const char* TcParser::RepeatedString<uint8_t, ::PROTOBUF_NAMESPACE_ID::internal::TcParser::kUtf8ValidateOnly>(PROTOBUF_TC_PARAM_DECL); +PROTOBUF_TCT_EXTERN template const char* TcParser::SingularFixed<arc_ui64, uint16_t>(PROTOBUF_TC_PARAM_DECL); +PROTOBUF_TCT_EXTERN template const char* TcParser::RepeatedFixed<arc_ui64, uint16_t>(PROTOBUF_TC_PARAM_DECL); +PROTOBUF_TCT_EXTERN template const char* TcParser::PackedFixed<arc_ui64, uint16_t>(PROTOBUF_TC_PARAM_DECL); +PROTOBUF_TCT_EXTERN template const char* TcParser::SingularFixed<arc_ui32, uint16_t>(PROTOBUF_TC_PARAM_DECL); +PROTOBUF_TCT_EXTERN template const char* TcParser::RepeatedFixed<arc_ui32, uint16_t>(PROTOBUF_TC_PARAM_DECL); +PROTOBUF_TCT_EXTERN template const char* TcParser::PackedFixed<arc_ui32, uint16_t>(PROTOBUF_TC_PARAM_DECL); +PROTOBUF_TCT_EXTERN template const char* TcParser::SingularVarint<arc_ui64, uint16_t, ::PROTOBUF_NAMESPACE_ID::internal::TcParser::kNoConversion>(PROTOBUF_TC_PARAM_DECL); +PROTOBUF_TCT_EXTERN template const char* TcParser::RepeatedVarint<arc_ui64, uint16_t, ::PROTOBUF_NAMESPACE_ID::internal::TcParser::kNoConversion>(PROTOBUF_TC_PARAM_DECL); +PROTOBUF_TCT_EXTERN template const char* TcParser::PackedVarint<arc_ui64, uint16_t, ::PROTOBUF_NAMESPACE_ID::internal::TcParser::kNoConversion>(PROTOBUF_TC_PARAM_DECL); +PROTOBUF_TCT_EXTERN template const char* TcParser::SingularVarint<arc_ui32, uint16_t, ::PROTOBUF_NAMESPACE_ID::internal::TcParser::kNoConversion>(PROTOBUF_TC_PARAM_DECL); +PROTOBUF_TCT_EXTERN template const char* TcParser::RepeatedVarint<arc_ui32, uint16_t, ::PROTOBUF_NAMESPACE_ID::internal::TcParser::kNoConversion>(PROTOBUF_TC_PARAM_DECL); +PROTOBUF_TCT_EXTERN template const char* TcParser::PackedVarint<arc_ui32, uint16_t, ::PROTOBUF_NAMESPACE_ID::internal::TcParser::kNoConversion>(PROTOBUF_TC_PARAM_DECL); +PROTOBUF_TCT_EXTERN template const char* TcParser::SingularVarint<arc_i64, uint16_t, ::PROTOBUF_NAMESPACE_ID::internal::TcParser::kZigZag>(PROTOBUF_TC_PARAM_DECL); +PROTOBUF_TCT_EXTERN template const char* TcParser::RepeatedVarint<arc_i64, uint16_t, ::PROTOBUF_NAMESPACE_ID::internal::TcParser::kZigZag>(PROTOBUF_TC_PARAM_DECL); +PROTOBUF_TCT_EXTERN template const char* TcParser::PackedVarint<arc_i64, uint16_t, ::PROTOBUF_NAMESPACE_ID::internal::TcParser::kZigZag>(PROTOBUF_TC_PARAM_DECL); +PROTOBUF_TCT_EXTERN template const char* TcParser::SingularVarint<arc_i32, uint16_t, ::PROTOBUF_NAMESPACE_ID::internal::TcParser::kZigZag>(PROTOBUF_TC_PARAM_DECL); +PROTOBUF_TCT_EXTERN template const char* TcParser::RepeatedVarint<arc_i32, uint16_t, ::PROTOBUF_NAMESPACE_ID::internal::TcParser::kZigZag>(PROTOBUF_TC_PARAM_DECL); +PROTOBUF_TCT_EXTERN template const char* TcParser::PackedVarint<arc_i32, uint16_t, ::PROTOBUF_NAMESPACE_ID::internal::TcParser::kZigZag>(PROTOBUF_TC_PARAM_DECL); +PROTOBUF_TCT_EXTERN template const char* TcParser::SingularVarint<bool, uint16_t, ::PROTOBUF_NAMESPACE_ID::internal::TcParser::kNoConversion>(PROTOBUF_TC_PARAM_DECL); +PROTOBUF_TCT_EXTERN template const char* TcParser::RepeatedVarint<bool, uint16_t, ::PROTOBUF_NAMESPACE_ID::internal::TcParser::kNoConversion>(PROTOBUF_TC_PARAM_DECL); +PROTOBUF_TCT_EXTERN template const char* TcParser::PackedVarint<bool, uint16_t, ::PROTOBUF_NAMESPACE_ID::internal::TcParser::kNoConversion>(PROTOBUF_TC_PARAM_DECL); +PROTOBUF_TCT_EXTERN template const char* TcParser::SingularString<uint16_t, ::PROTOBUF_NAMESPACE_ID::internal::TcParser::kNoUtf8>(PROTOBUF_TC_PARAM_DECL); +PROTOBUF_TCT_EXTERN template const char* TcParser::RepeatedString<uint16_t, ::PROTOBUF_NAMESPACE_ID::internal::TcParser::kNoUtf8>(PROTOBUF_TC_PARAM_DECL); +PROTOBUF_TCT_EXTERN template const char* TcParser::SingularString<uint16_t, ::PROTOBUF_NAMESPACE_ID::internal::TcParser::kUtf8>(PROTOBUF_TC_PARAM_DECL); +PROTOBUF_TCT_EXTERN template const char* TcParser::RepeatedString<uint16_t, ::PROTOBUF_NAMESPACE_ID::internal::TcParser::kUtf8>(PROTOBUF_TC_PARAM_DECL); +PROTOBUF_TCT_EXTERN template const char* TcParser::SingularString<uint16_t, ::PROTOBUF_NAMESPACE_ID::internal::TcParser::kUtf8ValidateOnly>(PROTOBUF_TC_PARAM_DECL); +PROTOBUF_TCT_EXTERN template const char* TcParser::RepeatedString<uint16_t, ::PROTOBUF_NAMESPACE_ID::internal::TcParser::kUtf8ValidateOnly>(PROTOBUF_TC_PARAM_DECL); +#undef PROTOBUF_TCT_EXTERN +// clang-format on diff --git a/contrib/libs/protobuf_old/src/google/protobuf/generated_message_tctable_lite.cc b/contrib/libs/protobuf_old/src/google/protobuf/generated_message_tctable_lite.cc new file mode 100644 index 0000000000..35071abd76 --- /dev/null +++ b/contrib/libs/protobuf_old/src/google/protobuf/generated_message_tctable_lite.cc @@ -0,0 +1,456 @@ +// 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 { + +#ifndef NDEBUG +template void AlignFail<4>(uintptr_t); +template void AlignFail<8>(uintptr_t); +#endif + +const char* TcParser::GenericFallbackLite(PROTOBUF_TC_PARAM_DECL) { + return GenericFallbackImpl<MessageLite, TProtoStringType>(PROTOBUF_TC_PARAM_PASS); +} + +namespace { + +// Offset returns the address `offset` bytes after `base`. +inline void* Offset(void* base, arc_ui32 offset) { + return static_cast<uint8_t*>(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 <typename LayoutType, typename TagType> +const char* TcParser::SingularFixed(PROTOBUF_TC_PARAM_DECL) { + if (PROTOBUF_PREDICT_FALSE(data.coded_tag<TagType>() != 0)) { + return table->fallback(PROTOBUF_TC_PARAM_PASS); + } + ptr += sizeof(TagType); // Consume tag + hasbits |= (arc_ui64{1} << data.hasbit_idx()); + std::memcpy(Offset(msg, data.offset()), ptr, sizeof(LayoutType)); + ptr += sizeof(LayoutType); + PROTOBUF_MUSTTAIL return ToTagDispatch(PROTOBUF_TC_PARAM_PASS); +} + +template <typename LayoutType, typename TagType> +const char* TcParser::RepeatedFixed(PROTOBUF_TC_PARAM_DECL) { + if (PROTOBUF_PREDICT_FALSE(data.coded_tag<TagType>() != 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 (data.coded_tag<TagType>() == 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 ToParseLoop(PROTOBUF_TC_PARAM_PASS); +} + +template <typename LayoutType, typename TagType> +const char* TcParser::PackedFixed(PROTOBUF_TC_PARAM_DECL) { + if (PROTOBUF_PREDICT_FALSE(data.coded_tag<TagType>() != 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 (data.coded_tag<TagType>() == 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)); +} + +////////////////////////////////////////////////////////////////////////////// +// Varint fields +////////////////////////////////////////////////////////////////////////////// + +namespace { + +inline PROTOBUF_ALWAYS_INLINE std::pair<const char*, arc_ui64> +Parse64FallbackPair(const char* p, arc_i64 res1) { + auto ptr = reinterpret_cast<const int8_t*>(p); + + // The algorithm relies on sign extension for each byte to set all high bits + // when the varint continues. It also relies on asserting all of the lower + // bits for each successive byte read. This allows the result to be aggregated + // using a bitwise AND. For example: + // + // 8 1 64 57 ... 24 17 16 9 8 1 + // ptr[0] = 1aaa aaaa ; res1 = 1111 1111 ... 1111 1111 1111 1111 1aaa aaaa + // ptr[1] = 1bbb bbbb ; res2 = 1111 1111 ... 1111 1111 11bb bbbb b111 1111 + // ptr[2] = 1ccc cccc ; res3 = 0000 0000 ... 000c cccc cc11 1111 1111 1111 + // --------------------------------------------- + // res1 & res2 & res3 = 0000 0000 ... 000c cccc ccbb bbbb baaa aaaa + // + // On x86-64, a shld from a single register filled with enough 1s in the high + // bits can accomplish all this in one instruction. It so happens that res1 + // has 57 high bits of ones, which is enough for the largest shift done. + GOOGLE_DCHECK_EQ(res1 >> 7, -1); + arc_ui64 ones = res1; // save the high 1 bits from res1 (input to SHLD) + arc_ui64 byte; // the "next" 7-bit chunk, shifted (result from SHLD) + arc_i64 res2, res3; // accumulated result chunks +#define SHLD(n) byte = ((byte << (n * 7)) | (ones >> (64 - (n * 7)))) + + int sign_bit; +#if defined(__GCC_ASM_FLAG_OUTPUTS__) && defined(__x86_64__) + // For the first two rounds (ptr[1] and ptr[2]), micro benchmarks show a + // substantial improvement from capturing the sign from the condition code + // register on x86-64. +#define SHLD_SIGN(n) \ + asm("shldq %3, %2, %1" \ + : "=@ccs"(sign_bit), "+r"(byte) \ + : "r"(ones), "i"(n * 7)) +#else + // Generic fallback: +#define SHLD_SIGN(n) \ + do { \ + SHLD(n); \ + sign_bit = static_cast<arc_i64>(byte) < 0; \ + } while (0) +#endif + + byte = ptr[1]; + SHLD_SIGN(1); + res2 = byte; + if (!sign_bit) goto done2; + byte = ptr[2]; + SHLD_SIGN(2); + res3 = byte; + if (!sign_bit) goto done3; + +#undef SHLD_SIGN + + // For the remainder of the chunks, check the sign of the AND result. + byte = ptr[3]; + SHLD(3); + res1 &= byte; + if (res1 >= 0) goto done4; + byte = ptr[4]; + SHLD(4); + res2 &= byte; + if (res2 >= 0) goto done5; + byte = ptr[5]; + SHLD(5); + res3 &= byte; + if (res3 >= 0) goto done6; + byte = ptr[6]; + SHLD(6); + res1 &= byte; + if (res1 >= 0) goto done7; + byte = ptr[7]; + SHLD(7); + res2 &= byte; + if (res2 >= 0) goto done8; + byte = ptr[8]; + SHLD(8); + res3 &= byte; + if (res3 >= 0) goto done9; + +#undef SHLD + + // For valid 64bit varints, the 10th byte/ptr[9] should be exactly 1. In this + // case, the continuation bit of ptr[8] already set the top bit of res3 + // correctly, so all we have to do is check that the expected case is true. + byte = ptr[9]; + if (PROTOBUF_PREDICT_TRUE(byte == 1)) goto done10; + + // A value of 0, however, represents an over-serialized varint. This case + // should not happen, but if does (say, due to a nonconforming serializer), + // deassert the continuation bit that came from ptr[8]. + if (byte == 0) { + res3 ^= static_cast<arc_ui64>(1) << 63; + goto done10; + } + + // If the 10th byte/ptr[9] itself has any other value, then it is too big to + // fit in 64 bits. If the continue bit is set, it is an unterminated varint. + return {nullptr, 0}; + +#define DONE(n) done##n : return {p + n, res1 & res2 & res3}; +done2: + return {p + 2, res1 & res2}; + DONE(3) + DONE(4) + DONE(5) + DONE(6) + DONE(7) + DONE(8) + DONE(9) + DONE(10) +#undef DONE +} + +inline PROTOBUF_ALWAYS_INLINE const char* ParseVarint(const char* p, + arc_ui64* value) { + arc_i64 byte = static_cast<int8_t>(*p); + if (PROTOBUF_PREDICT_TRUE(byte >= 0)) { + *value = byte; + return p + 1; + } else { + auto tmp = Parse64FallbackPair(p, byte); + if (PROTOBUF_PREDICT_TRUE(tmp.first)) *value = tmp.second; + return tmp.first; + } +} + +template <typename FieldType, + TcParser::VarintDecode = TcParser::VarintDecode::kNoConversion> +FieldType ZigZagDecodeHelper(arc_ui64 value) { + return static_cast<FieldType>(value); +} + +template <> +arc_i32 ZigZagDecodeHelper<arc_i32, TcParser::VarintDecode::kZigZag>( + arc_ui64 value) { + return WireFormatLite::ZigZagDecode32(value); +} + +template <> +arc_i64 ZigZagDecodeHelper<arc_i64, TcParser::VarintDecode::kZigZag>( + arc_ui64 value) { + return WireFormatLite::ZigZagDecode64(value); +} + +} // namespace + +template <typename FieldType, typename TagType, TcParser::VarintDecode zigzag> +const char* TcParser::SingularVarint(PROTOBUF_TC_PARAM_DECL) { + if (PROTOBUF_PREDICT_FALSE(data.coded_tag<TagType>() != 0)) { + return table->fallback(PROTOBUF_TC_PARAM_PASS); + } + ptr += sizeof(TagType); // Consume tag + hasbits |= (arc_ui64{1} << data.hasbit_idx()); + arc_ui64 tmp; + ptr = ParseVarint(ptr, &tmp); + if (ptr == nullptr) { + return Error(PROTOBUF_TC_PARAM_PASS); + } + RefAt<FieldType>(msg, data.offset()) = + ZigZagDecodeHelper<FieldType, zigzag>(tmp); + PROTOBUF_MUSTTAIL return ToTagDispatch(PROTOBUF_TC_PARAM_PASS); +} + +template <typename FieldType, typename TagType, TcParser::VarintDecode zigzag> +PROTOBUF_NOINLINE const char* TcParser::RepeatedVarint(PROTOBUF_TC_PARAM_DECL) { + if (PROTOBUF_PREDICT_FALSE(data.coded_tag<TagType>() != 0)) { + // Try parsing as non-packed repeated: + InvertPacked<WireFormatLite::WIRETYPE_VARINT>(data); + if (data.coded_tag<TagType>() == 0) { + return PackedVarint<FieldType, TagType, zigzag>(PROTOBUF_TC_PARAM_PASS); + } else { + return table->fallback(PROTOBUF_TC_PARAM_PASS); + } + } + auto& field = RefAt<RepeatedField<FieldType>>(msg, data.offset()); + auto expected_tag = UnalignedLoad<TagType>(ptr); + do { + ptr += sizeof(TagType); + arc_ui64 tmp; + ptr = ParseVarint(ptr, &tmp); + if (ptr == nullptr) { + return Error(PROTOBUF_TC_PARAM_PASS); + } + field.Add(ZigZagDecodeHelper<FieldType, zigzag>(tmp)); + if (!ctx->DataAvailable(ptr)) { + break; + } + } while (UnalignedLoad<TagType>(ptr) == expected_tag); + return ToParseLoop(PROTOBUF_TC_PARAM_PASS); +} + +template <typename FieldType, typename TagType, TcParser::VarintDecode zigzag> +PROTOBUF_NOINLINE const char* TcParser::PackedVarint(PROTOBUF_TC_PARAM_DECL) { + if (PROTOBUF_PREDICT_FALSE(data.coded_tag<TagType>() != 0)) { + InvertPacked<WireFormatLite::WIRETYPE_VARINT>(data); + if (data.coded_tag<TagType>() == 0) { + return RepeatedVarint<FieldType, TagType, zigzag>(PROTOBUF_TC_PARAM_PASS); + } else { + return table->fallback(PROTOBUF_TC_PARAM_PASS); + } + } + ptr += sizeof(TagType); + // Since ctx->ReadPackedVarint does not use TailCall or Return, sync any + // pending hasbits now: + SyncHasbits(msg, hasbits, table); + auto* field = &RefAt<RepeatedField<FieldType>>(msg, data.offset()); + return ctx->ReadPackedVarint(ptr, [field](arc_ui64 varint) { + FieldType val; + if (zigzag) { + if (sizeof(FieldType) == 8) { + val = WireFormatLite::ZigZagDecode64(varint); + } else { + val = WireFormatLite::ZigZagDecode32(varint); + } + } else { + val = varint; + } + field->Add(val); + }); +} + +////////////////////////////////////////////////////////////////////////////// +// String/bytes fields +////////////////////////////////////////////////////////////////////////////// + +// Defined in wire_format_lite.cc +void PrintUTF8ErrorLog(const char* field_name, const char* operation_str, + bool emit_stacktrace); + +namespace { + +PROTOBUF_NOINLINE +const char* SingularStringParserFallback(ArenaStringPtr* s, const char* ptr, + EpsCopyInputStream* stream) { + int size = ReadSize(&ptr); + if (!ptr) return nullptr; + return stream->ReadString( + ptr, size, s->MutableNoArenaNoDefault(&GetEmptyStringAlreadyInited())); +} + +} // namespace + +template <typename TagType, TcParser::Utf8Type utf8> +const char* TcParser::SingularString(PROTOBUF_TC_PARAM_DECL) { + if (PROTOBUF_PREDICT_FALSE(data.coded_tag<TagType>() != 0)) { + return table->fallback(PROTOBUF_TC_PARAM_PASS); + } + ptr += sizeof(TagType); + hasbits |= (arc_ui64{1} << data.hasbit_idx()); + auto& field = RefAt<ArenaStringPtr>(msg, data.offset()); + auto arena = ctx->data().arena; + if (arena) { + ptr = ctx->ReadArenaString(ptr, &field, arena); + } else { + ptr = SingularStringParserFallback(&field, ptr, ctx); + } + if (ptr == nullptr) return Error(PROTOBUF_TC_PARAM_PASS); + switch (utf8) { + case kNoUtf8: +#ifdef NDEBUG + case kUtf8ValidateOnly: +#endif + return ToParseLoop(PROTOBUF_TC_PARAM_PASS); + default: + if (PROTOBUF_PREDICT_TRUE(IsStructurallyValidUTF8(field.Get()))) { + return ToParseLoop(PROTOBUF_TC_PARAM_PASS); + } + PrintUTF8ErrorLog("unknown", "parsing", false); + return utf8 == kUtf8 ? Error(PROTOBUF_TC_PARAM_PASS) + : ToParseLoop(PROTOBUF_TC_PARAM_PASS); + } +} + +template <typename TagType, TcParser::Utf8Type utf8> +const char* TcParser::RepeatedString(PROTOBUF_TC_PARAM_DECL) { + if (PROTOBUF_PREDICT_FALSE(data.coded_tag<TagType>() != 0)) { + return table->fallback(PROTOBUF_TC_PARAM_PASS); + } + auto expected_tag = UnalignedLoad<TagType>(ptr); + auto& field = RefAt<RepeatedPtrField<TProtoStringType>>(msg, data.offset()); + do { + ptr += sizeof(TagType); + TProtoStringType* str = field.Add(); + ptr = InlineGreedyStringParser(str, ptr, ctx); + if (ptr == nullptr) { + return Error(PROTOBUF_TC_PARAM_PASS); + } + if (utf8 != kNoUtf8) { + if (PROTOBUF_PREDICT_FALSE(!IsStructurallyValidUTF8(*str))) { + PrintUTF8ErrorLog("unknown", "parsing", false); + if (utf8 == kUtf8) return Error(PROTOBUF_TC_PARAM_PASS); + } + } + if (!ctx->DataAvailable(ptr)) break; + } while (UnalignedLoad<TagType>(ptr) == expected_tag); + return ToParseLoop(PROTOBUF_TC_PARAM_PASS); +} + +#define PROTOBUF_TCT_SOURCE +#include <google/protobuf/generated_message_tctable_impl.inc> + +} // namespace internal +} // namespace protobuf +} // namespace google diff --git a/contrib/libs/protobuf_old/src/google/protobuf/generated_message_util.cc b/contrib/libs/protobuf_old/src/google/protobuf/generated_message_util.cc new file mode 100644 index 0000000000..8db97d66ae --- /dev/null +++ b/contrib/libs/protobuf_old/src/google/protobuf/generated_message_util.cc @@ -0,0 +1,779 @@ +// 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: kenton@google.com (Kenton Varda) +// Based on original Protocol Buffers design by +// Sanjay Ghemawat, Jeff Dean, and others. + +#include <google/protobuf/generated_message_util.h> + +#include <atomic> +#include <limits> +#include <vector> + +#include <google/protobuf/io/coded_stream.h> +#include <google/protobuf/io/zero_copy_stream_impl_lite.h> +#include <google/protobuf/arenastring.h> +#include <google/protobuf/extension_set.h> +#include <google/protobuf/generated_message_table_driven.h> +#include <google/protobuf/message_lite.h> +#include <google/protobuf/metadata_lite.h> +#include <google/protobuf/repeated_field.h> +#include <google/protobuf/wire_format_lite.h> + +// Must be included last +#include <google/protobuf/port_def.inc> + +PROTOBUF_PRAGMA_INIT_SEG + + +namespace google { +namespace protobuf { +namespace internal { + +void DestroyMessage(const void* message) { + static_cast<const MessageLite*>(message)->~MessageLite(); +} +void DestroyString(const void* s) { + static_cast<const TProtoStringType*>(s)->~TBasicString(); +} + +PROTOBUF_ATTRIBUTE_NO_DESTROY PROTOBUF_CONSTINIT + PROTOBUF_ATTRIBUTE_INIT_PRIORITY ExplicitlyConstructed<TProtoStringType> + fixed_address_empty_string{}; // NOLINT + + +PROTOBUF_CONSTINIT std::atomic<bool> init_protobuf_defaults_state{false}; +static bool InitProtobufDefaultsImpl() { + fixed_address_empty_string.DefaultConstruct(); + OnShutdownDestroyString(fixed_address_empty_string.get_mutable()); + + + init_protobuf_defaults_state.store(true, std::memory_order_release); + return true; +} + +void InitProtobufDefaultsSlow() { + static bool is_inited = InitProtobufDefaultsImpl(); + (void)is_inited; +} +// Force the initialization of the empty string. +// Normally, registration would do it, but we don't have any guarantee that +// there is any object with reflection. +PROTOBUF_ATTRIBUTE_INIT_PRIORITY static std::true_type init_empty_string = + (InitProtobufDefaultsSlow(), std::true_type{}); + +size_t StringSpaceUsedExcludingSelfLong(const TProtoStringType& str) { + const void* start = &str; + const void* end = &str + 1; + if (start <= str.data() && str.data() < end) { + // The string's data is stored inside the string object itself. + return 0; + } else { + return str.capacity(); + } +} + +template <typename T> +const T& Get(const void* ptr) { + return *static_cast<const T*>(ptr); +} + +// PrimitiveTypeHelper is a wrapper around the interface of WireFormatLite. +// WireFormatLite has a very inconvenient interface with respect to template +// meta-programming. This class wraps the different named functions into +// a single Serialize / SerializeToArray interface. +template <int type> +struct PrimitiveTypeHelper; + +template <> +struct PrimitiveTypeHelper<WireFormatLite::TYPE_BOOL> { + typedef bool Type; + static void Serialize(const void* ptr, io::CodedOutputStream* output) { + WireFormatLite::WriteBoolNoTag(Get<bool>(ptr), output); + } + static uint8_t* SerializeToArray(const void* ptr, uint8_t* buffer) { + return WireFormatLite::WriteBoolNoTagToArray(Get<Type>(ptr), buffer); + } +}; + +template <> +struct PrimitiveTypeHelper<WireFormatLite::TYPE_INT32> { + typedef arc_i32 Type; + static void Serialize(const void* ptr, io::CodedOutputStream* output) { + WireFormatLite::WriteInt32NoTag(Get<arc_i32>(ptr), output); + } + static uint8_t* SerializeToArray(const void* ptr, uint8_t* buffer) { + return WireFormatLite::WriteInt32NoTagToArray(Get<Type>(ptr), buffer); + } +}; + +template <> +struct PrimitiveTypeHelper<WireFormatLite::TYPE_SINT32> { + typedef arc_i32 Type; + static void Serialize(const void* ptr, io::CodedOutputStream* output) { + WireFormatLite::WriteSInt32NoTag(Get<arc_i32>(ptr), output); + } + static uint8_t* SerializeToArray(const void* ptr, uint8_t* buffer) { + return WireFormatLite::WriteSInt32NoTagToArray(Get<Type>(ptr), buffer); + } +}; + +template <> +struct PrimitiveTypeHelper<WireFormatLite::TYPE_UINT32> { + typedef arc_ui32 Type; + static void Serialize(const void* ptr, io::CodedOutputStream* output) { + WireFormatLite::WriteUInt32NoTag(Get<arc_ui32>(ptr), output); + } + static uint8_t* SerializeToArray(const void* ptr, uint8_t* buffer) { + return WireFormatLite::WriteUInt32NoTagToArray(Get<Type>(ptr), buffer); + } +}; +template <> +struct PrimitiveTypeHelper<WireFormatLite::TYPE_INT64> { + typedef arc_i64 Type; + static void Serialize(const void* ptr, io::CodedOutputStream* output) { + WireFormatLite::WriteInt64NoTag(Get<arc_i64>(ptr), output); + } + static uint8_t* SerializeToArray(const void* ptr, uint8_t* buffer) { + return WireFormatLite::WriteInt64NoTagToArray(Get<Type>(ptr), buffer); + } +}; + +template <> +struct PrimitiveTypeHelper<WireFormatLite::TYPE_SINT64> { + typedef arc_i64 Type; + static void Serialize(const void* ptr, io::CodedOutputStream* output) { + WireFormatLite::WriteSInt64NoTag(Get<arc_i64>(ptr), output); + } + static uint8_t* SerializeToArray(const void* ptr, uint8_t* buffer) { + return WireFormatLite::WriteSInt64NoTagToArray(Get<Type>(ptr), buffer); + } +}; +template <> +struct PrimitiveTypeHelper<WireFormatLite::TYPE_UINT64> { + typedef arc_ui64 Type; + static void Serialize(const void* ptr, io::CodedOutputStream* output) { + WireFormatLite::WriteUInt64NoTag(Get<arc_ui64>(ptr), output); + } + static uint8_t* SerializeToArray(const void* ptr, uint8_t* buffer) { + return WireFormatLite::WriteUInt64NoTagToArray(Get<Type>(ptr), buffer); + } +}; + +template <> +struct PrimitiveTypeHelper<WireFormatLite::TYPE_FIXED32> { + typedef arc_ui32 Type; + static void Serialize(const void* ptr, io::CodedOutputStream* output) { + WireFormatLite::WriteFixed32NoTag(Get<arc_ui32>(ptr), output); + } + static uint8_t* SerializeToArray(const void* ptr, uint8_t* buffer) { + return WireFormatLite::WriteFixed32NoTagToArray(Get<Type>(ptr), buffer); + } +}; + +template <> +struct PrimitiveTypeHelper<WireFormatLite::TYPE_FIXED64> { + typedef arc_ui64 Type; + static void Serialize(const void* ptr, io::CodedOutputStream* output) { + WireFormatLite::WriteFixed64NoTag(Get<arc_ui64>(ptr), output); + } + static uint8_t* SerializeToArray(const void* ptr, uint8_t* buffer) { + return WireFormatLite::WriteFixed64NoTagToArray(Get<Type>(ptr), buffer); + } +}; + +template <> +struct PrimitiveTypeHelper<WireFormatLite::TYPE_ENUM> + : PrimitiveTypeHelper<WireFormatLite::TYPE_INT32> {}; + +template <> +struct PrimitiveTypeHelper<WireFormatLite::TYPE_SFIXED32> + : PrimitiveTypeHelper<WireFormatLite::TYPE_FIXED32> { + typedef arc_i32 Type; +}; +template <> +struct PrimitiveTypeHelper<WireFormatLite::TYPE_SFIXED64> + : PrimitiveTypeHelper<WireFormatLite::TYPE_FIXED64> { + typedef arc_i64 Type; +}; +template <> +struct PrimitiveTypeHelper<WireFormatLite::TYPE_FLOAT> + : PrimitiveTypeHelper<WireFormatLite::TYPE_FIXED32> { + typedef float Type; +}; +template <> +struct PrimitiveTypeHelper<WireFormatLite::TYPE_DOUBLE> + : PrimitiveTypeHelper<WireFormatLite::TYPE_FIXED64> { + typedef double Type; +}; + +template <> +struct PrimitiveTypeHelper<WireFormatLite::TYPE_STRING> { + typedef TProtoStringType Type; + static void Serialize(const void* ptr, io::CodedOutputStream* output) { + const Type& value = *static_cast<const Type*>(ptr); + output->WriteVarint32(value.size()); + output->WriteRawMaybeAliased(value.data(), value.size()); + } + static uint8_t* SerializeToArray(const void* ptr, uint8_t* buffer) { + const Type& value = *static_cast<const Type*>(ptr); + return io::CodedOutputStream::WriteStringWithSizeToArray(value, buffer); + } +}; + +template <> +struct PrimitiveTypeHelper<WireFormatLite::TYPE_BYTES> + : PrimitiveTypeHelper<WireFormatLite::TYPE_STRING> {}; + + +template <> +struct PrimitiveTypeHelper<FieldMetadata::kInlinedType> + : PrimitiveTypeHelper<WireFormatLite::TYPE_STRING> {}; + +// We want to serialize to both CodedOutputStream and directly into byte arrays +// without duplicating the code. In fact we might want extra output channels in +// the future. +template <typename O, int type> +struct OutputHelper; + +template <int type, typename O> +void SerializeTo(const void* ptr, O* output) { + OutputHelper<O, type>::Serialize(ptr, output); +} + +template <typename O> +void WriteTagTo(arc_ui32 tag, O* output) { + SerializeTo<WireFormatLite::TYPE_UINT32>(&tag, output); +} + +template <typename O> +void WriteLengthTo(arc_ui32 length, O* output) { + SerializeTo<WireFormatLite::TYPE_UINT32>(&length, output); +} + +// Specialization for coded output stream +template <int type> +struct OutputHelper<io::CodedOutputStream, type> { + static void Serialize(const void* ptr, io::CodedOutputStream* output) { + PrimitiveTypeHelper<type>::Serialize(ptr, output); + } +}; + +// Specialization for writing into a plain array +struct ArrayOutput { + uint8_t* ptr; + bool is_deterministic; +}; + +template <int type> +struct OutputHelper<ArrayOutput, type> { + static void Serialize(const void* ptr, ArrayOutput* output) { + output->ptr = PrimitiveTypeHelper<type>::SerializeToArray(ptr, output->ptr); + } +}; + +void SerializeMessageNoTable(const MessageLite* msg, + io::CodedOutputStream* output) { + msg->SerializeWithCachedSizes(output); +} + +void SerializeMessageNoTable(const MessageLite* msg, ArrayOutput* output) { + io::ArrayOutputStream array_stream(output->ptr, INT_MAX); + io::CodedOutputStream o(&array_stream); + o.SetSerializationDeterministic(output->is_deterministic); + msg->SerializeWithCachedSizes(&o); + output->ptr += o.ByteCount(); +} + +// Helper to branch to fast path if possible +void SerializeMessageDispatch(const MessageLite& msg, + const FieldMetadata* field_table, int num_fields, + arc_i32 /*cached_size*/, + io::CodedOutputStream* output) { + const uint8_t* base = reinterpret_cast<const uint8_t*>(&msg); + SerializeInternal(base, field_table, num_fields, output); +} + +// Helper to branch to fast path if possible +void SerializeMessageDispatch(const MessageLite& msg, + const FieldMetadata* field_table, int num_fields, + arc_i32 /*cached_size*/, ArrayOutput* output) { + const uint8_t* base = reinterpret_cast<const uint8_t*>(&msg); + output->ptr = SerializeInternalToArray(base, field_table, num_fields, + output->is_deterministic, output->ptr); +} + +// Serializing messages is special as it's not a primitive type and needs an +// explicit overload for each output type. +template <typename O> +void SerializeMessageTo(const MessageLite* msg, const void* table_ptr, + O* output) { + const SerializationTable* table = + static_cast<const SerializationTable*>(table_ptr); + if (!table) { + // Proto1 + WriteLengthTo(msg->GetCachedSize(), output); + SerializeMessageNoTable(msg, output); + return; + } + const FieldMetadata* field_table = table->field_table; + const uint8_t* base = reinterpret_cast<const uint8_t*>(msg); + int cached_size = + *reinterpret_cast<const arc_i32*>(base + field_table->offset); + WriteLengthTo(cached_size, output); + int num_fields = table->num_fields - 1; + SerializeMessageDispatch(*msg, field_table + 1, num_fields, cached_size, + output); +} + +// Almost the same as above only it doesn't output the length field. +template <typename O> +void SerializeGroupTo(const MessageLite* msg, const void* table_ptr, + O* output) { + const SerializationTable* table = + static_cast<const SerializationTable*>(table_ptr); + if (!table) { + // Proto1 + SerializeMessageNoTable(msg, output); + return; + } + const FieldMetadata* field_table = table->field_table; + const uint8_t* base = reinterpret_cast<const uint8_t*>(msg); + int cached_size = + *reinterpret_cast<const arc_i32*>(base + field_table->offset); + int num_fields = table->num_fields - 1; + SerializeMessageDispatch(*msg, field_table + 1, num_fields, cached_size, + output); +} + +template <int type> +struct SingularFieldHelper { + template <typename O> + static void Serialize(const void* field, const FieldMetadata& md, O* output) { + WriteTagTo(md.tag, output); + SerializeTo<type>(field, output); + } +}; + +template <> +struct SingularFieldHelper<WireFormatLite::TYPE_STRING> { + template <typename O> + static void Serialize(const void* field, const FieldMetadata& md, O* output) { + WriteTagTo(md.tag, output); + SerializeTo<WireFormatLite::TYPE_STRING>(&Get<ArenaStringPtr>(field).Get(), + output); + } +}; + +template <> +struct SingularFieldHelper<WireFormatLite::TYPE_BYTES> + : SingularFieldHelper<WireFormatLite::TYPE_STRING> {}; + +template <> +struct SingularFieldHelper<WireFormatLite::TYPE_GROUP> { + template <typename O> + static void Serialize(const void* field, const FieldMetadata& md, O* output) { + WriteTagTo(md.tag, output); + SerializeGroupTo(Get<const MessageLite*>(field), + static_cast<const SerializationTable*>(md.ptr), output); + WriteTagTo(md.tag + 1, output); + } +}; + +template <> +struct SingularFieldHelper<WireFormatLite::TYPE_MESSAGE> { + template <typename O> + static void Serialize(const void* field, const FieldMetadata& md, O* output) { + WriteTagTo(md.tag, output); + SerializeMessageTo(Get<const MessageLite*>(field), + static_cast<const SerializationTable*>(md.ptr), output); + } +}; + +template <> +struct SingularFieldHelper<FieldMetadata::kInlinedType> { + template <typename O> + static void Serialize(const void* field, const FieldMetadata& md, O* output) { + WriteTagTo(md.tag, output); + SerializeTo<FieldMetadata::kInlinedType>(&Get<TProtoStringType>(field), output); + } +}; + +template <int type> +struct RepeatedFieldHelper { + template <typename O> + static void Serialize(const void* field, const FieldMetadata& md, O* output) { + typedef typename PrimitiveTypeHelper<type>::Type T; + const RepeatedField<T>& array = Get<RepeatedField<T> >(field); + for (int i = 0; i < array.size(); i++) { + WriteTagTo(md.tag, output); + SerializeTo<type>(&array[i], output); + } + } +}; + +// We need to use a helper class to get access to the private members +class AccessorHelper { + public: + static int Size(const RepeatedPtrFieldBase& x) { return x.size(); } + static void const* Get(const RepeatedPtrFieldBase& x, int idx) { + return x.raw_data()[idx]; + } +}; + +template <> +struct RepeatedFieldHelper<WireFormatLite::TYPE_STRING> { + template <typename O> + static void Serialize(const void* field, const FieldMetadata& md, O* output) { + const internal::RepeatedPtrFieldBase& array = + Get<internal::RepeatedPtrFieldBase>(field); + for (int i = 0; i < AccessorHelper::Size(array); i++) { + WriteTagTo(md.tag, output); + SerializeTo<WireFormatLite::TYPE_STRING>(AccessorHelper::Get(array, i), + output); + } + } +}; + +template <> +struct RepeatedFieldHelper<WireFormatLite::TYPE_BYTES> + : RepeatedFieldHelper<WireFormatLite::TYPE_STRING> {}; + +template <> +struct RepeatedFieldHelper<WireFormatLite::TYPE_GROUP> { + template <typename O> + static void Serialize(const void* field, const FieldMetadata& md, O* output) { + const internal::RepeatedPtrFieldBase& array = + Get<internal::RepeatedPtrFieldBase>(field); + for (int i = 0; i < AccessorHelper::Size(array); i++) { + WriteTagTo(md.tag, output); + SerializeGroupTo( + static_cast<const MessageLite*>(AccessorHelper::Get(array, i)), + static_cast<const SerializationTable*>(md.ptr), output); + WriteTagTo(md.tag + 1, output); + } + } +}; + +template <> +struct RepeatedFieldHelper<WireFormatLite::TYPE_MESSAGE> { + template <typename O> + static void Serialize(const void* field, const FieldMetadata& md, O* output) { + const internal::RepeatedPtrFieldBase& array = + Get<internal::RepeatedPtrFieldBase>(field); + for (int i = 0; i < AccessorHelper::Size(array); i++) { + WriteTagTo(md.tag, output); + SerializeMessageTo( + static_cast<const MessageLite*>(AccessorHelper::Get(array, i)), + md.ptr, output); + } + } +}; + + +template <> +struct RepeatedFieldHelper<FieldMetadata::kInlinedType> + : RepeatedFieldHelper<WireFormatLite::TYPE_STRING> {}; + +template <int type> +struct PackedFieldHelper { + template <typename O> + static void Serialize(const void* field, const FieldMetadata& md, O* output) { + typedef typename PrimitiveTypeHelper<type>::Type T; + const RepeatedField<T>& array = Get<RepeatedField<T> >(field); + if (array.empty()) return; + WriteTagTo(md.tag, output); + int cached_size = + Get<int>(static_cast<const uint8_t*>(field) + sizeof(RepeatedField<T>)); + WriteLengthTo(cached_size, output); + for (int i = 0; i < array.size(); i++) { + SerializeTo<type>(&array[i], output); + } + } +}; + +template <> +struct PackedFieldHelper<WireFormatLite::TYPE_STRING> { + template <typename O> + static void Serialize(const void* /*field*/, const FieldMetadata& md, + O* /*output*/) { + GOOGLE_LOG(FATAL) << "Not implemented field number " << md.tag << " with type " + << md.type; + } +}; + +template <> +struct PackedFieldHelper<WireFormatLite::TYPE_BYTES> + : PackedFieldHelper<WireFormatLite::TYPE_STRING> {}; +template <> +struct PackedFieldHelper<WireFormatLite::TYPE_GROUP> + : PackedFieldHelper<WireFormatLite::TYPE_STRING> {}; +template <> +struct PackedFieldHelper<WireFormatLite::TYPE_MESSAGE> + : PackedFieldHelper<WireFormatLite::TYPE_STRING> {}; +template <> +struct PackedFieldHelper<FieldMetadata::kInlinedType> + : PackedFieldHelper<WireFormatLite::TYPE_STRING> {}; + +template <int type> +struct OneOfFieldHelper { + template <typename O> + static void Serialize(const void* field, const FieldMetadata& md, O* output) { + SingularFieldHelper<type>::Serialize(field, md, output); + } +}; + + +template <> +struct OneOfFieldHelper<FieldMetadata::kInlinedType> { + template <typename O> + static void Serialize(const void* field, const FieldMetadata& md, O* output) { + SingularFieldHelper<FieldMetadata::kInlinedType>::Serialize( + Get<const TProtoStringType*>(field), md, output); + } +}; + +void SerializeNotImplemented(int field) { + GOOGLE_LOG(FATAL) << "Not implemented field number " << field; +} + +// When switching to c++11 we should make these constexpr functions +#define SERIALIZE_TABLE_OP(type, type_class) \ + ((type - 1) + static_cast<int>(type_class) * FieldMetadata::kNumTypes) + +int FieldMetadata::CalculateType(int type, + FieldMetadata::FieldTypeClass type_class) { + return SERIALIZE_TABLE_OP(type, type_class); +} + +template <int type> +bool IsNull(const void* ptr) { + return *static_cast<const typename PrimitiveTypeHelper<type>::Type*>(ptr) == + 0; +} + +template <> +bool IsNull<WireFormatLite::TYPE_STRING>(const void* ptr) { + return static_cast<const ArenaStringPtr*>(ptr)->Get().size() == 0; +} + +template <> +bool IsNull<WireFormatLite::TYPE_BYTES>(const void* ptr) { + return static_cast<const ArenaStringPtr*>(ptr)->Get().size() == 0; +} + +template <> +bool IsNull<WireFormatLite::TYPE_GROUP>(const void* ptr) { + return Get<const MessageLite*>(ptr) == nullptr; +} + +template <> +bool IsNull<WireFormatLite::TYPE_MESSAGE>(const void* ptr) { + return Get<const MessageLite*>(ptr) == nullptr; +} + + +template <> +bool IsNull<FieldMetadata::kInlinedType>(const void* ptr) { + return static_cast<const TProtoStringType*>(ptr)->empty(); +} + +#define SERIALIZERS_FOR_TYPE(type) \ + case SERIALIZE_TABLE_OP(type, FieldMetadata::kPresence): \ + if (!IsPresent(base, field_metadata.has_offset)) continue; \ + SingularFieldHelper<type>::Serialize(ptr, field_metadata, output); \ + break; \ + case SERIALIZE_TABLE_OP(type, FieldMetadata::kNoPresence): \ + if (IsNull<type>(ptr)) continue; \ + SingularFieldHelper<type>::Serialize(ptr, field_metadata, output); \ + break; \ + case SERIALIZE_TABLE_OP(type, FieldMetadata::kRepeated): \ + RepeatedFieldHelper<type>::Serialize(ptr, field_metadata, output); \ + break; \ + case SERIALIZE_TABLE_OP(type, FieldMetadata::kPacked): \ + PackedFieldHelper<type>::Serialize(ptr, field_metadata, output); \ + break; \ + case SERIALIZE_TABLE_OP(type, FieldMetadata::kOneOf): \ + if (!IsOneofPresent(base, field_metadata.has_offset, field_metadata.tag)) \ + continue; \ + OneOfFieldHelper<type>::Serialize(ptr, field_metadata, output); \ + break + +void SerializeInternal(const uint8_t* base, + const FieldMetadata* field_metadata_table, + arc_i32 num_fields, io::CodedOutputStream* output) { + SpecialSerializer func = nullptr; + for (int i = 0; i < num_fields; i++) { + const FieldMetadata& field_metadata = field_metadata_table[i]; + const uint8_t* ptr = base + field_metadata.offset; + switch (field_metadata.type) { + SERIALIZERS_FOR_TYPE(WireFormatLite::TYPE_DOUBLE); + SERIALIZERS_FOR_TYPE(WireFormatLite::TYPE_FLOAT); + SERIALIZERS_FOR_TYPE(WireFormatLite::TYPE_INT64); + SERIALIZERS_FOR_TYPE(WireFormatLite::TYPE_UINT64); + SERIALIZERS_FOR_TYPE(WireFormatLite::TYPE_INT32); + SERIALIZERS_FOR_TYPE(WireFormatLite::TYPE_FIXED64); + SERIALIZERS_FOR_TYPE(WireFormatLite::TYPE_FIXED32); + SERIALIZERS_FOR_TYPE(WireFormatLite::TYPE_BOOL); + SERIALIZERS_FOR_TYPE(WireFormatLite::TYPE_STRING); + SERIALIZERS_FOR_TYPE(WireFormatLite::TYPE_GROUP); + SERIALIZERS_FOR_TYPE(WireFormatLite::TYPE_MESSAGE); + SERIALIZERS_FOR_TYPE(WireFormatLite::TYPE_BYTES); + SERIALIZERS_FOR_TYPE(WireFormatLite::TYPE_UINT32); + SERIALIZERS_FOR_TYPE(WireFormatLite::TYPE_ENUM); + SERIALIZERS_FOR_TYPE(WireFormatLite::TYPE_SFIXED32); + SERIALIZERS_FOR_TYPE(WireFormatLite::TYPE_SFIXED64); + SERIALIZERS_FOR_TYPE(WireFormatLite::TYPE_SINT32); + SERIALIZERS_FOR_TYPE(WireFormatLite::TYPE_SINT64); + SERIALIZERS_FOR_TYPE(FieldMetadata::kInlinedType); + + // Special cases + case FieldMetadata::kSpecial: + func = reinterpret_cast<SpecialSerializer>( + const_cast<void*>(field_metadata.ptr)); + func(base, field_metadata.offset, field_metadata.tag, + field_metadata.has_offset, output); + break; + default: + // __builtin_unreachable() + SerializeNotImplemented(field_metadata.type); + } + } +} + +uint8_t* SerializeInternalToArray(const uint8_t* base, + const FieldMetadata* field_metadata_table, + arc_i32 num_fields, bool is_deterministic, + uint8_t* buffer) { + ArrayOutput array_output = {buffer, is_deterministic}; + ArrayOutput* output = &array_output; + SpecialSerializer func = nullptr; + for (int i = 0; i < num_fields; i++) { + const FieldMetadata& field_metadata = field_metadata_table[i]; + const uint8_t* ptr = base + field_metadata.offset; + switch (field_metadata.type) { + SERIALIZERS_FOR_TYPE(WireFormatLite::TYPE_DOUBLE); + SERIALIZERS_FOR_TYPE(WireFormatLite::TYPE_FLOAT); + SERIALIZERS_FOR_TYPE(WireFormatLite::TYPE_INT64); + SERIALIZERS_FOR_TYPE(WireFormatLite::TYPE_UINT64); + SERIALIZERS_FOR_TYPE(WireFormatLite::TYPE_INT32); + SERIALIZERS_FOR_TYPE(WireFormatLite::TYPE_FIXED64); + SERIALIZERS_FOR_TYPE(WireFormatLite::TYPE_FIXED32); + SERIALIZERS_FOR_TYPE(WireFormatLite::TYPE_BOOL); + SERIALIZERS_FOR_TYPE(WireFormatLite::TYPE_STRING); + SERIALIZERS_FOR_TYPE(WireFormatLite::TYPE_GROUP); + SERIALIZERS_FOR_TYPE(WireFormatLite::TYPE_MESSAGE); + SERIALIZERS_FOR_TYPE(WireFormatLite::TYPE_BYTES); + SERIALIZERS_FOR_TYPE(WireFormatLite::TYPE_UINT32); + SERIALIZERS_FOR_TYPE(WireFormatLite::TYPE_ENUM); + SERIALIZERS_FOR_TYPE(WireFormatLite::TYPE_SFIXED32); + SERIALIZERS_FOR_TYPE(WireFormatLite::TYPE_SFIXED64); + SERIALIZERS_FOR_TYPE(WireFormatLite::TYPE_SINT32); + SERIALIZERS_FOR_TYPE(WireFormatLite::TYPE_SINT64); + SERIALIZERS_FOR_TYPE(FieldMetadata::kInlinedType); + // Special cases + case FieldMetadata::kSpecial: { + io::ArrayOutputStream array_stream(array_output.ptr, INT_MAX); + io::CodedOutputStream output_stream(&array_stream); + output_stream.SetSerializationDeterministic(is_deterministic); + func = reinterpret_cast<SpecialSerializer>( + const_cast<void*>(field_metadata.ptr)); + func(base, field_metadata.offset, field_metadata.tag, + field_metadata.has_offset, &output_stream); + array_output.ptr += output_stream.ByteCount(); + } break; + default: + // __builtin_unreachable() + SerializeNotImplemented(field_metadata.type); + } + } + return array_output.ptr; +} +#undef SERIALIZERS_FOR_TYPE + +void ExtensionSerializer(const MessageLite* extendee, const uint8_t* ptr, + arc_ui32 offset, arc_ui32 tag, arc_ui32 has_offset, + io::CodedOutputStream* output) { + reinterpret_cast<const ExtensionSet*>(ptr + offset) + ->SerializeWithCachedSizes(extendee, tag, has_offset, output); +} + +void UnknownFieldSerializerLite(const uint8_t* ptr, arc_ui32 offset, + arc_ui32 /*tag*/, arc_ui32 /*has_offset*/, + io::CodedOutputStream* output) { + output->WriteString( + reinterpret_cast<const InternalMetadata*>(ptr + offset) + ->unknown_fields<TProtoStringType>(&internal::GetEmptyString)); +} + +MessageLite* DuplicateIfNonNullInternal(MessageLite* message) { + if (message) { + MessageLite* ret = message->New(); + ret->CheckTypeAndMergeFrom(*message); + return ret; + } else { + return nullptr; + } +} + +void GenericSwap(MessageLite* m1, MessageLite* m2) { + std::unique_ptr<MessageLite> tmp(m1->New()); + tmp->CheckTypeAndMergeFrom(*m1); + m1->Clear(); + m1->CheckTypeAndMergeFrom(*m2); + m2->Clear(); + m2->CheckTypeAndMergeFrom(*tmp); +} + +// Returns a message owned by this Arena. This may require Own()ing or +// duplicating the message. +MessageLite* GetOwnedMessageInternal(Arena* message_arena, + MessageLite* submessage, + Arena* submessage_arena) { + GOOGLE_DCHECK(Arena::InternalHelper<MessageLite>::GetOwningArena(submessage) == + submessage_arena); + GOOGLE_DCHECK(message_arena != submessage_arena); + GOOGLE_DCHECK_EQ(submessage_arena, nullptr); + if (message_arena != nullptr && submessage_arena == nullptr) { + message_arena->Own(submessage); + return submessage; + } else { + MessageLite* ret = submessage->New(message_arena); + ret->CheckTypeAndMergeFrom(*submessage); + return ret; + } +} + +} // namespace internal +} // namespace protobuf +} // namespace google + +#include <google/protobuf/port_undef.inc> diff --git a/contrib/libs/protobuf_old/src/google/protobuf/generated_message_util.h b/contrib/libs/protobuf_old/src/google/protobuf/generated_message_util.h new file mode 100644 index 0000000000..c751ddbd7b --- /dev/null +++ b/contrib/libs/protobuf_old/src/google/protobuf/generated_message_util.h @@ -0,0 +1,213 @@ +// 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: kenton@google.com (Kenton Varda) +// Based on original Protocol Buffers design by +// Sanjay Ghemawat, Jeff Dean, and others. +// +// This file contains miscellaneous helper code used by generated code -- +// including lite types -- but which should not be used directly by users. + +#ifndef GOOGLE_PROTOBUF_GENERATED_MESSAGE_UTIL_H__ +#define GOOGLE_PROTOBUF_GENERATED_MESSAGE_UTIL_H__ + +#include <assert.h> + +#include <atomic> +#include <climits> +#include <string> +#include <vector> + +#include <google/protobuf/stubs/common.h> +#include <google/protobuf/any.h> +#include <google/protobuf/has_bits.h> +#include <google/protobuf/implicit_weak_message.h> +#include <google/protobuf/message_lite.h> +#include <google/protobuf/stubs/once.h> // Add direct dep on port for pb.cc +#include <google/protobuf/port.h> +#include <google/protobuf/repeated_field.h> +#include <google/protobuf/wire_format_lite.h> +#include <google/protobuf/stubs/strutil.h> +#include <google/protobuf/stubs/casts.h> + +#include <google/protobuf/port_def.inc> + +#ifdef SWIG +#error "You cannot SWIG proto headers" +#endif + +namespace google { +namespace protobuf { + +class Arena; +class Message; + +namespace io { +class CodedInputStream; +} + +namespace internal { + +template <typename To, typename From> +inline To DownCast(From* f) { + return PROTOBUF_NAMESPACE_ID::internal::down_cast<To>(f); +} +template <typename To, typename From> +inline To DownCast(From& f) { + return PROTOBUF_NAMESPACE_ID::internal::down_cast<To>(f); +} + + +// This fastpath inlines a single branch instead of having to make the +// InitProtobufDefaults function call. +// It also generates less inlined code than a function-scope static initializer. +PROTOBUF_EXPORT extern std::atomic<bool> init_protobuf_defaults_state; +PROTOBUF_EXPORT void InitProtobufDefaultsSlow(); +PROTOBUF_EXPORT inline void InitProtobufDefaults() { + if (PROTOBUF_PREDICT_FALSE( + !init_protobuf_defaults_state.load(std::memory_order_acquire))) { + InitProtobufDefaultsSlow(); + } +} + +// This used by proto1 +PROTOBUF_EXPORT inline const TProtoStringType& GetEmptyString() { + InitProtobufDefaults(); + return GetEmptyStringAlreadyInited(); +} + + +// True if IsInitialized() is true for all elements of t. Type is expected +// to be a RepeatedPtrField<some message type>. It's useful to have this +// helper here to keep the protobuf compiler from ever having to emit loops in +// IsInitialized() methods. We want the C++ compiler to inline this or not +// as it sees fit. +template <typename Msg> +bool AllAreInitialized(const RepeatedPtrField<Msg>& t) { + for (int i = t.size(); --i >= 0;) { + if (!t.Get(i).IsInitialized()) return false; + } + return true; +} + +// "Weak" variant of AllAreInitialized, used to implement implicit weak fields. +// This version operates on MessageLite to avoid introducing a dependency on the +// concrete message type. +template <class T> +bool AllAreInitializedWeak(const RepeatedPtrField<T>& t) { + for (int i = t.size(); --i >= 0;) { + if (!reinterpret_cast<const RepeatedPtrFieldBase&>(t) + .Get<ImplicitWeakTypeHandler<T> >(i) + .IsInitialized()) { + return false; + } + } + return true; +} + +inline bool IsPresent(const void* base, arc_ui32 hasbit) { + const arc_ui32* has_bits_array = static_cast<const arc_ui32*>(base); + return (has_bits_array[hasbit / 32] & (1u << (hasbit & 31))) != 0; +} + +inline bool IsOneofPresent(const void* base, arc_ui32 offset, arc_ui32 tag) { + const arc_ui32* oneof = reinterpret_cast<const arc_ui32*>( + static_cast<const uint8_t*>(base) + offset); + return *oneof == tag >> 3; +} + +typedef void (*SpecialSerializer)(const uint8_t* base, arc_ui32 offset, + arc_ui32 tag, arc_ui32 has_offset, + io::CodedOutputStream* output); + +PROTOBUF_EXPORT void ExtensionSerializer(const MessageLite* extendee, + const uint8_t* ptr, arc_ui32 offset, + arc_ui32 tag, arc_ui32 has_offset, + io::CodedOutputStream* output); +PROTOBUF_EXPORT void UnknownFieldSerializerLite(const uint8_t* base, + arc_ui32 offset, arc_ui32 tag, + arc_ui32 has_offset, + io::CodedOutputStream* output); + +PROTOBUF_EXPORT MessageLite* DuplicateIfNonNullInternal(MessageLite* message); +PROTOBUF_EXPORT MessageLite* GetOwnedMessageInternal(Arena* message_arena, + MessageLite* submessage, + Arena* submessage_arena); +PROTOBUF_EXPORT void GenericSwap(MessageLite* m1, MessageLite* m2); +// We specialize GenericSwap for non-lite messages to benefit from reflection. +PROTOBUF_EXPORT void GenericSwap(Message* m1, Message* m2); + +template <typename T> +T* DuplicateIfNonNull(T* message) { + // The casts must be reinterpret_cast<> because T might be a forward-declared + // type that the compiler doesn't know is related to MessageLite. + return reinterpret_cast<T*>( + DuplicateIfNonNullInternal(reinterpret_cast<MessageLite*>(message))); +} + +template <typename T> +T* GetOwnedMessage(Arena* message_arena, T* submessage, + Arena* submessage_arena) { + // The casts must be reinterpret_cast<> because T might be a forward-declared + // type that the compiler doesn't know is related to MessageLite. + return reinterpret_cast<T*>(GetOwnedMessageInternal( + message_arena, reinterpret_cast<MessageLite*>(submessage), + submessage_arena)); +} + +// Hide atomic from the public header and allow easy change to regular int +// on platforms where the atomic might have a perf impact. +class PROTOBUF_EXPORT CachedSize { + public: + int Get() const { return size_.load(std::memory_order_relaxed); } + void Set(int size) { size_.store(size, std::memory_order_relaxed); } + + private: + std::atomic<int> size_{0}; +}; + +PROTOBUF_EXPORT void DestroyMessage(const void* message); +PROTOBUF_EXPORT void DestroyString(const void* s); +// Destroy (not delete) the message +inline void OnShutdownDestroyMessage(const void* ptr) { + OnShutdownRun(DestroyMessage, ptr); +} +// Destroy the string (call TProtoStringType destructor) +inline void OnShutdownDestroyString(const TProtoStringType* ptr) { + OnShutdownRun(DestroyString, ptr); +} + +} // namespace internal +} // namespace protobuf +} // namespace google + +#include <google/protobuf/port_undef.inc> + +#endif // GOOGLE_PROTOBUF_GENERATED_MESSAGE_UTIL_H__ diff --git a/contrib/libs/protobuf_old/src/google/protobuf/has_bits.h b/contrib/libs/protobuf_old/src/google/protobuf/has_bits.h new file mode 100644 index 0000000000..9cff105307 --- /dev/null +++ b/contrib/libs/protobuf_old/src/google/protobuf/has_bits.h @@ -0,0 +1,116 @@ +// 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_HAS_BITS_H__ +#define GOOGLE_PROTOBUF_HAS_BITS_H__ + +#include <google/protobuf/stubs/common.h> +#include <google/protobuf/port.h> + +#include <google/protobuf/port_def.inc> + +#ifdef SWIG +#error "You cannot SWIG proto headers" +#endif + +namespace google { +namespace protobuf { +namespace internal { + +template <size_t doublewords> +class HasBits { + public: + PROTOBUF_NDEBUG_INLINE constexpr HasBits() : has_bits_{} {} + + PROTOBUF_NDEBUG_INLINE void Clear() { + memset(has_bits_, 0, sizeof(has_bits_)); + } + + PROTOBUF_NDEBUG_INLINE arc_ui32& operator[](int index) { + return has_bits_[index]; + } + + PROTOBUF_NDEBUG_INLINE const arc_ui32& operator[](int index) const { + return has_bits_[index]; + } + + bool operator==(const HasBits<doublewords>& rhs) const { + return memcmp(has_bits_, rhs.has_bits_, sizeof(has_bits_)) == 0; + } + + bool operator!=(const HasBits<doublewords>& rhs) const { + return !(*this == rhs); + } + + void Or(const HasBits<doublewords>& rhs) { + for (size_t i = 0; i < doublewords; i++) has_bits_[i] |= rhs[i]; + } + + bool empty() const; + + private: + arc_ui32 has_bits_[doublewords]; +}; + +template <> +inline bool HasBits<1>::empty() const { + return !has_bits_[0]; +} + +template <> +inline bool HasBits<2>::empty() const { + return !(has_bits_[0] | has_bits_[1]); +} + +template <> +inline bool HasBits<3>::empty() const { + return !(has_bits_[0] | has_bits_[1] | has_bits_[2]); +} + +template <> +inline bool HasBits<4>::empty() const { + return !(has_bits_[0] | has_bits_[1] | has_bits_[2] | has_bits_[3]); +} + +template <size_t doublewords> +inline bool HasBits<doublewords>::empty() const { + for (size_t i = 0; i < doublewords; ++i) { + if (has_bits_[i]) return false; + } + return true; +} + +} // namespace internal +} // namespace protobuf +} // namespace google + +#include <google/protobuf/port_undef.inc> + +#endif // GOOGLE_PROTOBUF_HAS_BITS_H__ diff --git a/contrib/libs/protobuf_old/src/google/protobuf/implicit_weak_message.cc b/contrib/libs/protobuf_old/src/google/protobuf/implicit_weak_message.cc new file mode 100644 index 0000000000..528cf95d41 --- /dev/null +++ b/contrib/libs/protobuf_old/src/google/protobuf/implicit_weak_message.cc @@ -0,0 +1,67 @@ +// 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 <google/protobuf/implicit_weak_message.h> + +#include <google/protobuf/parse_context.h> +#include <google/protobuf/io/zero_copy_stream_impl_lite.h> +#include <google/protobuf/stubs/once.h> +#include <google/protobuf/wire_format_lite.h> + +#include <google/protobuf/port_def.inc> + +namespace google { +namespace protobuf { +namespace internal { + +const char* ImplicitWeakMessage::_InternalParse(const char* ptr, + ParseContext* ctx) { + return ctx->AppendString(ptr, &data_); +} + +ExplicitlyConstructed<ImplicitWeakMessage> + implicit_weak_message_default_instance; +internal::once_flag implicit_weak_message_once_init_; + +void InitImplicitWeakMessageDefaultInstance() { + implicit_weak_message_default_instance.DefaultConstruct(); +} + +const ImplicitWeakMessage* ImplicitWeakMessage::default_instance() { + internal::call_once(implicit_weak_message_once_init_, + InitImplicitWeakMessageDefaultInstance); + return &implicit_weak_message_default_instance.get(); +} + +} // namespace internal +} // namespace protobuf +} // namespace google + +#include <google/protobuf/port_undef.inc> diff --git a/contrib/libs/protobuf_old/src/google/protobuf/implicit_weak_message.h b/contrib/libs/protobuf_old/src/google/protobuf/implicit_weak_message.h new file mode 100644 index 0000000000..85c6205b7a --- /dev/null +++ b/contrib/libs/protobuf_old/src/google/protobuf/implicit_weak_message.h @@ -0,0 +1,186 @@ +// 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_IMPLICIT_WEAK_MESSAGE_H__ +#define GOOGLE_PROTOBUF_IMPLICIT_WEAK_MESSAGE_H__ + +#include <string> + +#include <google/protobuf/io/coded_stream.h> +#include <google/protobuf/arena.h> +#include <google/protobuf/message_lite.h> +#include <google/protobuf/repeated_field.h> + +#ifdef SWIG +#error "You cannot SWIG proto headers" +#endif + +#include <google/protobuf/port_def.inc> + +// This file is logically internal-only and should only be used by protobuf +// generated code. + +namespace google { +namespace protobuf { +namespace internal { + +// An implementation of MessageLite that treats all data as unknown. This type +// acts as a placeholder for an implicit weak field in the case where the true +// message type does not get linked into the binary. +class PROTOBUF_EXPORT ImplicitWeakMessage : public MessageLite { + public: + ImplicitWeakMessage() {} + explicit ImplicitWeakMessage(Arena* arena) : MessageLite(arena) {} + + static const ImplicitWeakMessage* default_instance(); + + TProtoStringType GetTypeName() const override { return ""; } + + MessageLite* New(Arena* arena) const override { + return Arena::CreateMessage<ImplicitWeakMessage>(arena); + } + + void Clear() override { data_.clear(); } + + bool IsInitialized() const override { return true; } + + void CheckTypeAndMergeFrom(const MessageLite& other) override { + data_.append(static_cast<const ImplicitWeakMessage&>(other).data_); + } + + const char* _InternalParse(const char* ptr, ParseContext* ctx) final; + + size_t ByteSizeLong() const override { return data_.size(); } + + uint8_t* _InternalSerialize(uint8_t* target, + io::EpsCopyOutputStream* stream) const final { + return stream->WriteRaw(data_.data(), static_cast<int>(data_.size()), + target); + } + + int GetCachedSize() const override { return static_cast<int>(data_.size()); } + + typedef void InternalArenaConstructable_; + + private: + TProtoStringType data_; + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ImplicitWeakMessage); +}; + +// A type handler for use with implicit weak repeated message fields. +template <typename ImplicitWeakType> +class ImplicitWeakTypeHandler { + public: + typedef MessageLite Type; + static constexpr bool Moveable = false; + + static inline MessageLite* NewFromPrototype(const MessageLite* prototype, + Arena* arena = nullptr) { + return prototype->New(arena); + } + + static inline void Delete(MessageLite* value, Arena* arena) { + if (arena == nullptr) { + delete value; + } + } + static inline Arena* GetArena(MessageLite* value) { + return value->GetArena(); + } + static inline void Clear(MessageLite* value) { value->Clear(); } + static void Merge(const MessageLite& from, MessageLite* to) { + to->CheckTypeAndMergeFrom(from); + } +}; + +} // namespace internal + +template <typename T> +struct WeakRepeatedPtrField { + using TypeHandler = internal::ImplicitWeakTypeHandler<T>; + constexpr WeakRepeatedPtrField() : weak() {} + explicit WeakRepeatedPtrField(Arena* arena) : weak(arena) {} + ~WeakRepeatedPtrField() { weak.template Destroy<TypeHandler>(); } + + typedef internal::RepeatedPtrIterator<MessageLite> iterator; + typedef internal::RepeatedPtrIterator<const MessageLite> const_iterator; + typedef internal::RepeatedPtrOverPtrsIterator<MessageLite*, void*> + pointer_iterator; + typedef internal::RepeatedPtrOverPtrsIterator<const MessageLite* const, + const void* const> + const_pointer_iterator; + + iterator begin() { return iterator(base().raw_data()); } + const_iterator begin() const { return iterator(base().raw_data()); } + const_iterator cbegin() const { return begin(); } + iterator end() { return begin() + base().size(); } + const_iterator end() const { return begin() + base().size(); } + const_iterator cend() const { return end(); } + pointer_iterator pointer_begin() { + return pointer_iterator(base().raw_mutable_data()); + } + const_pointer_iterator pointer_begin() const { + return const_pointer_iterator(base().raw_mutable_data()); + } + pointer_iterator pointer_end() { + return pointer_iterator(base().raw_mutable_data() + base().size()); + } + const_pointer_iterator pointer_end() const { + return const_pointer_iterator(base().raw_mutable_data() + base().size()); + } + + MessageLite* AddWeak(const MessageLite* prototype) { + return base().AddWeak(prototype); + } + T* Add() { return weak.Add(); } + void Clear() { base().template Clear<TypeHandler>(); } + void MergeFrom(const WeakRepeatedPtrField& other) { + base().template MergeFrom<TypeHandler>(other.base()); + } + void InternalSwap(WeakRepeatedPtrField* other) { + base().InternalSwap(&other->base()); + } + + const internal::RepeatedPtrFieldBase& base() const { return weak; } + internal::RepeatedPtrFieldBase& base() { return weak; } + // Union disables running the destructor. Which would create a strong link. + // Instead we explicitly destroy the underlying base through the virtual + // destructor. + union { + RepeatedPtrField<T> weak; + }; +}; + +} // namespace protobuf +} // namespace google + +#include <google/protobuf/port_undef.inc> + +#endif // GOOGLE_PROTOBUF_IMPLICIT_WEAK_MESSAGE_H__ diff --git a/contrib/libs/protobuf_old/src/google/protobuf/inlined_string_field.cc b/contrib/libs/protobuf_old/src/google/protobuf/inlined_string_field.cc new file mode 100644 index 0000000000..d3614c8d74 --- /dev/null +++ b/contrib/libs/protobuf_old/src/google/protobuf/inlined_string_field.cc @@ -0,0 +1,110 @@ +// 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 <google/protobuf/inlined_string_field.h> + +#include <google/protobuf/parse_context.h> +#include <google/protobuf/arena.h> +#include <google/protobuf/arenastring.h> +#include <google/protobuf/generated_message_util.h> +#include <google/protobuf/message_lite.h> + +// clang-format off +#include <google/protobuf/port_def.inc> +// clang-format on + +namespace google { +namespace protobuf { +namespace internal { + + +TProtoStringType* InlinedStringField::Mutable(const LazyString& /*default_value*/, + Arena* arena, bool donated, + arc_ui32* donating_states, + arc_ui32 mask) { + if (arena == nullptr || !donated) { + return UnsafeMutablePointer(); + } + return MutableSlow(arena, donated, donating_states, mask); +} + +TProtoStringType* InlinedStringField::Mutable(ArenaStringPtr::EmptyDefault, + Arena* arena, bool donated, + arc_ui32* donating_states, + arc_ui32 mask) { + if (arena == nullptr || !donated) { + return UnsafeMutablePointer(); + } + return MutableSlow(arena, donated, donating_states, mask); +} + +TProtoStringType* InlinedStringField::MutableSlow(::google::protobuf::Arena* arena, + bool donated, + arc_ui32* donating_states, + arc_ui32 mask) { + return UnsafeMutablePointer(); +} + +void InlinedStringField::SetAllocated(const TProtoStringType* default_value, + TProtoStringType* value, Arena* arena, + bool donated, arc_ui32* donating_states, + arc_ui32 mask) { + SetAllocatedNoArena(default_value, value); +} + +void InlinedStringField::Set(const TProtoStringType* default_value, + TProtoStringType&& value, Arena* arena, bool donated, + arc_ui32* donating_states, arc_ui32 mask) { + SetNoArena(default_value, std::move(value)); +} + +TProtoStringType* InlinedStringField::Release(const TProtoStringType* default_value, + Arena* arena, bool donated) { + if (arena == nullptr && !donated) { + return ReleaseNonDefaultNoArena(default_value); + } + return ReleaseNonDefault(default_value, arena); +} + +TProtoStringType* InlinedStringField::ReleaseNonDefault( + const TProtoStringType* default_value, Arena* arena) { + return ReleaseNonDefaultNoArena(default_value); +} + +void InlinedStringField::ClearToDefault(const LazyString& default_value, + Arena* arena, bool donated) { + (void)arena; + get_mutable()->assign(default_value.get()); +} + + +} // namespace internal +} // namespace protobuf +} // namespace google diff --git a/contrib/libs/protobuf_old/src/google/protobuf/inlined_string_field.h b/contrib/libs/protobuf_old/src/google/protobuf/inlined_string_field.h new file mode 100644 index 0000000000..40dba70b45 --- /dev/null +++ b/contrib/libs/protobuf_old/src/google/protobuf/inlined_string_field.h @@ -0,0 +1,384 @@ +// 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_INLINED_STRING_FIELD_H__ +#define GOOGLE_PROTOBUF_INLINED_STRING_FIELD_H__ + +#include <string> +#include <utility> + +#include <google/protobuf/stubs/logging.h> +#include <google/protobuf/stubs/common.h> +#include <google/protobuf/arenastring.h> +#include <google/protobuf/message_lite.h> +#include <google/protobuf/port.h> +#include <google/protobuf/stubs/strutil.h> + +// Must be included last. +#include <google/protobuf/port_def.inc> + +#ifdef SWIG +#error "You cannot SWIG proto headers" +#endif + +namespace google { +namespace protobuf { + +class Arena; + +namespace internal { + +// InlinedStringField wraps a TProtoStringType instance and exposes an API similar to +// ArenaStringPtr's wrapping of a TProtoStringType* instance. +// +// default_value parameters are taken for consistency with ArenaStringPtr, but +// are not used for most methods. With inlining, these should be removed from +// the generated binary. +// +// InlinedStringField has a donating mechanism that allows string buffer +// allocated on arena. A string is donated means both the string container and +// the data buffer are on arena. The donating mechanism here is similar to the +// one in ArenaStringPtr with some differences: +// +// When an InlinedStringField is constructed, the donating state is true. This +// is because the string container is directly stored in the message on the +// arena: +// +// Construction: donated=true +// Arena: +// +-----------------------+ +// |Message foo: | +// | +-------------------+ | +// | |InlinedStringField:| | +// | | +-----+ | | +// | | | | | | | | +// | | +-----+ | | +// | +-------------------+ | +// +-----------------------+ +// +// When lvalue Set is called, the donating state is still true. String data will +// be allocated on the arena: +// +// Lvalue Set: donated=true +// Arena: +// +-----------------------+ +// |Message foo: | +// | +-------------------+ | +// | |InlinedStringField:| | +// | | +-----+ | | +// | | | | | | | | +// | | +|----+ | | +// | +--|----------------+ | +// | V | +// | +----------------+ | +// | |'f','o','o',... | | +// | +----------------+ | +// +-----------------------+ +// +// Some operations will undonate a donated string, including: Mutable, +// SetAllocated, Rvalue Set, and Swap with a non-donated string. +// +// For more details of the donating states transitions, go/pd-inlined-string. +class PROTOBUF_EXPORT InlinedStringField { + public: + InlinedStringField() { Init(); } + inline void Init() { new (get_mutable()) TProtoStringType(); } + // Add the dummy parameter just to make InlinedStringField(nullptr) + // unambiguous. + constexpr InlinedStringField( + const ExplicitlyConstructed<TProtoStringType>* /*default_value*/, + bool /*dummy*/) + : value_{} {} + explicit InlinedStringField(const TProtoStringType& default_value); + explicit InlinedStringField(Arena* arena); + ~InlinedStringField() { Destruct(); } + + // Lvalue Set. To save space, we pack the donating states of multiple + // InlinedStringFields into an arc_ui32 `donating_states`. The `mask` + // indicates the position of the bit for this InlinedStringField. `donated` is + // whether this field is donated. + // + // The caller should guarantee that: + // + // `donated == ((donating_states & ~mask) != 0)` + // + // This method never changes the `donating_states`. + void Set(const TProtoStringType* default_value, ConstStringParam value, + Arena* arena, bool donated, arc_ui32* /*donating_states*/, + arc_ui32 /*mask*/) { + (void)arena; + (void)donated; + SetNoArena(default_value, value); + } + + // Rvalue Set. If this field is donated, this method will undonate this field + // by mutating the `donating_states` according to `mask`. + void Set(const TProtoStringType* default_value, TProtoStringType&& value, Arena* arena, + bool donated, arc_ui32* donating_states, arc_ui32 mask); + + template <typename FirstParam> + void Set(FirstParam p1, const char* str, ::google::protobuf::Arena* arena, bool donated, + arc_ui32* donating_states, arc_ui32 mask) { + Set(p1, ConstStringParam(str), arena, donated, donating_states, mask); + } + + template <typename FirstParam> + void Set(FirstParam p1, const char* str, size_t size, ::google::protobuf::Arena* arena, + bool donated, arc_ui32* donating_states, arc_ui32 mask) { + ConstStringParam sp{str, size}; // for string_view and `const string &` + Set(p1, sp, arena, donated, donating_states, mask); + } + + template <typename FirstParam, typename RefWrappedType> + void Set(FirstParam p1, + std::reference_wrapper<RefWrappedType> const_string_ref, + ::google::protobuf::Arena* arena, bool donated, arc_ui32* donating_states, + arc_ui32 mask) { + Set(p1, const_string_ref.get(), arena, donated, donating_states, mask); + } + + template <typename FirstParam, typename SecondParam> + void SetBytes(FirstParam p1, SecondParam&& p2, ::google::protobuf::Arena* arena, + bool donated, arc_ui32* donating_states, arc_ui32 mask) { + Set(p1, static_cast<SecondParam&&>(p2), arena, donated, donating_states, + mask); + } + + template <typename FirstParam> + void SetBytes(FirstParam p1, const void* str, size_t size, + ::google::protobuf::Arena* arena, bool donated, arc_ui32* donating_states, + arc_ui32 mask) { + // Must work whether ConstStringParam is string_view or `const string &` + ConstStringParam sp{static_cast<const char*>(str), size}; + Set(p1, sp, arena, donated, donating_states, mask); + } + + PROTOBUF_NDEBUG_INLINE void SetNoArena(const TProtoStringType* default_value, + StringPiece value); + PROTOBUF_NDEBUG_INLINE void SetNoArena(const TProtoStringType* default_value, + TProtoStringType&& value); + + // Basic accessors. + PROTOBUF_NDEBUG_INLINE const TProtoStringType& Get() const { return GetNoArena(); } + PROTOBUF_NDEBUG_INLINE const TProtoStringType& GetNoArena() const; + + // Mutable returns a TProtoStringType* instance that is heap-allocated. If this + // field is donated, this method undonates this field by mutating the + // `donating_states` according to `mask`, and copies the content of the + // original string to the returning string. + TProtoStringType* Mutable(const LazyString& default_value, Arena* arena, + bool donated, arc_ui32* donating_states, arc_ui32 mask); + TProtoStringType* Mutable(ArenaStringPtr::EmptyDefault, Arena* arena, bool donated, + arc_ui32* donating_states, arc_ui32 mask); + + // Release returns a TProtoStringType* instance that is heap-allocated and is not + // Own()'d by any arena. If the field is not set, this returns nullptr. The + // caller retains ownership. Clears this field back to nullptr state. Used to + // implement release_<field>() methods on generated classes. + PROTOBUF_NODISCARD TProtoStringType* Release(const TProtoStringType* default_value, + Arena* arena, bool donated); + PROTOBUF_NODISCARD TProtoStringType* ReleaseNonDefault( + const TProtoStringType* default_value, Arena* arena); + TProtoStringType* ReleaseNonDefaultNoArena(const TProtoStringType* default_value); + + // Takes a TProtoStringType that is heap-allocated, and takes ownership. The + // TProtoStringType's destructor is registered with the arena. Used to implement + // set_allocated_<field> in generated classes. + // + // If this field is donated, this method undonates this field by mutating the + // `donating_states` according to `mask`. + void SetAllocated(const TProtoStringType* default_value, TProtoStringType* value, + Arena* arena, bool donated, arc_ui32* donating_states, + arc_ui32 mask); + + void SetAllocatedNoArena(const TProtoStringType* default_value, + TProtoStringType* value); + + // When one of `this` and `from` is donated and the other is not donated, this + // method will undonate the donated one and swap the two heap-allocated + // strings. + PROTOBUF_NDEBUG_INLINE void Swap(InlinedStringField* from, + const TProtoStringType* default_value, + Arena* arena, bool donated, + bool from_donated, arc_ui32* donating_states, + arc_ui32* from_donating_states, + arc_ui32 mask); + + // Frees storage (if not on an arena). + PROTOBUF_NDEBUG_INLINE void Destroy(const TProtoStringType* default_value, + Arena* arena) { + if (arena == nullptr) { + DestroyNoArena(default_value); + } + } + PROTOBUF_NDEBUG_INLINE void DestroyNoArena(const TProtoStringType* default_value); + + // Clears content, but keeps allocated TProtoStringType, to avoid the overhead of + // heap operations. After this returns, the content (as seen by the user) will + // always be the empty TProtoStringType. + PROTOBUF_NDEBUG_INLINE void ClearToEmpty() { ClearNonDefaultToEmpty(); } + PROTOBUF_NDEBUG_INLINE void ClearNonDefaultToEmpty() { + get_mutable()->clear(); + } + + // Clears content, but keeps allocated TProtoStringType if arena != nullptr, to + // avoid the overhead of heap operations. After this returns, the content (as + // seen by the user) will always be equal to |default_value|. + void ClearToDefault(const LazyString& default_value, Arena* arena, + bool donated); + + // Returns a mutable pointer, but doesn't initialize the string to the + // default value. + PROTOBUF_NDEBUG_INLINE TProtoStringType* MutableNoArenaNoDefault( + const TProtoStringType* /*default_value*/); + + // Generated code / reflection only! Returns a mutable pointer to the string. + PROTOBUF_NDEBUG_INLINE TProtoStringType* UnsafeMutablePointer(); + + // InlinedStringField doesn't have things like the `default_value` pointer in + // ArenaStringPtr. + bool IsDefault(const TProtoStringType* /*default_value*/) const { return false; } + + private: + void Destruct() { get_mutable()->~TBasicString(); } + + PROTOBUF_NDEBUG_INLINE TProtoStringType* get_mutable(); + PROTOBUF_NDEBUG_INLINE const TProtoStringType* get_const() const; + + alignas(TProtoStringType) char value_[sizeof(TProtoStringType)]; + + TProtoStringType* MutableSlow(::google::protobuf::Arena* arena, bool donated, + arc_ui32* donating_states, arc_ui32 mask); + + + // When constructed in an Arena, we want our destructor to be skipped. + friend class ::google::protobuf::Arena; + typedef void InternalArenaConstructable_; + typedef void DestructorSkippable_; +}; + +inline TProtoStringType* InlinedStringField::get_mutable() { + return reinterpret_cast<TProtoStringType*>(&value_); +} + +inline const TProtoStringType* InlinedStringField::get_const() const { + return reinterpret_cast<const TProtoStringType*>(&value_); +} + +inline InlinedStringField::InlinedStringField( + const TProtoStringType& default_value) { + new (get_mutable()) TProtoStringType(default_value); +} + +inline InlinedStringField::InlinedStringField(Arena* arena) { + Init(); + if (arena != nullptr) { + arena->OwnDestructor(get_mutable()); + } +} + +inline const TProtoStringType& InlinedStringField::GetNoArena() const { + return *get_const(); +} + +inline void InlinedStringField::SetAllocatedNoArena( + const TProtoStringType* /*default_value*/, TProtoStringType* value) { + if (value == nullptr) { + // Currently, inlined string field can't have non empty default. + get_mutable()->clear(); + } else { + get_mutable()->assign(std::move(*value)); + delete value; + } +} + +inline void InlinedStringField::DestroyNoArena(const TProtoStringType*) { + // This is invoked from the generated message's ArenaDtor, which is used to + // clean up objects not allocated on the Arena. + this->~InlinedStringField(); +} + +inline TProtoStringType* InlinedStringField::ReleaseNonDefaultNoArena( + const TProtoStringType* /*default_value*/) { + // Currently, inlined string field can't have non empty default. + auto* released = new TProtoStringType(); + get_mutable()->swap(*released); + return released; +} + +inline void InlinedStringField::SetNoArena(const TProtoStringType* /*default_value*/, + StringPiece value) { + get_mutable()->assign(value.data(), value.length()); +} + +inline void InlinedStringField::SetNoArena(const TProtoStringType* /*default_value*/, + TProtoStringType&& value) { + get_mutable()->assign(std::move(value)); +} + +inline void InlinedStringField::Swap( + InlinedStringField* from, const TProtoStringType* /*default_value*/, + Arena* arena, bool donated, bool from_donated, arc_ui32* donating_states, + arc_ui32* from_donating_states, arc_ui32 mask) { +#if GOOGLE_PROTOBUF_INTERNAL_DONATE_STEAL_INLINE + // If one is donated and the other is not, undonate the donated one. + if (donated && !from_donated) { + MutableSlow(arena, donated, donating_states, mask); + } else if (!donated && from_donated) { + from->MutableSlow(arena, from_donated, from_donating_states, mask); + } + // Then, swap the two undonated strings. +#else + (void)arena; + (void)donated; + (void)from_donated; + (void)donating_states; + (void)from_donating_states; + (void)mask; +#endif + get_mutable()->swap(*from->get_mutable()); +} + +inline TProtoStringType* InlinedStringField::MutableNoArenaNoDefault( + const TProtoStringType*) { + return get_mutable(); +} + +inline TProtoStringType* InlinedStringField::UnsafeMutablePointer() { + return get_mutable(); +} + +} // namespace internal +} // namespace protobuf +} // namespace google + +#include <google/protobuf/port_undef.inc> + +#endif // GOOGLE_PROTOBUF_INLINED_STRING_FIELD_H__ diff --git a/contrib/libs/protobuf_old/src/google/protobuf/io/coded_stream.cc b/contrib/libs/protobuf_old/src/google/protobuf/io/coded_stream.cc new file mode 100644 index 0000000000..c209aeabad --- /dev/null +++ b/contrib/libs/protobuf_old/src/google/protobuf/io/coded_stream.cc @@ -0,0 +1,978 @@ +// 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: kenton@google.com (Kenton Varda) +// Based on original Protocol Buffers design by +// Sanjay Ghemawat, Jeff Dean, and others. +// +// This implementation is heavily optimized to make reads and writes +// of small values (especially varints) as fast as possible. In +// particular, we optimize for the common case that a read or a write +// will not cross the end of the buffer, since we can avoid a lot +// of branching in this case. + +#include <google/protobuf/io/coded_stream.h> + +#include <limits.h> + +#include <algorithm> +#include <cstring> +#include <utility> + +#include <google/protobuf/stubs/logging.h> +#include <google/protobuf/stubs/common.h> +#include <google/protobuf/arena.h> +#include <google/protobuf/io/zero_copy_stream.h> +#include <google/protobuf/io/zero_copy_stream_impl_lite.h> +#include <google/protobuf/stubs/stl_util.h> + + +#include <google/protobuf/port_def.inc> + +namespace google { +namespace protobuf { +namespace io { + +namespace { + +static const int kMaxVarintBytes = 10; +static const int kMaxVarint32Bytes = 5; + + +inline bool NextNonEmpty(ZeroCopyInputStream* input, const void** data, + int* size) { + bool success; + do { + success = input->Next(data, size); + } while (success && *size == 0); + return success; +} + +} // namespace + +// CodedInputStream ================================================== + +CodedInputStream::~CodedInputStream() { + if (input_ != NULL) { + BackUpInputToCurrentPosition(); + } +} + +// Static. +int CodedInputStream::default_recursion_limit_ = 100; + + +void CodedInputStream::BackUpInputToCurrentPosition() { + int backup_bytes = BufferSize() + buffer_size_after_limit_ + overflow_bytes_; + if (backup_bytes > 0) { + input_->BackUp(backup_bytes); + + // total_bytes_read_ doesn't include overflow_bytes_. + total_bytes_read_ -= BufferSize() + buffer_size_after_limit_; + buffer_end_ = buffer_; + buffer_size_after_limit_ = 0; + overflow_bytes_ = 0; + } +} + +inline void CodedInputStream::RecomputeBufferLimits() { + buffer_end_ += buffer_size_after_limit_; + int closest_limit = std::min(current_limit_, total_bytes_limit_); + if (closest_limit < total_bytes_read_) { + // The limit position is in the current buffer. We must adjust + // the buffer size accordingly. + buffer_size_after_limit_ = total_bytes_read_ - closest_limit; + buffer_end_ -= buffer_size_after_limit_; + } else { + buffer_size_after_limit_ = 0; + } +} + +CodedInputStream::Limit CodedInputStream::PushLimit(int byte_limit) { + // Current position relative to the beginning of the stream. + int current_position = CurrentPosition(); + + Limit old_limit = current_limit_; + + // security: byte_limit is possibly evil, so check for negative values + // and overflow. Also check that the new requested limit is before the + // previous limit; otherwise we continue to enforce the previous limit. + if (PROTOBUF_PREDICT_TRUE(byte_limit >= 0 && + byte_limit <= INT_MAX - current_position && + byte_limit < current_limit_ - current_position)) { + current_limit_ = current_position + byte_limit; + RecomputeBufferLimits(); + } + + return old_limit; +} + +void CodedInputStream::PopLimit(Limit limit) { + // The limit passed in is actually the *old* limit, which we returned from + // PushLimit(). + current_limit_ = limit; + RecomputeBufferLimits(); + + // We may no longer be at a legitimate message end. ReadTag() needs to be + // called again to find out. + legitimate_message_end_ = false; +} + +std::pair<CodedInputStream::Limit, int> +CodedInputStream::IncrementRecursionDepthAndPushLimit(int byte_limit) { + return std::make_pair(PushLimit(byte_limit), --recursion_budget_); +} + +CodedInputStream::Limit CodedInputStream::ReadLengthAndPushLimit() { + arc_ui32 length; + return PushLimit(ReadVarint32(&length) ? length : 0); +} + +bool CodedInputStream::DecrementRecursionDepthAndPopLimit(Limit limit) { + bool result = ConsumedEntireMessage(); + PopLimit(limit); + GOOGLE_DCHECK_LT(recursion_budget_, recursion_limit_); + ++recursion_budget_; + return result; +} + +bool CodedInputStream::CheckEntireMessageConsumedAndPopLimit(Limit limit) { + bool result = ConsumedEntireMessage(); + PopLimit(limit); + return result; +} + +int CodedInputStream::BytesUntilLimit() const { + if (current_limit_ == INT_MAX) return -1; + int current_position = CurrentPosition(); + + return current_limit_ - current_position; +} + +void CodedInputStream::SetTotalBytesLimit(int total_bytes_limit) { + // Make sure the limit isn't already past, since this could confuse other + // code. + int current_position = CurrentPosition(); + total_bytes_limit_ = std::max(current_position, total_bytes_limit); + RecomputeBufferLimits(); +} + +int CodedInputStream::BytesUntilTotalBytesLimit() const { + if (total_bytes_limit_ == INT_MAX) return -1; + return total_bytes_limit_ - CurrentPosition(); +} + +void CodedInputStream::PrintTotalBytesLimitError() { + GOOGLE_LOG(ERROR) + << "A protocol message was rejected because it was too " + "big (more than " + << total_bytes_limit_ + << " bytes). To increase the limit (or to disable these " + "warnings), see CodedInputStream::SetTotalBytesLimit() " + "in third_party/protobuf/src/google/protobuf/io/coded_stream.h."; +} + +bool CodedInputStream::SkipFallback(int count, int original_buffer_size) { + if (buffer_size_after_limit_ > 0) { + // We hit a limit inside this buffer. Advance to the limit and fail. + Advance(original_buffer_size); + return false; + } + + count -= original_buffer_size; + buffer_ = NULL; + buffer_end_ = buffer_; + + // Make sure this skip doesn't try to skip past the current limit. + int closest_limit = std::min(current_limit_, total_bytes_limit_); + int bytes_until_limit = closest_limit - total_bytes_read_; + if (bytes_until_limit < count) { + // We hit the limit. Skip up to it then fail. + if (bytes_until_limit > 0) { + total_bytes_read_ = closest_limit; + input_->Skip(bytes_until_limit); + } + return false; + } + + if (!input_->Skip(count)) { + total_bytes_read_ = input_->ByteCount(); + return false; + } + total_bytes_read_ += count; + return true; +} + +bool CodedInputStream::GetDirectBufferPointer(const void** data, int* size) { + if (BufferSize() == 0 && !Refresh()) return false; + + *data = buffer_; + *size = BufferSize(); + return true; +} + +bool CodedInputStream::ReadRaw(void* buffer, int size) { + int current_buffer_size; + while ((current_buffer_size = BufferSize()) < size) { + // Reading past end of buffer. Copy what we have, then refresh. + memcpy(buffer, buffer_, current_buffer_size); + buffer = reinterpret_cast<uint8_t*>(buffer) + current_buffer_size; + size -= current_buffer_size; + Advance(current_buffer_size); + if (!Refresh()) return false; + } + + memcpy(buffer, buffer_, size); + Advance(size); + + return true; +} + +bool CodedInputStream::ReadString(TProtoStringType* buffer, int size) { + if (size < 0) return false; // security: size is often user-supplied + + if (BufferSize() >= size) { + STLStringResizeUninitialized(buffer, size); + std::pair<char*, bool> z = as_string_data(buffer); + if (z.second) { + // Oddly enough, memcpy() requires its first two args to be non-NULL even + // if we copy 0 bytes. So, we have ensured that z.first is non-NULL here. + GOOGLE_DCHECK(z.first != NULL); + memcpy(z.first, buffer_, size); + Advance(size); + } + return true; + } + + return ReadStringFallback(buffer, size); +} + +bool CodedInputStream::ReadStringFallback(TProtoStringType* buffer, int size) { + if (!buffer->empty()) { + buffer->clear(); + } + + int closest_limit = std::min(current_limit_, total_bytes_limit_); + if (closest_limit != INT_MAX) { + int bytes_to_limit = closest_limit - CurrentPosition(); + if (bytes_to_limit > 0 && size > 0 && size <= bytes_to_limit) { + buffer->reserve(size); + } + } + + int current_buffer_size; + while ((current_buffer_size = BufferSize()) < size) { + // Some STL implementations "helpfully" crash on buffer->append(NULL, 0). + if (current_buffer_size != 0) { + // Note: string1.append(string2) is O(string2.size()) (as opposed to + // O(string1.size() + string2.size()), which would be bad). + buffer->append(reinterpret_cast<const char*>(buffer_), + current_buffer_size); + } + size -= current_buffer_size; + Advance(current_buffer_size); + if (!Refresh()) return false; + } + + buffer->append(reinterpret_cast<const char*>(buffer_), size); + Advance(size); + + return true; +} + + +bool CodedInputStream::ReadLittleEndian32Fallback(arc_ui32* value) { + uint8_t bytes[sizeof(*value)]; + + const uint8_t* ptr; + if (BufferSize() >= static_cast<arc_i64>(sizeof(*value))) { + // Fast path: Enough bytes in the buffer to read directly. + ptr = buffer_; + Advance(sizeof(*value)); + } else { + // Slow path: Had to read past the end of the buffer. + if (!ReadRaw(bytes, sizeof(*value))) return false; + ptr = bytes; + } + ReadLittleEndian32FromArray(ptr, value); + return true; +} + +bool CodedInputStream::ReadLittleEndian64Fallback(arc_ui64* value) { + uint8_t bytes[sizeof(*value)]; + + const uint8_t* ptr; + if (BufferSize() >= static_cast<arc_i64>(sizeof(*value))) { + // Fast path: Enough bytes in the buffer to read directly. + ptr = buffer_; + Advance(sizeof(*value)); + } else { + // Slow path: Had to read past the end of the buffer. + if (!ReadRaw(bytes, sizeof(*value))) return false; + ptr = bytes; + } + ReadLittleEndian64FromArray(ptr, value); + return true; +} + +namespace { + +// Decodes varint64 with known size, N, and returns next pointer. Knowing N at +// compile time, compiler can generate optimal code. For example, instead of +// subtracting 0x80 at each iteration, it subtracts properly shifted mask once. +template <size_t N> +const uint8_t* DecodeVarint64KnownSize(const uint8_t* buffer, arc_ui64* value) { + GOOGLE_DCHECK_GT(N, 0); + arc_ui64 result = static_cast<arc_ui64>(buffer[N - 1]) << (7 * (N - 1)); + for (size_t i = 0, offset = 0; i < N - 1; i++, offset += 7) { + result += static_cast<arc_ui64>(buffer[i] - 0x80) << offset; + } + *value = result; + return buffer + N; +} + +// Read a varint from the given buffer, write it to *value, and return a pair. +// The first part of the pair is true iff the read was successful. The second +// part is buffer + (number of bytes read). This function is always inlined, +// so returning a pair is costless. +PROTOBUF_ALWAYS_INLINE +::std::pair<bool, const uint8_t*> ReadVarint32FromArray(arc_ui32 first_byte, + const uint8_t* buffer, + arc_ui32* value); +inline ::std::pair<bool, const uint8_t*> ReadVarint32FromArray( + arc_ui32 first_byte, const uint8_t* buffer, arc_ui32* value) { + // Fast path: We have enough bytes left in the buffer to guarantee that + // this read won't cross the end, so we can skip the checks. + GOOGLE_DCHECK_EQ(*buffer, first_byte); + GOOGLE_DCHECK_EQ(first_byte & 0x80, 0x80) << first_byte; + const uint8_t* ptr = buffer; + arc_ui32 b; + arc_ui32 result = first_byte - 0x80; + ++ptr; // We just processed the first byte. Move on to the second. + b = *(ptr++); + result += b << 7; + if (!(b & 0x80)) goto done; + result -= 0x80 << 7; + b = *(ptr++); + result += b << 14; + if (!(b & 0x80)) goto done; + result -= 0x80 << 14; + b = *(ptr++); + result += b << 21; + if (!(b & 0x80)) goto done; + result -= 0x80 << 21; + b = *(ptr++); + result += b << 28; + if (!(b & 0x80)) goto done; + // "result -= 0x80 << 28" is irrevelant. + + // If the input is larger than 32 bits, we still need to read it all + // and discard the high-order bits. + for (int i = 0; i < kMaxVarintBytes - kMaxVarint32Bytes; i++) { + b = *(ptr++); + if (!(b & 0x80)) goto done; + } + + // We have overrun the maximum size of a varint (10 bytes). Assume + // the data is corrupt. + return std::make_pair(false, ptr); + +done: + *value = result; + return std::make_pair(true, ptr); +} + +PROTOBUF_ALWAYS_INLINE::std::pair<bool, const uint8_t*> ReadVarint64FromArray( + const uint8_t* buffer, arc_ui64* value); +inline ::std::pair<bool, const uint8_t*> ReadVarint64FromArray( + const uint8_t* buffer, arc_ui64* value) { + // Assumes varint64 is at least 2 bytes. + GOOGLE_DCHECK_GE(buffer[0], 128); + + const uint8_t* next; + if (buffer[1] < 128) { + next = DecodeVarint64KnownSize<2>(buffer, value); + } else if (buffer[2] < 128) { + next = DecodeVarint64KnownSize<3>(buffer, value); + } else if (buffer[3] < 128) { + next = DecodeVarint64KnownSize<4>(buffer, value); + } else if (buffer[4] < 128) { + next = DecodeVarint64KnownSize<5>(buffer, value); + } else if (buffer[5] < 128) { + next = DecodeVarint64KnownSize<6>(buffer, value); + } else if (buffer[6] < 128) { + next = DecodeVarint64KnownSize<7>(buffer, value); + } else if (buffer[7] < 128) { + next = DecodeVarint64KnownSize<8>(buffer, value); + } else if (buffer[8] < 128) { + next = DecodeVarint64KnownSize<9>(buffer, value); + } else if (buffer[9] < 128) { + next = DecodeVarint64KnownSize<10>(buffer, value); + } else { + // We have overrun the maximum size of a varint (10 bytes). Assume + // the data is corrupt. + return std::make_pair(false, buffer + 11); + } + + return std::make_pair(true, next); +} + +} // namespace + +bool CodedInputStream::ReadVarint32Slow(arc_ui32* value) { + // Directly invoke ReadVarint64Fallback, since we already tried to optimize + // for one-byte varints. + std::pair<arc_ui64, bool> p = ReadVarint64Fallback(); + *value = static_cast<arc_ui32>(p.first); + return p.second; +} + +arc_i64 CodedInputStream::ReadVarint32Fallback(arc_ui32 first_byte_or_zero) { + if (BufferSize() >= kMaxVarintBytes || + // Optimization: We're also safe if the buffer is non-empty and it ends + // with a byte that would terminate a varint. + (buffer_end_ > buffer_ && !(buffer_end_[-1] & 0x80))) { + GOOGLE_DCHECK_NE(first_byte_or_zero, 0) + << "Caller should provide us with *buffer_ when buffer is non-empty"; + arc_ui32 temp; + ::std::pair<bool, const uint8_t*> p = + ReadVarint32FromArray(first_byte_or_zero, buffer_, &temp); + if (!p.first) return -1; + buffer_ = p.second; + return temp; + } else { + // Really slow case: we will incur the cost of an extra function call here, + // but moving this out of line reduces the size of this function, which + // improves the common case. In micro benchmarks, this is worth about 10-15% + arc_ui32 temp; + return ReadVarint32Slow(&temp) ? static_cast<arc_i64>(temp) : -1; + } +} + +int CodedInputStream::ReadVarintSizeAsIntSlow() { + // Directly invoke ReadVarint64Fallback, since we already tried to optimize + // for one-byte varints. + std::pair<arc_ui64, bool> p = ReadVarint64Fallback(); + if (!p.second || p.first > static_cast<arc_ui64>(INT_MAX)) return -1; + return p.first; +} + +int CodedInputStream::ReadVarintSizeAsIntFallback() { + if (BufferSize() >= kMaxVarintBytes || + // Optimization: We're also safe if the buffer is non-empty and it ends + // with a byte that would terminate a varint. + (buffer_end_ > buffer_ && !(buffer_end_[-1] & 0x80))) { + arc_ui64 temp; + ::std::pair<bool, const uint8_t*> p = ReadVarint64FromArray(buffer_, &temp); + if (!p.first || temp > static_cast<arc_ui64>(INT_MAX)) return -1; + buffer_ = p.second; + return temp; + } else { + // Really slow case: we will incur the cost of an extra function call here, + // but moving this out of line reduces the size of this function, which + // improves the common case. In micro benchmarks, this is worth about 10-15% + return ReadVarintSizeAsIntSlow(); + } +} + +arc_ui32 CodedInputStream::ReadTagSlow() { + if (buffer_ == buffer_end_) { + // Call refresh. + if (!Refresh()) { + // Refresh failed. Make sure that it failed due to EOF, not because + // we hit total_bytes_limit_, which, unlike normal limits, is not a + // valid place to end a message. + int current_position = total_bytes_read_ - buffer_size_after_limit_; + if (current_position >= total_bytes_limit_) { + // Hit total_bytes_limit_. But if we also hit the normal limit, + // we're still OK. + legitimate_message_end_ = current_limit_ == total_bytes_limit_; + } else { + legitimate_message_end_ = true; + } + return 0; + } + } + + // For the slow path, just do a 64-bit read. Try to optimize for one-byte tags + // again, since we have now refreshed the buffer. + arc_ui64 result = 0; + if (!ReadVarint64(&result)) return 0; + return static_cast<arc_ui32>(result); +} + +arc_ui32 CodedInputStream::ReadTagFallback(arc_ui32 first_byte_or_zero) { + const int buf_size = BufferSize(); + if (buf_size >= kMaxVarintBytes || + // Optimization: We're also safe if the buffer is non-empty and it ends + // with a byte that would terminate a varint. + (buf_size > 0 && !(buffer_end_[-1] & 0x80))) { + GOOGLE_DCHECK_EQ(first_byte_or_zero, buffer_[0]); + if (first_byte_or_zero == 0) { + ++buffer_; + return 0; + } + arc_ui32 tag; + ::std::pair<bool, const uint8_t*> p = + ReadVarint32FromArray(first_byte_or_zero, buffer_, &tag); + if (!p.first) { + return 0; + } + buffer_ = p.second; + return tag; + } else { + // We are commonly at a limit when attempting to read tags. Try to quickly + // detect this case without making another function call. + if ((buf_size == 0) && + ((buffer_size_after_limit_ > 0) || + (total_bytes_read_ == current_limit_)) && + // Make sure that the limit we hit is not total_bytes_limit_, since + // in that case we still need to call Refresh() so that it prints an + // error. + total_bytes_read_ - buffer_size_after_limit_ < total_bytes_limit_) { + // We hit a byte limit. + legitimate_message_end_ = true; + return 0; + } + return ReadTagSlow(); + } +} + +bool CodedInputStream::ReadVarint64Slow(arc_ui64* value) { + // Slow path: This read might cross the end of the buffer, so we + // need to check and refresh the buffer if and when it does. + + arc_ui64 result = 0; + int count = 0; + arc_ui32 b; + + do { + if (count == kMaxVarintBytes) { + *value = 0; + return false; + } + while (buffer_ == buffer_end_) { + if (!Refresh()) { + *value = 0; + return false; + } + } + b = *buffer_; + result |= static_cast<arc_ui64>(b & 0x7F) << (7 * count); + Advance(1); + ++count; + } while (b & 0x80); + + *value = result; + return true; +} + +std::pair<arc_ui64, bool> CodedInputStream::ReadVarint64Fallback() { + if (BufferSize() >= kMaxVarintBytes || + // Optimization: We're also safe if the buffer is non-empty and it ends + // with a byte that would terminate a varint. + (buffer_end_ > buffer_ && !(buffer_end_[-1] & 0x80))) { + arc_ui64 temp; + ::std::pair<bool, const uint8_t*> p = ReadVarint64FromArray(buffer_, &temp); + if (!p.first) { + return std::make_pair(0, false); + } + buffer_ = p.second; + return std::make_pair(temp, true); + } else { + arc_ui64 temp; + bool success = ReadVarint64Slow(&temp); + return std::make_pair(temp, success); + } +} + +bool CodedInputStream::Refresh() { + GOOGLE_DCHECK_EQ(0, BufferSize()); + + if (buffer_size_after_limit_ > 0 || overflow_bytes_ > 0 || + total_bytes_read_ == current_limit_) { + // We've hit a limit. Stop. + int current_position = total_bytes_read_ - buffer_size_after_limit_; + + if (current_position >= total_bytes_limit_ && + total_bytes_limit_ != current_limit_) { + // Hit total_bytes_limit_. + PrintTotalBytesLimitError(); + } + + return false; + } + + const void* void_buffer; + int buffer_size; + if (NextNonEmpty(input_, &void_buffer, &buffer_size)) { + buffer_ = reinterpret_cast<const uint8_t*>(void_buffer); + buffer_end_ = buffer_ + buffer_size; + GOOGLE_CHECK_GE(buffer_size, 0); + + if (total_bytes_read_ <= INT_MAX - buffer_size) { + total_bytes_read_ += buffer_size; + } else { + // Overflow. Reset buffer_end_ to not include the bytes beyond INT_MAX. + // We can't get that far anyway, because total_bytes_limit_ is guaranteed + // to be less than it. We need to keep track of the number of bytes + // we discarded, though, so that we can call input_->BackUp() to back + // up over them on destruction. + + // The following line is equivalent to: + // overflow_bytes_ = total_bytes_read_ + buffer_size - INT_MAX; + // except that it avoids overflows. Signed integer overflow has + // undefined results according to the C standard. + overflow_bytes_ = total_bytes_read_ - (INT_MAX - buffer_size); + buffer_end_ -= overflow_bytes_; + total_bytes_read_ = INT_MAX; + } + + RecomputeBufferLimits(); + return true; + } else { + buffer_ = NULL; + buffer_end_ = NULL; + return false; + } +} + +// CodedOutputStream ================================================= + +void EpsCopyOutputStream::EnableAliasing(bool enabled) { + aliasing_enabled_ = enabled && stream_->AllowsAliasing(); +} + +int64_t EpsCopyOutputStream::ByteCount(uint8_t* ptr) const { + // Calculate the current offset relative to the end of the stream buffer. + int delta = (end_ - ptr) + (buffer_end_ ? 0 : kSlopBytes); + return stream_->ByteCount() - delta; +} + +// Flushes what's written out to the underlying ZeroCopyOutputStream buffers. +// Returns the size remaining in the buffer and sets buffer_end_ to the start +// of the remaining buffer, ie. [buffer_end_, buffer_end_ + return value) +int EpsCopyOutputStream::Flush(uint8_t* ptr) { + while (buffer_end_ && ptr > end_) { + int overrun = ptr - end_; + GOOGLE_DCHECK(!had_error_); + GOOGLE_DCHECK(overrun <= kSlopBytes); // NOLINT + ptr = Next() + overrun; + if (had_error_) return 0; + } + int s; + if (buffer_end_) { + std::memcpy(buffer_end_, buffer_, ptr - buffer_); + buffer_end_ += ptr - buffer_; + s = end_ - ptr; + } else { + // The stream is writing directly in the ZeroCopyOutputStream buffer. + s = end_ + kSlopBytes - ptr; + buffer_end_ = ptr; + } + GOOGLE_DCHECK(s >= 0); // NOLINT + return s; +} + +uint8_t* EpsCopyOutputStream::Trim(uint8_t* ptr) { + if (had_error_) return ptr; + int s = Flush(ptr); + if (s) stream_->BackUp(s); + // Reset to initial state (expecting new buffer) + buffer_end_ = end_ = buffer_; + return buffer_; +} + + +uint8_t* EpsCopyOutputStream::FlushAndResetBuffer(uint8_t* ptr) { + if (had_error_) return buffer_; + int s = Flush(ptr); + if (had_error_) return buffer_; + return SetInitialBuffer(buffer_end_, s); +} + +bool EpsCopyOutputStream::Skip(int count, uint8_t** pp) { + if (count < 0) return false; + if (had_error_) { + *pp = buffer_; + return false; + } + int size = Flush(*pp); + if (had_error_) { + *pp = buffer_; + return false; + } + void* data = buffer_end_; + while (count > size) { + count -= size; + if (!stream_->Next(&data, &size)) { + *pp = Error(); + return false; + } + } + *pp = SetInitialBuffer(static_cast<uint8_t*>(data) + count, size - count); + return true; +} + +bool EpsCopyOutputStream::GetDirectBufferPointer(void** data, int* size, + uint8_t** pp) { + if (had_error_) { + *pp = buffer_; + return false; + } + *size = Flush(*pp); + if (had_error_) { + *pp = buffer_; + return false; + } + *data = buffer_end_; + while (*size == 0) { + if (!stream_->Next(data, size)) { + *pp = Error(); + return false; + } + } + *pp = SetInitialBuffer(*data, *size); + return true; +} + +uint8_t* EpsCopyOutputStream::GetDirectBufferForNBytesAndAdvance(int size, + uint8_t** pp) { + if (had_error_) { + *pp = buffer_; + return nullptr; + } + int s = Flush(*pp); + if (had_error_) { + *pp = buffer_; + return nullptr; + } + if (s >= size) { + auto res = buffer_end_; + *pp = SetInitialBuffer(buffer_end_ + size, s - size); + return res; + } else { + *pp = SetInitialBuffer(buffer_end_, s); + return nullptr; + } +} + +uint8_t* EpsCopyOutputStream::Next() { + GOOGLE_DCHECK(!had_error_); // NOLINT + if (PROTOBUF_PREDICT_FALSE(stream_ == nullptr)) return Error(); + if (buffer_end_) { + // We're in the patch buffer and need to fill up the previous buffer. + std::memcpy(buffer_end_, buffer_, end_ - buffer_); + uint8_t* ptr; + int size; + do { + void* data; + if (PROTOBUF_PREDICT_FALSE(!stream_->Next(&data, &size))) { + // Stream has an error, we use the patch buffer to continue to be + // able to write. + return Error(); + } + ptr = static_cast<uint8_t*>(data); + } while (size == 0); + if (PROTOBUF_PREDICT_TRUE(size > kSlopBytes)) { + std::memcpy(ptr, end_, kSlopBytes); + end_ = ptr + size - kSlopBytes; + buffer_end_ = nullptr; + return ptr; + } else { + GOOGLE_DCHECK(size > 0); // NOLINT + // Buffer to small + std::memmove(buffer_, end_, kSlopBytes); + buffer_end_ = ptr; + end_ = buffer_ + size; + return buffer_; + } + } else { + std::memcpy(buffer_, end_, kSlopBytes); + buffer_end_ = end_; + end_ = buffer_ + kSlopBytes; + return buffer_; + } +} + +uint8_t* EpsCopyOutputStream::EnsureSpaceFallback(uint8_t* ptr) { + do { + if (PROTOBUF_PREDICT_FALSE(had_error_)) return buffer_; + int overrun = ptr - end_; + GOOGLE_DCHECK(overrun >= 0); // NOLINT + GOOGLE_DCHECK(overrun <= kSlopBytes); // NOLINT + ptr = Next() + overrun; + } while (ptr >= end_); + GOOGLE_DCHECK(ptr < end_); // NOLINT + return ptr; +} + +uint8_t* EpsCopyOutputStream::WriteRawFallback(const void* data, int size, + uint8_t* ptr) { + int s = GetSize(ptr); + while (s < size) { + std::memcpy(ptr, data, s); + size -= s; + data = static_cast<const uint8_t*>(data) + s; + ptr = EnsureSpaceFallback(ptr + s); + s = GetSize(ptr); + } + std::memcpy(ptr, data, size); + return ptr + size; +} + +uint8_t* EpsCopyOutputStream::WriteAliasedRaw(const void* data, int size, + uint8_t* ptr) { + if (size < GetSize(ptr) + ) { + return WriteRaw(data, size, ptr); + } else { + ptr = Trim(ptr); + if (stream_->WriteAliasedRaw(data, size)) return ptr; + return Error(); + } +} + +#ifndef PROTOBUF_LITTLE_ENDIAN +uint8_t* EpsCopyOutputStream::WriteRawLittleEndian32(const void* data, int size, + uint8_t* ptr) { + auto p = static_cast<const uint8_t*>(data); + auto end = p + size; + while (end - p >= kSlopBytes) { + ptr = EnsureSpace(ptr); + arc_ui32 buffer[4]; + static_assert(sizeof(buffer) == kSlopBytes, "Buffer must be kSlopBytes"); + std::memcpy(buffer, p, kSlopBytes); + p += kSlopBytes; + for (auto x : buffer) + ptr = CodedOutputStream::WriteLittleEndian32ToArray(x, ptr); + } + while (p < end) { + ptr = EnsureSpace(ptr); + arc_ui32 buffer; + std::memcpy(&buffer, p, 4); + p += 4; + ptr = CodedOutputStream::WriteLittleEndian32ToArray(buffer, ptr); + } + return ptr; +} + +uint8_t* EpsCopyOutputStream::WriteRawLittleEndian64(const void* data, int size, + uint8_t* ptr) { + auto p = static_cast<const uint8_t*>(data); + auto end = p + size; + while (end - p >= kSlopBytes) { + ptr = EnsureSpace(ptr); + arc_ui64 buffer[2]; + static_assert(sizeof(buffer) == kSlopBytes, "Buffer must be kSlopBytes"); + std::memcpy(buffer, p, kSlopBytes); + p += kSlopBytes; + for (auto x : buffer) + ptr = CodedOutputStream::WriteLittleEndian64ToArray(x, ptr); + } + while (p < end) { + ptr = EnsureSpace(ptr); + arc_ui64 buffer; + std::memcpy(&buffer, p, 8); + p += 8; + ptr = CodedOutputStream::WriteLittleEndian64ToArray(buffer, ptr); + } + return ptr; +} +#endif + + +uint8_t* EpsCopyOutputStream::WriteStringMaybeAliasedOutline(arc_ui32 num, + const TProtoStringType& s, + uint8_t* ptr) { + ptr = EnsureSpace(ptr); + arc_ui32 size = s.size(); + ptr = WriteLengthDelim(num, size, ptr); + return WriteRawMaybeAliased(s.data(), size, ptr); +} + +uint8_t* EpsCopyOutputStream::WriteStringOutline(arc_ui32 num, const TProtoStringType& s, + uint8_t* ptr) { + ptr = EnsureSpace(ptr); + arc_ui32 size = s.size(); + ptr = WriteLengthDelim(num, size, ptr); + return WriteRaw(s.data(), size, ptr); +} + +std::atomic<bool> CodedOutputStream::default_serialization_deterministic_{ + false}; + +CodedOutputStream::CodedOutputStream(ZeroCopyOutputStream* stream, + bool do_eager_refresh) + : impl_(stream, IsDefaultSerializationDeterministic(), &cur_), + start_count_(stream->ByteCount()) { + if (do_eager_refresh) { + void* data; + int size; + if (!stream->Next(&data, &size) || size == 0) return; + cur_ = impl_.SetInitialBuffer(data, size); + } +} + +CodedOutputStream::~CodedOutputStream() { Trim(); } + + +uint8_t* CodedOutputStream::WriteStringWithSizeToArray(const TProtoStringType& str, + uint8_t* target) { + GOOGLE_DCHECK_LE(str.size(), std::numeric_limits<arc_ui32>::max()); + target = WriteVarint32ToArray(str.size(), target); + return WriteStringToArray(str, target); +} + +uint8_t* CodedOutputStream::WriteVarint32ToArrayOutOfLineHelper(arc_ui32 value, + uint8_t* target) { + GOOGLE_DCHECK_GE(value, 0x80); + target[0] |= static_cast<uint8_t>(0x80); + value >>= 7; + target[1] = static_cast<uint8_t>(value); + if (value < 0x80) { + return target + 2; + } + target += 2; + do { + // Turn on continuation bit in the byte we just wrote. + target[-1] |= static_cast<uint8_t>(0x80); + value >>= 7; + *target = static_cast<uint8_t>(value); + ++target; + } while (value >= 0x80); + return target; +} + +} // namespace io +} // namespace protobuf +} // namespace google + +#include <google/protobuf/port_undef.inc> diff --git a/contrib/libs/protobuf_old/src/google/protobuf/io/coded_stream.h b/contrib/libs/protobuf_old/src/google/protobuf/io/coded_stream.h new file mode 100644 index 0000000000..64d4068f5f --- /dev/null +++ b/contrib/libs/protobuf_old/src/google/protobuf/io/coded_stream.h @@ -0,0 +1,1775 @@ +// 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: kenton@google.com (Kenton Varda) +// Based on original Protocol Buffers design by +// Sanjay Ghemawat, Jeff Dean, and others. +// +// This file contains the CodedInputStream and CodedOutputStream classes, +// which wrap a ZeroCopyInputStream or ZeroCopyOutputStream, respectively, +// and allow you to read or write individual pieces of data in various +// formats. In particular, these implement the varint encoding for +// integers, a simple variable-length encoding in which smaller numbers +// take fewer bytes. +// +// Typically these classes will only be used internally by the protocol +// buffer library in order to encode and decode protocol buffers. Clients +// of the library only need to know about this class if they wish to write +// custom message parsing or serialization procedures. +// +// CodedOutputStream example: +// // Write some data to "myfile". First we write a 4-byte "magic number" +// // to identify the file type, then write a length-delimited string. The +// // string is composed of a varint giving the length followed by the raw +// // bytes. +// int fd = open("myfile", O_CREAT | O_WRONLY); +// ZeroCopyOutputStream* raw_output = new FileOutputStream(fd); +// CodedOutputStream* coded_output = new CodedOutputStream(raw_output); +// +// int magic_number = 1234; +// char text[] = "Hello world!"; +// coded_output->WriteLittleEndian32(magic_number); +// coded_output->WriteVarint32(strlen(text)); +// coded_output->WriteRaw(text, strlen(text)); +// +// delete coded_output; +// delete raw_output; +// close(fd); +// +// CodedInputStream example: +// // Read a file created by the above code. +// int fd = open("myfile", O_RDONLY); +// ZeroCopyInputStream* raw_input = new FileInputStream(fd); +// CodedInputStream* coded_input = new CodedInputStream(raw_input); +// +// coded_input->ReadLittleEndian32(&magic_number); +// if (magic_number != 1234) { +// cerr << "File not in expected format." << endl; +// return; +// } +// +// arc_ui32 size; +// coded_input->ReadVarint32(&size); +// +// char* text = new char[size + 1]; +// coded_input->ReadRaw(buffer, size); +// text[size] = '\0'; +// +// delete coded_input; +// delete raw_input; +// close(fd); +// +// cout << "Text is: " << text << endl; +// delete [] text; +// +// For those who are interested, varint encoding is defined as follows: +// +// The encoding operates on unsigned integers of up to 64 bits in length. +// Each byte of the encoded value has the format: +// * bits 0-6: Seven bits of the number being encoded. +// * bit 7: Zero if this is the last byte in the encoding (in which +// case all remaining bits of the number are zero) or 1 if +// more bytes follow. +// The first byte contains the least-significant 7 bits of the number, the +// second byte (if present) contains the next-least-significant 7 bits, +// and so on. So, the binary number 1011000101011 would be encoded in two +// bytes as "10101011 00101100". +// +// In theory, varint could be used to encode integers of any length. +// However, for practicality we set a limit at 64 bits. The maximum encoded +// length of a number is thus 10 bytes. + +#ifndef GOOGLE_PROTOBUF_IO_CODED_STREAM_H__ +#define GOOGLE_PROTOBUF_IO_CODED_STREAM_H__ + + +#include <assert.h> + +#include <atomic> +#include <climits> +#include <cstddef> +#include <cstring> +#include <limits> +#include <string> +#include <type_traits> +#include <utility> + +#ifdef _WIN32 +// Assuming windows is always little-endian. +#if !defined(PROTOBUF_DISABLE_LITTLE_ENDIAN_OPT_FOR_TEST) +#define PROTOBUF_LITTLE_ENDIAN 1 +#endif +#if defined(_MSC_VER) && _MSC_VER >= 1300 && !defined(__INTEL_COMPILER) +// If MSVC has "/RTCc" set, it will complain about truncating casts at +// runtime. This file contains some intentional truncating casts. +#pragma runtime_checks("c", off) +#endif +#else +#ifdef __APPLE__ +#include <machine/endian.h> // __BYTE_ORDER +#elif defined(__FreeBSD__) +#include <sys/endian.h> // __BYTE_ORDER +#elif (defined(sun) || defined(__sun)) && (defined(__SVR4) || defined(__svr4__)) +#error #include <sys/isa_defs.h> // __BYTE_ORDER +#elif defined(_AIX) || defined(__TOS_AIX__) +#include <sys/machine.h> // BYTE_ORDER +#else +#if !defined(__QNX__) +#include <endian.h> // __BYTE_ORDER +#endif +#endif +#if ((defined(__LITTLE_ENDIAN__) && !defined(__BIG_ENDIAN__)) || \ + (defined(__BYTE_ORDER) && __BYTE_ORDER == __LITTLE_ENDIAN)) && \ + !defined(PROTOBUF_DISABLE_LITTLE_ENDIAN_OPT_FOR_TEST) +#define PROTOBUF_LITTLE_ENDIAN 1 +#endif +#endif +#include <google/protobuf/stubs/common.h> +#include <google/protobuf/stubs/logging.h> +#include <google/protobuf/stubs/strutil.h> +#include <google/protobuf/port.h> +#include <google/protobuf/stubs/port.h> + + +#include <google/protobuf/port_def.inc> + +namespace google { +namespace protobuf { + +class DescriptorPool; +class MessageFactory; +class ZeroCopyCodedInputStream; + +namespace internal { +void MapTestForceDeterministic(); +class EpsCopyByteStream; +} // namespace internal + +namespace io { + +// Defined in this file. +class CodedInputStream; +class CodedOutputStream; + +// Defined in other files. +class ZeroCopyInputStream; // zero_copy_stream.h +class ZeroCopyOutputStream; // zero_copy_stream.h + +// Class which reads and decodes binary data which is composed of varint- +// encoded integers and fixed-width pieces. Wraps a ZeroCopyInputStream. +// Most users will not need to deal with CodedInputStream. +// +// Most methods of CodedInputStream that return a bool return false if an +// underlying I/O error occurs or if the data is malformed. Once such a +// failure occurs, the CodedInputStream is broken and is no longer useful. +// After a failure, callers also should assume writes to "out" args may have +// occurred, though nothing useful can be determined from those writes. +class PROTOBUF_EXPORT CodedInputStream { + public: + // Create a CodedInputStream that reads from the given ZeroCopyInputStream. + explicit CodedInputStream(ZeroCopyInputStream* input); + + // Create a CodedInputStream that reads from the given flat array. This is + // faster than using an ArrayInputStream. PushLimit(size) is implied by + // this constructor. + explicit CodedInputStream(const uint8_t* buffer, int size); + + // Destroy the CodedInputStream and position the underlying + // ZeroCopyInputStream at the first unread byte. If an error occurred while + // reading (causing a method to return false), then the exact position of + // the input stream may be anywhere between the last value that was read + // successfully and the stream's byte limit. + ~CodedInputStream(); + + // Return true if this CodedInputStream reads from a flat array instead of + // a ZeroCopyInputStream. + inline bool IsFlat() const; + + // Skips a number of bytes. Returns false if an underlying read error + // occurs. + inline bool Skip(int count); + + // Sets *data to point directly at the unread part of the CodedInputStream's + // underlying buffer, and *size to the size of that buffer, but does not + // advance the stream's current position. This will always either produce + // a non-empty buffer or return false. If the caller consumes any of + // this data, it should then call Skip() to skip over the consumed bytes. + // This may be useful for implementing external fast parsing routines for + // types of data not covered by the CodedInputStream interface. + bool GetDirectBufferPointer(const void** data, int* size); + + // Like GetDirectBufferPointer, but this method is inlined, and does not + // attempt to Refresh() if the buffer is currently empty. + PROTOBUF_ALWAYS_INLINE + void GetDirectBufferPointerInline(const void** data, int* size); + + // Read raw bytes, copying them into the given buffer. + bool ReadRaw(void* buffer, int size); + + // Like ReadRaw, but reads into a string. + bool ReadString(TProtoStringType* buffer, int size); + + + // Read a 32-bit little-endian integer. + bool ReadLittleEndian32(arc_ui32* value); + // Read a 64-bit little-endian integer. + bool ReadLittleEndian64(arc_ui64* value); + + // These methods read from an externally provided buffer. The caller is + // responsible for ensuring that the buffer has sufficient space. + // Read a 32-bit little-endian integer. + static const uint8_t* ReadLittleEndian32FromArray(const uint8_t* buffer, + arc_ui32* value); + // Read a 64-bit little-endian integer. + static const uint8_t* ReadLittleEndian64FromArray(const uint8_t* buffer, + arc_ui64* value); + + // Read an unsigned integer with Varint encoding, truncating to 32 bits. + // Reading a 32-bit value is equivalent to reading a 64-bit one and casting + // it to arc_ui32, but may be more efficient. + bool ReadVarint32(arc_ui32* value); + // Read an unsigned integer with Varint encoding. + bool ReadVarint64(arc_ui64* value); + + // Reads a varint off the wire into an "int". This should be used for reading + // sizes off the wire (sizes of strings, submessages, bytes fields, etc). + // + // The value from the wire is interpreted as unsigned. If its value exceeds + // the representable value of an integer on this platform, instead of + // truncating we return false. Truncating (as performed by ReadVarint32() + // above) is an acceptable approach for fields representing an integer, but + // when we are parsing a size from the wire, truncating the value would result + // in us misparsing the payload. + bool ReadVarintSizeAsInt(int* value); + + // Read a tag. This calls ReadVarint32() and returns the result, or returns + // zero (which is not a valid tag) if ReadVarint32() fails. Also, ReadTag + // (but not ReadTagNoLastTag) updates the last tag value, which can be checked + // with LastTagWas(). + // + // Always inline because this is only called in one place per parse loop + // but it is called for every iteration of said loop, so it should be fast. + // GCC doesn't want to inline this by default. + PROTOBUF_ALWAYS_INLINE arc_ui32 ReadTag() { + return last_tag_ = ReadTagNoLastTag(); + } + + PROTOBUF_ALWAYS_INLINE arc_ui32 ReadTagNoLastTag(); + + // This usually a faster alternative to ReadTag() when cutoff is a manifest + // constant. It does particularly well for cutoff >= 127. The first part + // of the return value is the tag that was read, though it can also be 0 in + // the cases where ReadTag() would return 0. If the second part is true + // then the tag is known to be in [0, cutoff]. If not, the tag either is + // above cutoff or is 0. (There's intentional wiggle room when tag is 0, + // because that can arise in several ways, and for best performance we want + // to avoid an extra "is tag == 0?" check here.) + PROTOBUF_ALWAYS_INLINE + std::pair<arc_ui32, bool> ReadTagWithCutoff(arc_ui32 cutoff) { + std::pair<arc_ui32, bool> result = ReadTagWithCutoffNoLastTag(cutoff); + last_tag_ = result.first; + return result; + } + + PROTOBUF_ALWAYS_INLINE + std::pair<arc_ui32, bool> ReadTagWithCutoffNoLastTag(arc_ui32 cutoff); + + // Usually returns true if calling ReadVarint32() now would produce the given + // value. Will always return false if ReadVarint32() would not return the + // given value. If ExpectTag() returns true, it also advances past + // the varint. For best performance, use a compile-time constant as the + // parameter. + // Always inline because this collapses to a small number of instructions + // when given a constant parameter, but GCC doesn't want to inline by default. + PROTOBUF_ALWAYS_INLINE bool ExpectTag(arc_ui32 expected); + + // Like above, except this reads from the specified buffer. The caller is + // responsible for ensuring that the buffer is large enough to read a varint + // of the expected size. For best performance, use a compile-time constant as + // the expected tag parameter. + // + // Returns a pointer beyond the expected tag if it was found, or NULL if it + // was not. + PROTOBUF_ALWAYS_INLINE + static const uint8_t* ExpectTagFromArray(const uint8_t* buffer, + arc_ui32 expected); + + // Usually returns true if no more bytes can be read. Always returns false + // if more bytes can be read. If ExpectAtEnd() returns true, a subsequent + // call to LastTagWas() will act as if ReadTag() had been called and returned + // zero, and ConsumedEntireMessage() will return true. + bool ExpectAtEnd(); + + // If the last call to ReadTag() or ReadTagWithCutoff() returned the given + // value, returns true. Otherwise, returns false. + // ReadTagNoLastTag/ReadTagWithCutoffNoLastTag do not preserve the last + // returned value. + // + // This is needed because parsers for some types of embedded messages + // (with field type TYPE_GROUP) don't actually know that they've reached the + // end of a message until they see an ENDGROUP tag, which was actually part + // of the enclosing message. The enclosing message would like to check that + // tag to make sure it had the right number, so it calls LastTagWas() on + // return from the embedded parser to check. + bool LastTagWas(arc_ui32 expected); + void SetLastTag(arc_ui32 tag) { last_tag_ = tag; } + + // When parsing message (but NOT a group), this method must be called + // immediately after MergeFromCodedStream() returns (if it returns true) + // to further verify that the message ended in a legitimate way. For + // example, this verifies that parsing did not end on an end-group tag. + // It also checks for some cases where, due to optimizations, + // MergeFromCodedStream() can incorrectly return true. + bool ConsumedEntireMessage(); + void SetConsumed() { legitimate_message_end_ = true; } + + // Limits ---------------------------------------------------------- + // Limits are used when parsing length-delimited embedded messages. + // After the message's length is read, PushLimit() is used to prevent + // the CodedInputStream from reading beyond that length. Once the + // embedded message has been parsed, PopLimit() is called to undo the + // limit. + + // Opaque type used with PushLimit() and PopLimit(). Do not modify + // values of this type yourself. The only reason that this isn't a + // struct with private internals is for efficiency. + typedef int Limit; + + // Places a limit on the number of bytes that the stream may read, + // starting from the current position. Once the stream hits this limit, + // it will act like the end of the input has been reached until PopLimit() + // is called. + // + // As the names imply, the stream conceptually has a stack of limits. The + // shortest limit on the stack is always enforced, even if it is not the + // top limit. + // + // The value returned by PushLimit() is opaque to the caller, and must + // be passed unchanged to the corresponding call to PopLimit(). + Limit PushLimit(int byte_limit); + + // Pops the last limit pushed by PushLimit(). The input must be the value + // returned by that call to PushLimit(). + void PopLimit(Limit limit); + + // Returns the number of bytes left until the nearest limit on the + // stack is hit, or -1 if no limits are in place. + int BytesUntilLimit() const; + + // Returns current position relative to the beginning of the input stream. + int CurrentPosition() const; + + // Total Bytes Limit ----------------------------------------------- + // To prevent malicious users from sending excessively large messages + // and causing memory exhaustion, CodedInputStream imposes a hard limit on + // the total number of bytes it will read. + + // Sets the maximum number of bytes that this CodedInputStream will read + // before refusing to continue. To prevent servers from allocating enormous + // amounts of memory to hold parsed messages, the maximum message length + // should be limited to the shortest length that will not harm usability. + // The default limit is INT_MAX (~2GB) and apps should set shorter limits + // if possible. An error will always be printed to stderr if the limit is + // reached. + // + // Note: setting a limit less than the current read position is interpreted + // as a limit on the current position. + // + // This is unrelated to PushLimit()/PopLimit(). + void SetTotalBytesLimit(int total_bytes_limit); + + // The Total Bytes Limit minus the Current Position, or -1 if the total bytes + // limit is INT_MAX. + int BytesUntilTotalBytesLimit() const; + + // Recursion Limit ------------------------------------------------- + // To prevent corrupt or malicious messages from causing stack overflows, + // we must keep track of the depth of recursion when parsing embedded + // messages and groups. CodedInputStream keeps track of this because it + // is the only object that is passed down the stack during parsing. + + // Sets the maximum recursion depth. The default is 100. + void SetRecursionLimit(int limit); + int RecursionBudget() { return recursion_budget_; } + + static int GetDefaultRecursionLimit() { return default_recursion_limit_; } + + // Increments the current recursion depth. Returns true if the depth is + // under the limit, false if it has gone over. + bool IncrementRecursionDepth(); + + // Decrements the recursion depth if possible. + void DecrementRecursionDepth(); + + // Decrements the recursion depth blindly. This is faster than + // DecrementRecursionDepth(). It should be used only if all previous + // increments to recursion depth were successful. + void UnsafeDecrementRecursionDepth(); + + // Shorthand for make_pair(PushLimit(byte_limit), --recursion_budget_). + // Using this can reduce code size and complexity in some cases. The caller + // is expected to check that the second part of the result is non-negative (to + // bail out if the depth of recursion is too high) and, if all is well, to + // later pass the first part of the result to PopLimit() or similar. + std::pair<CodedInputStream::Limit, int> IncrementRecursionDepthAndPushLimit( + int byte_limit); + + // Shorthand for PushLimit(ReadVarint32(&length) ? length : 0). + Limit ReadLengthAndPushLimit(); + + // Helper that is equivalent to: { + // bool result = ConsumedEntireMessage(); + // PopLimit(limit); + // UnsafeDecrementRecursionDepth(); + // return result; } + // Using this can reduce code size and complexity in some cases. + // Do not use unless the current recursion depth is greater than zero. + bool DecrementRecursionDepthAndPopLimit(Limit limit); + + // Helper that is equivalent to: { + // bool result = ConsumedEntireMessage(); + // PopLimit(limit); + // return result; } + // Using this can reduce code size and complexity in some cases. + bool CheckEntireMessageConsumedAndPopLimit(Limit limit); + + // Extension Registry ---------------------------------------------- + // ADVANCED USAGE: 99.9% of people can ignore this section. + // + // By default, when parsing extensions, the parser looks for extension + // definitions in the pool which owns the outer message's Descriptor. + // However, you may call SetExtensionRegistry() to provide an alternative + // pool instead. This makes it possible, for example, to parse a message + // using a generated class, but represent some extensions using + // DynamicMessage. + + // Set the pool used to look up extensions. Most users do not need to call + // this as the correct pool will be chosen automatically. + // + // WARNING: It is very easy to misuse this. Carefully read the requirements + // below. Do not use this unless you are sure you need it. Almost no one + // does. + // + // Let's say you are parsing a message into message object m, and you want + // to take advantage of SetExtensionRegistry(). You must follow these + // requirements: + // + // The given DescriptorPool must contain m->GetDescriptor(). It is not + // sufficient for it to simply contain a descriptor that has the same name + // and content -- it must be the *exact object*. In other words: + // assert(pool->FindMessageTypeByName(m->GetDescriptor()->full_name()) == + // m->GetDescriptor()); + // There are two ways to satisfy this requirement: + // 1) Use m->GetDescriptor()->pool() as the pool. This is generally useless + // because this is the pool that would be used anyway if you didn't call + // SetExtensionRegistry() at all. + // 2) Use a DescriptorPool which has m->GetDescriptor()->pool() as an + // "underlay". Read the documentation for DescriptorPool for more + // information about underlays. + // + // You must also provide a MessageFactory. This factory will be used to + // construct Message objects representing extensions. The factory's + // GetPrototype() MUST return non-NULL for any Descriptor which can be found + // through the provided pool. + // + // If the provided factory might return instances of protocol-compiler- + // generated (i.e. compiled-in) types, or if the outer message object m is + // a generated type, then the given factory MUST have this property: If + // GetPrototype() is given a Descriptor which resides in + // DescriptorPool::generated_pool(), the factory MUST return the same + // prototype which MessageFactory::generated_factory() would return. That + // is, given a descriptor for a generated type, the factory must return an + // instance of the generated class (NOT DynamicMessage). However, when + // given a descriptor for a type that is NOT in generated_pool, the factory + // is free to return any implementation. + // + // The reason for this requirement is that generated sub-objects may be + // accessed via the standard (non-reflection) extension accessor methods, + // and these methods will down-cast the object to the generated class type. + // If the object is not actually of that type, the results would be undefined. + // On the other hand, if an extension is not compiled in, then there is no + // way the code could end up accessing it via the standard accessors -- the + // only way to access the extension is via reflection. When using reflection, + // DynamicMessage and generated messages are indistinguishable, so it's fine + // if these objects are represented using DynamicMessage. + // + // Using DynamicMessageFactory on which you have called + // SetDelegateToGeneratedFactory(true) should be sufficient to satisfy the + // above requirement. + // + // If either pool or factory is NULL, both must be NULL. + // + // Note that this feature is ignored when parsing "lite" messages as they do + // not have descriptors. + void SetExtensionRegistry(const DescriptorPool* pool, + MessageFactory* factory); + + // Get the DescriptorPool set via SetExtensionRegistry(), or NULL if no pool + // has been provided. + const DescriptorPool* GetExtensionPool(); + + // Get the MessageFactory set via SetExtensionRegistry(), or NULL if no + // factory has been provided. + MessageFactory* GetExtensionFactory(); + + private: + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(CodedInputStream); + + const uint8_t* buffer_; + const uint8_t* buffer_end_; // pointer to the end of the buffer. + ZeroCopyInputStream* input_; + int total_bytes_read_; // total bytes read from input_, including + // the current buffer + + // If total_bytes_read_ surpasses INT_MAX, we record the extra bytes here + // so that we can BackUp() on destruction. + int overflow_bytes_; + + // LastTagWas() stuff. + arc_ui32 last_tag_; // result of last ReadTag() or ReadTagWithCutoff(). + + // This is set true by ReadTag{Fallback/Slow}() if it is called when exactly + // at EOF, or by ExpectAtEnd() when it returns true. This happens when we + // reach the end of a message and attempt to read another tag. + bool legitimate_message_end_; + + // See EnableAliasing(). + bool aliasing_enabled_; + + // Limits + Limit current_limit_; // if position = -1, no limit is applied + + // For simplicity, if the current buffer crosses a limit (either a normal + // limit created by PushLimit() or the total bytes limit), buffer_size_ + // only tracks the number of bytes before that limit. This field + // contains the number of bytes after it. Note that this implies that if + // buffer_size_ == 0 and buffer_size_after_limit_ > 0, we know we've + // hit a limit. However, if both are zero, it doesn't necessarily mean + // we aren't at a limit -- the buffer may have ended exactly at the limit. + int buffer_size_after_limit_; + + // Maximum number of bytes to read, period. This is unrelated to + // current_limit_. Set using SetTotalBytesLimit(). + int total_bytes_limit_; + + // Current recursion budget, controlled by IncrementRecursionDepth() and + // similar. Starts at recursion_limit_ and goes down: if this reaches + // -1 we are over budget. + int recursion_budget_; + // Recursion depth limit, set by SetRecursionLimit(). + int recursion_limit_; + + // See SetExtensionRegistry(). + const DescriptorPool* extension_pool_; + MessageFactory* extension_factory_; + + // Private member functions. + + // Fallback when Skip() goes past the end of the current buffer. + bool SkipFallback(int count, int original_buffer_size); + + // Advance the buffer by a given number of bytes. + void Advance(int amount); + + // Back up input_ to the current buffer position. + void BackUpInputToCurrentPosition(); + + // Recomputes the value of buffer_size_after_limit_. Must be called after + // current_limit_ or total_bytes_limit_ changes. + void RecomputeBufferLimits(); + + // Writes an error message saying that we hit total_bytes_limit_. + void PrintTotalBytesLimitError(); + + // Called when the buffer runs out to request more data. Implies an + // Advance(BufferSize()). + bool Refresh(); + + // When parsing varints, we optimize for the common case of small values, and + // then optimize for the case when the varint fits within the current buffer + // piece. The Fallback method is used when we can't use the one-byte + // optimization. The Slow method is yet another fallback when the buffer is + // not large enough. Making the slow path out-of-line speeds up the common + // case by 10-15%. The slow path is fairly uncommon: it only triggers when a + // message crosses multiple buffers. Note: ReadVarint32Fallback() and + // ReadVarint64Fallback() are called frequently and generally not inlined, so + // they have been optimized to avoid "out" parameters. The former returns -1 + // if it fails and the arc_ui32 it read otherwise. The latter has a bool + // indicating success or failure as part of its return type. + arc_i64 ReadVarint32Fallback(arc_ui32 first_byte_or_zero); + int ReadVarintSizeAsIntFallback(); + std::pair<arc_ui64, bool> ReadVarint64Fallback(); + bool ReadVarint32Slow(arc_ui32* value); + bool ReadVarint64Slow(arc_ui64* value); + int ReadVarintSizeAsIntSlow(); + bool ReadLittleEndian32Fallback(arc_ui32* value); + bool ReadLittleEndian64Fallback(arc_ui64* value); + + // Fallback/slow methods for reading tags. These do not update last_tag_, + // but will set legitimate_message_end_ if we are at the end of the input + // stream. + arc_ui32 ReadTagFallback(arc_ui32 first_byte_or_zero); + arc_ui32 ReadTagSlow(); + bool ReadStringFallback(TProtoStringType* buffer, int size); + + // Return the size of the buffer. + int BufferSize() const; + + static const int kDefaultTotalBytesLimit = INT_MAX; + + static int default_recursion_limit_; // 100 by default. + + friend class google::protobuf::ZeroCopyCodedInputStream; + friend class google::protobuf::internal::EpsCopyByteStream; +}; + +// EpsCopyOutputStream wraps a ZeroCopyOutputStream and exposes a new stream, +// which has the property you can write kSlopBytes (16 bytes) from the current +// position without bounds checks. The cursor into the stream is managed by +// the user of the class and is an explicit parameter in the methods. Careful +// use of this class, ie. keep ptr a local variable, eliminates the need to +// for the compiler to sync the ptr value between register and memory. +class PROTOBUF_EXPORT EpsCopyOutputStream { + public: + enum { kSlopBytes = 16 }; + + // Initialize from a stream. + EpsCopyOutputStream(ZeroCopyOutputStream* stream, bool deterministic, + uint8_t** pp) + : end_(buffer_), + stream_(stream), + is_serialization_deterministic_(deterministic) { + *pp = buffer_; + } + + // Only for array serialization. No overflow protection, end_ will be the + // pointed to the end of the array. When using this the total size is already + // known, so no need to maintain the slop region. + EpsCopyOutputStream(void* data, int size, bool deterministic) + : end_(static_cast<uint8_t*>(data) + size), + buffer_end_(nullptr), + stream_(nullptr), + is_serialization_deterministic_(deterministic) {} + + // Initialize from stream but with the first buffer already given (eager). + EpsCopyOutputStream(void* data, int size, ZeroCopyOutputStream* stream, + bool deterministic, uint8_t** pp) + : stream_(stream), is_serialization_deterministic_(deterministic) { + *pp = SetInitialBuffer(data, size); + } + + // Flush everything that's written into the underlying ZeroCopyOutputStream + // and trims the underlying stream to the location of ptr. + uint8_t* Trim(uint8_t* ptr); + + // After this it's guaranteed you can safely write kSlopBytes to ptr. This + // will never fail! The underlying stream can produce an error. Use HadError + // to check for errors. + PROTOBUF_NODISCARD uint8_t* EnsureSpace(uint8_t* ptr) { + if (PROTOBUF_PREDICT_FALSE(ptr >= end_)) { + return EnsureSpaceFallback(ptr); + } + return ptr; + } + + uint8_t* WriteRaw(const void* data, int size, uint8_t* ptr) { + if (PROTOBUF_PREDICT_FALSE(end_ - ptr < size)) { + return WriteRawFallback(data, size, ptr); + } + std::memcpy(ptr, data, size); + return ptr + size; + } + // Writes the buffer specified by data, size to the stream. Possibly by + // aliasing the buffer (ie. not copying the data). The caller is responsible + // to make sure the buffer is alive for the duration of the + // ZeroCopyOutputStream. +#ifndef NDEBUG + PROTOBUF_NOINLINE +#endif + uint8_t* WriteRawMaybeAliased(const void* data, int size, uint8_t* ptr) { + if (aliasing_enabled_) { + return WriteAliasedRaw(data, size, ptr); + } else { + return WriteRaw(data, size, ptr); + } + } + + +#ifndef NDEBUG + PROTOBUF_NOINLINE +#endif + uint8_t* WriteStringMaybeAliased(arc_ui32 num, const TProtoStringType& s, + uint8_t* ptr) { + std::ptrdiff_t size = s.size(); + if (PROTOBUF_PREDICT_FALSE( + size >= 128 || end_ - ptr + 16 - TagSize(num << 3) - 1 < size)) { + return WriteStringMaybeAliasedOutline(num, s, ptr); + } + ptr = UnsafeVarint((num << 3) | 2, ptr); + *ptr++ = static_cast<uint8_t>(size); + std::memcpy(ptr, s.data(), size); + return ptr + size; + } + uint8_t* WriteBytesMaybeAliased(arc_ui32 num, const TProtoStringType& s, + uint8_t* ptr) { + return WriteStringMaybeAliased(num, s, ptr); + } + + template <typename T> + PROTOBUF_ALWAYS_INLINE uint8_t* WriteString(arc_ui32 num, const T& s, + uint8_t* ptr) { + std::ptrdiff_t size = s.size(); + if (PROTOBUF_PREDICT_FALSE( + size >= 128 || end_ - ptr + 16 - TagSize(num << 3) - 1 < size)) { + return WriteStringOutline(num, s, ptr); + } + ptr = UnsafeVarint((num << 3) | 2, ptr); + *ptr++ = static_cast<uint8_t>(size); + std::memcpy(ptr, s.data(), size); + return ptr + size; + } + template <typename T> +#ifndef NDEBUG + PROTOBUF_NOINLINE +#endif + uint8_t* WriteBytes(arc_ui32 num, const T& s, uint8_t* ptr) { + return WriteString(num, s, ptr); + } + + template <typename T> + PROTOBUF_ALWAYS_INLINE uint8_t* WriteInt32Packed(int num, const T& r, + int size, uint8_t* ptr) { + return WriteVarintPacked(num, r, size, ptr, Encode64); + } + template <typename T> + PROTOBUF_ALWAYS_INLINE uint8_t* WriteUInt32Packed(int num, const T& r, + int size, uint8_t* ptr) { + return WriteVarintPacked(num, r, size, ptr, Encode32); + } + template <typename T> + PROTOBUF_ALWAYS_INLINE uint8_t* WriteSInt32Packed(int num, const T& r, + int size, uint8_t* ptr) { + return WriteVarintPacked(num, r, size, ptr, ZigZagEncode32); + } + template <typename T> + PROTOBUF_ALWAYS_INLINE uint8_t* WriteInt64Packed(int num, const T& r, + int size, uint8_t* ptr) { + return WriteVarintPacked(num, r, size, ptr, Encode64); + } + template <typename T> + PROTOBUF_ALWAYS_INLINE uint8_t* WriteUInt64Packed(int num, const T& r, + int size, uint8_t* ptr) { + return WriteVarintPacked(num, r, size, ptr, Encode64); + } + template <typename T> + PROTOBUF_ALWAYS_INLINE uint8_t* WriteSInt64Packed(int num, const T& r, + int size, uint8_t* ptr) { + return WriteVarintPacked(num, r, size, ptr, ZigZagEncode64); + } + template <typename T> + PROTOBUF_ALWAYS_INLINE uint8_t* WriteEnumPacked(int num, const T& r, int size, + uint8_t* ptr) { + return WriteVarintPacked(num, r, size, ptr, Encode64); + } + + template <typename T> + PROTOBUF_ALWAYS_INLINE uint8_t* WriteFixedPacked(int num, const T& r, + uint8_t* ptr) { + ptr = EnsureSpace(ptr); + constexpr auto element_size = sizeof(typename T::value_type); + auto size = r.size() * element_size; + ptr = WriteLengthDelim(num, size, ptr); + return WriteRawLittleEndian<element_size>(r.data(), static_cast<int>(size), + ptr); + } + + // Returns true if there was an underlying I/O error since this object was + // created. + bool HadError() const { return had_error_; } + + // Instructs the EpsCopyOutputStream to allow the underlying + // ZeroCopyOutputStream to hold pointers to the original structure instead of + // copying, if it supports it (i.e. output->AllowsAliasing() is true). If the + // underlying stream does not support aliasing, then enabling it has no + // affect. For now, this only affects the behavior of + // WriteRawMaybeAliased(). + // + // NOTE: It is caller's responsibility to ensure that the chunk of memory + // remains live until all of the data has been consumed from the stream. + void EnableAliasing(bool enabled); + + // See documentation on CodedOutputStream::SetSerializationDeterministic. + void SetSerializationDeterministic(bool value) { + is_serialization_deterministic_ = value; + } + + // See documentation on CodedOutputStream::IsSerializationDeterministic. + bool IsSerializationDeterministic() const { + return is_serialization_deterministic_; + } + + // The number of bytes written to the stream at position ptr, relative to the + // stream's overall position. + int64_t ByteCount(uint8_t* ptr) const; + + + private: + uint8_t* end_; + uint8_t* buffer_end_ = buffer_; + uint8_t buffer_[2 * kSlopBytes]; + ZeroCopyOutputStream* stream_; + bool had_error_ = false; + bool aliasing_enabled_ = false; // See EnableAliasing(). + bool is_serialization_deterministic_; + + uint8_t* EnsureSpaceFallback(uint8_t* ptr); + inline uint8_t* Next(); + int Flush(uint8_t* ptr); + std::ptrdiff_t GetSize(uint8_t* ptr) const { + GOOGLE_DCHECK(ptr <= end_ + kSlopBytes); // NOLINT + return end_ + kSlopBytes - ptr; + } + + uint8_t* Error() { + had_error_ = true; + // We use the patch buffer to always guarantee space to write to. + end_ = buffer_ + kSlopBytes; + return buffer_; + } + + static constexpr int TagSize(arc_ui32 tag) { + return (tag < (1 << 7)) ? 1 + : (tag < (1 << 14)) ? 2 + : (tag < (1 << 21)) ? 3 + : (tag < (1 << 28)) ? 4 + : 5; + } + + PROTOBUF_ALWAYS_INLINE uint8_t* WriteTag(arc_ui32 num, arc_ui32 wt, + uint8_t* ptr) { + GOOGLE_DCHECK(ptr < end_); // NOLINT + return UnsafeVarint((num << 3) | wt, ptr); + } + + PROTOBUF_ALWAYS_INLINE uint8_t* WriteLengthDelim(int num, arc_ui32 size, + uint8_t* ptr) { + ptr = WriteTag(num, 2, ptr); + return UnsafeWriteSize(size, ptr); + } + + uint8_t* WriteRawFallback(const void* data, int size, uint8_t* ptr); + + uint8_t* WriteAliasedRaw(const void* data, int size, uint8_t* ptr); + + uint8_t* WriteStringMaybeAliasedOutline(arc_ui32 num, const TProtoStringType& s, + uint8_t* ptr); + uint8_t* WriteStringOutline(arc_ui32 num, const TProtoStringType& s, uint8_t* ptr); + + template <typename T, typename E> + PROTOBUF_ALWAYS_INLINE uint8_t* WriteVarintPacked(int num, const T& r, + int size, uint8_t* ptr, + const E& encode) { + ptr = EnsureSpace(ptr); + ptr = WriteLengthDelim(num, size, ptr); + auto it = r.data(); + auto end = it + r.size(); + do { + ptr = EnsureSpace(ptr); + ptr = UnsafeVarint(encode(*it++), ptr); + } while (it < end); + return ptr; + } + + static arc_ui32 Encode32(arc_ui32 v) { return v; } + static arc_ui64 Encode64(arc_ui64 v) { return v; } + static arc_ui32 ZigZagEncode32(arc_i32 v) { + return (static_cast<arc_ui32>(v) << 1) ^ static_cast<arc_ui32>(v >> 31); + } + static arc_ui64 ZigZagEncode64(arc_i64 v) { + return (static_cast<arc_ui64>(v) << 1) ^ static_cast<arc_ui64>(v >> 63); + } + + template <typename T> + PROTOBUF_ALWAYS_INLINE static uint8_t* UnsafeVarint(T value, uint8_t* ptr) { + static_assert(std::is_unsigned<T>::value, + "Varint serialization must be unsigned"); + ptr[0] = static_cast<uint8_t>(value); + if (value < 0x80) { + return ptr + 1; + } + // Turn on continuation bit in the byte we just wrote. + ptr[0] |= static_cast<uint8_t>(0x80); + value >>= 7; + ptr[1] = static_cast<uint8_t>(value); + if (value < 0x80) { + return ptr + 2; + } + ptr += 2; + do { + // Turn on continuation bit in the byte we just wrote. + ptr[-1] |= static_cast<uint8_t>(0x80); + value >>= 7; + *ptr = static_cast<uint8_t>(value); + ++ptr; + } while (value >= 0x80); + return ptr; + } + + PROTOBUF_ALWAYS_INLINE static uint8_t* UnsafeWriteSize(arc_ui32 value, + uint8_t* ptr) { + while (PROTOBUF_PREDICT_FALSE(value >= 0x80)) { + *ptr = static_cast<uint8_t>(value | 0x80); + value >>= 7; + ++ptr; + } + *ptr++ = static_cast<uint8_t>(value); + return ptr; + } + + template <int S> + uint8_t* WriteRawLittleEndian(const void* data, int size, uint8_t* ptr); +#ifndef PROTOBUF_LITTLE_ENDIAN + uint8_t* WriteRawLittleEndian32(const void* data, int size, uint8_t* ptr); + uint8_t* WriteRawLittleEndian64(const void* data, int size, uint8_t* ptr); +#endif + + // These methods are for CodedOutputStream. Ideally they should be private + // but to match current behavior of CodedOutputStream as close as possible + // we allow it some functionality. + public: + uint8_t* SetInitialBuffer(void* data, int size) { + auto ptr = static_cast<uint8_t*>(data); + if (size > kSlopBytes) { + end_ = ptr + size - kSlopBytes; + buffer_end_ = nullptr; + return ptr; + } else { + end_ = buffer_ + size; + buffer_end_ = ptr; + return buffer_; + } + } + + private: + // Needed by CodedOutputStream HadError. HadError needs to flush the patch + // buffers to ensure there is no error as of yet. + uint8_t* FlushAndResetBuffer(uint8_t*); + + // The following functions mimic the old CodedOutputStream behavior as close + // as possible. They flush the current state to the stream, behave as + // the old CodedOutputStream and then return to normal operation. + bool Skip(int count, uint8_t** pp); + bool GetDirectBufferPointer(void** data, int* size, uint8_t** pp); + uint8_t* GetDirectBufferForNBytesAndAdvance(int size, uint8_t** pp); + + friend class CodedOutputStream; +}; + +template <> +inline uint8_t* EpsCopyOutputStream::WriteRawLittleEndian<1>(const void* data, + int size, + uint8_t* ptr) { + return WriteRaw(data, size, ptr); +} +template <> +inline uint8_t* EpsCopyOutputStream::WriteRawLittleEndian<4>(const void* data, + int size, + uint8_t* ptr) { +#ifdef PROTOBUF_LITTLE_ENDIAN + return WriteRaw(data, size, ptr); +#else + return WriteRawLittleEndian32(data, size, ptr); +#endif +} +template <> +inline uint8_t* EpsCopyOutputStream::WriteRawLittleEndian<8>(const void* data, + int size, + uint8_t* ptr) { +#ifdef PROTOBUF_LITTLE_ENDIAN + return WriteRaw(data, size, ptr); +#else + return WriteRawLittleEndian64(data, size, ptr); +#endif +} + +// Class which encodes and writes binary data which is composed of varint- +// encoded integers and fixed-width pieces. Wraps a ZeroCopyOutputStream. +// Most users will not need to deal with CodedOutputStream. +// +// Most methods of CodedOutputStream which return a bool return false if an +// underlying I/O error occurs. Once such a failure occurs, the +// CodedOutputStream is broken and is no longer useful. The Write* methods do +// not return the stream status, but will invalidate the stream if an error +// occurs. The client can probe HadError() to determine the status. +// +// Note that every method of CodedOutputStream which writes some data has +// a corresponding static "ToArray" version. These versions write directly +// to the provided buffer, returning a pointer past the last written byte. +// They require that the buffer has sufficient capacity for the encoded data. +// This allows an optimization where we check if an output stream has enough +// space for an entire message before we start writing and, if there is, we +// call only the ToArray methods to avoid doing bound checks for each +// individual value. +// i.e., in the example above: +// +// CodedOutputStream* coded_output = new CodedOutputStream(raw_output); +// int magic_number = 1234; +// char text[] = "Hello world!"; +// +// int coded_size = sizeof(magic_number) + +// CodedOutputStream::VarintSize32(strlen(text)) + +// strlen(text); +// +// uint8_t* buffer = +// coded_output->GetDirectBufferForNBytesAndAdvance(coded_size); +// if (buffer != nullptr) { +// // The output stream has enough space in the buffer: write directly to +// // the array. +// buffer = CodedOutputStream::WriteLittleEndian32ToArray(magic_number, +// buffer); +// buffer = CodedOutputStream::WriteVarint32ToArray(strlen(text), buffer); +// buffer = CodedOutputStream::WriteRawToArray(text, strlen(text), buffer); +// } else { +// // Make bound-checked writes, which will ask the underlying stream for +// // more space as needed. +// coded_output->WriteLittleEndian32(magic_number); +// coded_output->WriteVarint32(strlen(text)); +// coded_output->WriteRaw(text, strlen(text)); +// } +// +// delete coded_output; +class PROTOBUF_EXPORT CodedOutputStream { + public: + // Create an CodedOutputStream that writes to the given ZeroCopyOutputStream. + explicit CodedOutputStream(ZeroCopyOutputStream* stream) + : CodedOutputStream(stream, true) {} + CodedOutputStream(ZeroCopyOutputStream* stream, bool do_eager_refresh); + + // Destroy the CodedOutputStream and position the underlying + // ZeroCopyOutputStream immediately after the last byte written. + ~CodedOutputStream(); + + // Returns true if there was an underlying I/O error since this object was + // created. On should call Trim before this function in order to catch all + // errors. + bool HadError() { + cur_ = impl_.FlushAndResetBuffer(cur_); + GOOGLE_DCHECK(cur_); + return impl_.HadError(); + } + + // Trims any unused space in the underlying buffer so that its size matches + // the number of bytes written by this stream. The underlying buffer will + // automatically be trimmed when this stream is destroyed; this call is only + // necessary if the underlying buffer is accessed *before* the stream is + // destroyed. + void Trim() { cur_ = impl_.Trim(cur_); } + + // Skips a number of bytes, leaving the bytes unmodified in the underlying + // buffer. Returns false if an underlying write error occurs. This is + // mainly useful with GetDirectBufferPointer(). + // Note of caution, the skipped bytes may contain uninitialized data. The + // caller must make sure that the skipped bytes are properly initialized, + // otherwise you might leak bytes from your heap. + bool Skip(int count) { return impl_.Skip(count, &cur_); } + + // Sets *data to point directly at the unwritten part of the + // CodedOutputStream's underlying buffer, and *size to the size of that + // buffer, but does not advance the stream's current position. This will + // always either produce a non-empty buffer or return false. If the caller + // writes any data to this buffer, it should then call Skip() to skip over + // the consumed bytes. This may be useful for implementing external fast + // serialization routines for types of data not covered by the + // CodedOutputStream interface. + bool GetDirectBufferPointer(void** data, int* size) { + return impl_.GetDirectBufferPointer(data, size, &cur_); + } + + // If there are at least "size" bytes available in the current buffer, + // returns a pointer directly into the buffer and advances over these bytes. + // The caller may then write directly into this buffer (e.g. using the + // *ToArray static methods) rather than go through CodedOutputStream. If + // there are not enough bytes available, returns NULL. The return pointer is + // invalidated as soon as any other non-const method of CodedOutputStream + // is called. + inline uint8_t* GetDirectBufferForNBytesAndAdvance(int size) { + return impl_.GetDirectBufferForNBytesAndAdvance(size, &cur_); + } + + // Write raw bytes, copying them from the given buffer. + void WriteRaw(const void* buffer, int size) { + cur_ = impl_.WriteRaw(buffer, size, cur_); + } + // Like WriteRaw() but will try to write aliased data if aliasing is + // turned on. + void WriteRawMaybeAliased(const void* data, int size); + // Like WriteRaw() but writing directly to the target array. + // This is _not_ inlined, as the compiler often optimizes memcpy into inline + // copy loops. Since this gets called by every field with string or bytes + // type, inlining may lead to a significant amount of code bloat, with only a + // minor performance gain. + static uint8_t* WriteRawToArray(const void* buffer, int size, + uint8_t* target); + + // Equivalent to WriteRaw(str.data(), str.size()). + void WriteString(const TProtoStringType& str); + // Like WriteString() but writing directly to the target array. + static uint8_t* WriteStringToArray(const TProtoStringType& str, uint8_t* target); + // Write the varint-encoded size of str followed by str. + static uint8_t* WriteStringWithSizeToArray(const TProtoStringType& str, + uint8_t* target); + + + // Write a 32-bit little-endian integer. + void WriteLittleEndian32(arc_ui32 value) { + cur_ = impl_.EnsureSpace(cur_); + SetCur(WriteLittleEndian32ToArray(value, Cur())); + } + // Like WriteLittleEndian32() but writing directly to the target array. + static uint8_t* WriteLittleEndian32ToArray(arc_ui32 value, uint8_t* target); + // Write a 64-bit little-endian integer. + void WriteLittleEndian64(arc_ui64 value) { + cur_ = impl_.EnsureSpace(cur_); + SetCur(WriteLittleEndian64ToArray(value, Cur())); + } + // Like WriteLittleEndian64() but writing directly to the target array. + static uint8_t* WriteLittleEndian64ToArray(arc_ui64 value, uint8_t* target); + + // Write an unsigned integer with Varint encoding. Writing a 32-bit value + // is equivalent to casting it to arc_ui64 and writing it as a 64-bit value, + // but may be more efficient. + void WriteVarint32(arc_ui32 value); + // Like WriteVarint32() but writing directly to the target array. + static uint8_t* WriteVarint32ToArray(arc_ui32 value, uint8_t* target); + // Like WriteVarint32() but writing directly to the target array, and with + // the less common-case paths being out of line rather than inlined. + static uint8_t* WriteVarint32ToArrayOutOfLine(arc_ui32 value, + uint8_t* target); + // Write an unsigned integer with Varint encoding. + void WriteVarint64(arc_ui64 value); + // Like WriteVarint64() but writing directly to the target array. + static uint8_t* WriteVarint64ToArray(arc_ui64 value, uint8_t* target); + + // Equivalent to WriteVarint32() except when the value is negative, + // in which case it must be sign-extended to a full 10 bytes. + void WriteVarint32SignExtended(arc_i32 value); + // Like WriteVarint32SignExtended() but writing directly to the target array. + static uint8_t* WriteVarint32SignExtendedToArray(arc_i32 value, + uint8_t* target); + + // This is identical to WriteVarint32(), but optimized for writing tags. + // In particular, if the input is a compile-time constant, this method + // compiles down to a couple instructions. + // Always inline because otherwise the aforementioned optimization can't work, + // but GCC by default doesn't want to inline this. + void WriteTag(arc_ui32 value); + // Like WriteTag() but writing directly to the target array. + PROTOBUF_ALWAYS_INLINE + static uint8_t* WriteTagToArray(arc_ui32 value, uint8_t* target); + + // Returns the number of bytes needed to encode the given value as a varint. + static size_t VarintSize32(arc_ui32 value); + // Returns the number of bytes needed to encode the given value as a varint. + static size_t VarintSize64(arc_ui64 value); + + // If negative, 10 bytes. Otherwise, same as VarintSize32(). + static size_t VarintSize32SignExtended(arc_i32 value); + + // Same as above, plus one. The additional one comes at no compute cost. + static size_t VarintSize32PlusOne(arc_ui32 value); + static size_t VarintSize64PlusOne(arc_ui64 value); + static size_t VarintSize32SignExtendedPlusOne(arc_i32 value); + + // Compile-time equivalent of VarintSize32(). + template <arc_ui32 Value> + struct StaticVarintSize32 { + static const size_t value = (Value < (1 << 7)) ? 1 + : (Value < (1 << 14)) ? 2 + : (Value < (1 << 21)) ? 3 + : (Value < (1 << 28)) ? 4 + : 5; + }; + + // Returns the total number of bytes written since this object was created. + int ByteCount() const { + return static_cast<int>(impl_.ByteCount(cur_) - start_count_); + } + + // Instructs the CodedOutputStream to allow the underlying + // ZeroCopyOutputStream to hold pointers to the original structure instead of + // copying, if it supports it (i.e. output->AllowsAliasing() is true). If the + // underlying stream does not support aliasing, then enabling it has no + // affect. For now, this only affects the behavior of + // WriteRawMaybeAliased(). + // + // NOTE: It is caller's responsibility to ensure that the chunk of memory + // remains live until all of the data has been consumed from the stream. + void EnableAliasing(bool enabled) { impl_.EnableAliasing(enabled); } + + // Indicate to the serializer whether the user wants derministic + // serialization. The default when this is not called comes from the global + // default, controlled by SetDefaultSerializationDeterministic. + // + // What deterministic serialization means is entirely up to the driver of the + // serialization process (i.e. the caller of methods like WriteVarint32). In + // the case of serializing a proto buffer message using one of the methods of + // MessageLite, this means that for a given binary equal messages will always + // be serialized to the same bytes. This implies: + // + // * Repeated serialization of a message will return the same bytes. + // + // * Different processes running the same binary (including on different + // machines) will serialize equal messages to the same bytes. + // + // Note that this is *not* canonical across languages. It is also unstable + // across different builds with intervening message definition changes, due to + // unknown fields. Users who need canonical serialization (e.g. persistent + // storage in a canonical form, fingerprinting) should define their own + // canonicalization specification and implement the serializer using + // reflection APIs rather than relying on this API. + void SetSerializationDeterministic(bool value) { + impl_.SetSerializationDeterministic(value); + } + + // Return whether the user wants deterministic serialization. See above. + bool IsSerializationDeterministic() const { + return impl_.IsSerializationDeterministic(); + } + + static bool IsDefaultSerializationDeterministic() { + return default_serialization_deterministic_.load( + std::memory_order_relaxed) != 0; + } + + template <typename Func> + void Serialize(const Func& func); + + uint8_t* Cur() const { return cur_; } + void SetCur(uint8_t* ptr) { cur_ = ptr; } + EpsCopyOutputStream* EpsCopy() { return &impl_; } + + private: + EpsCopyOutputStream impl_; + uint8_t* cur_; + arc_i64 start_count_; + static std::atomic<bool> default_serialization_deterministic_; + + // See above. Other projects may use "friend" to allow them to call this. + // After SetDefaultSerializationDeterministic() completes, all protocol + // buffer serializations will be deterministic by default. Thread safe. + // However, the meaning of "after" is subtle here: to be safe, each thread + // that wants deterministic serialization by default needs to call + // SetDefaultSerializationDeterministic() or ensure on its own that another + // thread has done so. + friend void internal::MapTestForceDeterministic(); + static void SetDefaultSerializationDeterministic() { + default_serialization_deterministic_.store(true, std::memory_order_relaxed); + } + // REQUIRES: value >= 0x80, and that (value & 7f) has been written to *target. + static uint8_t* WriteVarint32ToArrayOutOfLineHelper(arc_ui32 value, + uint8_t* target); + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(CodedOutputStream); +}; + +// inline methods ==================================================== +// The vast majority of varints are only one byte. These inline +// methods optimize for that case. + +inline bool CodedInputStream::ReadVarint32(arc_ui32* value) { + arc_ui32 v = 0; + if (PROTOBUF_PREDICT_TRUE(buffer_ < buffer_end_)) { + v = *buffer_; + if (v < 0x80) { + *value = v; + Advance(1); + return true; + } + } + arc_i64 result = ReadVarint32Fallback(v); + *value = static_cast<arc_ui32>(result); + return result >= 0; +} + +inline bool CodedInputStream::ReadVarint64(arc_ui64* value) { + if (PROTOBUF_PREDICT_TRUE(buffer_ < buffer_end_) && *buffer_ < 0x80) { + *value = *buffer_; + Advance(1); + return true; + } + std::pair<arc_ui64, bool> p = ReadVarint64Fallback(); + *value = p.first; + return p.second; +} + +inline bool CodedInputStream::ReadVarintSizeAsInt(int* value) { + if (PROTOBUF_PREDICT_TRUE(buffer_ < buffer_end_)) { + int v = *buffer_; + if (v < 0x80) { + *value = v; + Advance(1); + return true; + } + } + *value = ReadVarintSizeAsIntFallback(); + return *value >= 0; +} + +// static +inline const uint8_t* CodedInputStream::ReadLittleEndian32FromArray( + const uint8_t* buffer, arc_ui32* value) { +#if defined(PROTOBUF_LITTLE_ENDIAN) + memcpy(value, buffer, sizeof(*value)); + return buffer + sizeof(*value); +#else + *value = (static_cast<arc_ui32>(buffer[0])) | + (static_cast<arc_ui32>(buffer[1]) << 8) | + (static_cast<arc_ui32>(buffer[2]) << 16) | + (static_cast<arc_ui32>(buffer[3]) << 24); + return buffer + sizeof(*value); +#endif +} +// static +inline const uint8_t* CodedInputStream::ReadLittleEndian64FromArray( + const uint8_t* buffer, arc_ui64* value) { +#if defined(PROTOBUF_LITTLE_ENDIAN) + memcpy(value, buffer, sizeof(*value)); + return buffer + sizeof(*value); +#else + arc_ui32 part0 = (static_cast<arc_ui32>(buffer[0])) | + (static_cast<arc_ui32>(buffer[1]) << 8) | + (static_cast<arc_ui32>(buffer[2]) << 16) | + (static_cast<arc_ui32>(buffer[3]) << 24); + arc_ui32 part1 = (static_cast<arc_ui32>(buffer[4])) | + (static_cast<arc_ui32>(buffer[5]) << 8) | + (static_cast<arc_ui32>(buffer[6]) << 16) | + (static_cast<arc_ui32>(buffer[7]) << 24); + *value = static_cast<arc_ui64>(part0) | (static_cast<arc_ui64>(part1) << 32); + return buffer + sizeof(*value); +#endif +} + +inline bool CodedInputStream::ReadLittleEndian32(arc_ui32* value) { +#if defined(PROTOBUF_LITTLE_ENDIAN) + if (PROTOBUF_PREDICT_TRUE(BufferSize() >= static_cast<int>(sizeof(*value)))) { + buffer_ = ReadLittleEndian32FromArray(buffer_, value); + return true; + } else { + return ReadLittleEndian32Fallback(value); + } +#else + return ReadLittleEndian32Fallback(value); +#endif +} + +inline bool CodedInputStream::ReadLittleEndian64(arc_ui64* value) { +#if defined(PROTOBUF_LITTLE_ENDIAN) + if (PROTOBUF_PREDICT_TRUE(BufferSize() >= static_cast<int>(sizeof(*value)))) { + buffer_ = ReadLittleEndian64FromArray(buffer_, value); + return true; + } else { + return ReadLittleEndian64Fallback(value); + } +#else + return ReadLittleEndian64Fallback(value); +#endif +} + +inline arc_ui32 CodedInputStream::ReadTagNoLastTag() { + arc_ui32 v = 0; + if (PROTOBUF_PREDICT_TRUE(buffer_ < buffer_end_)) { + v = *buffer_; + if (v < 0x80) { + Advance(1); + return v; + } + } + v = ReadTagFallback(v); + return v; +} + +inline std::pair<arc_ui32, bool> CodedInputStream::ReadTagWithCutoffNoLastTag( + arc_ui32 cutoff) { + // In performance-sensitive code we can expect cutoff to be a compile-time + // constant, and things like "cutoff >= kMax1ByteVarint" to be evaluated at + // compile time. + arc_ui32 first_byte_or_zero = 0; + if (PROTOBUF_PREDICT_TRUE(buffer_ < buffer_end_)) { + // Hot case: buffer_ non_empty, buffer_[0] in [1, 128). + // TODO(gpike): Is it worth rearranging this? E.g., if the number of fields + // is large enough then is it better to check for the two-byte case first? + first_byte_or_zero = buffer_[0]; + if (static_cast<int8_t>(buffer_[0]) > 0) { + const arc_ui32 kMax1ByteVarint = 0x7f; + arc_ui32 tag = buffer_[0]; + Advance(1); + return std::make_pair(tag, cutoff >= kMax1ByteVarint || tag <= cutoff); + } + // Other hot case: cutoff >= 0x80, buffer_ has at least two bytes available, + // and tag is two bytes. The latter is tested by bitwise-and-not of the + // first byte and the second byte. + if (cutoff >= 0x80 && PROTOBUF_PREDICT_TRUE(buffer_ + 1 < buffer_end_) && + PROTOBUF_PREDICT_TRUE((buffer_[0] & ~buffer_[1]) >= 0x80)) { + const arc_ui32 kMax2ByteVarint = (0x7f << 7) + 0x7f; + arc_ui32 tag = (1u << 7) * buffer_[1] + (buffer_[0] - 0x80); + Advance(2); + // It might make sense to test for tag == 0 now, but it is so rare that + // that we don't bother. A varint-encoded 0 should be one byte unless + // the encoder lost its mind. The second part of the return value of + // this function is allowed to be either true or false if the tag is 0, + // so we don't have to check for tag == 0. We may need to check whether + // it exceeds cutoff. + bool at_or_below_cutoff = cutoff >= kMax2ByteVarint || tag <= cutoff; + return std::make_pair(tag, at_or_below_cutoff); + } + } + // Slow path + const arc_ui32 tag = ReadTagFallback(first_byte_or_zero); + return std::make_pair(tag, static_cast<arc_ui32>(tag - 1) < cutoff); +} + +inline bool CodedInputStream::LastTagWas(arc_ui32 expected) { + return last_tag_ == expected; +} + +inline bool CodedInputStream::ConsumedEntireMessage() { + return legitimate_message_end_; +} + +inline bool CodedInputStream::ExpectTag(arc_ui32 expected) { + if (expected < (1 << 7)) { + if (PROTOBUF_PREDICT_TRUE(buffer_ < buffer_end_) && + buffer_[0] == expected) { + Advance(1); + return true; + } else { + return false; + } + } else if (expected < (1 << 14)) { + if (PROTOBUF_PREDICT_TRUE(BufferSize() >= 2) && + buffer_[0] == static_cast<uint8_t>(expected | 0x80) && + buffer_[1] == static_cast<uint8_t>(expected >> 7)) { + Advance(2); + return true; + } else { + return false; + } + } else { + // Don't bother optimizing for larger values. + return false; + } +} + +inline const uint8_t* CodedInputStream::ExpectTagFromArray( + const uint8_t* buffer, arc_ui32 expected) { + if (expected < (1 << 7)) { + if (buffer[0] == expected) { + return buffer + 1; + } + } else if (expected < (1 << 14)) { + if (buffer[0] == static_cast<uint8_t>(expected | 0x80) && + buffer[1] == static_cast<uint8_t>(expected >> 7)) { + return buffer + 2; + } + } + return nullptr; +} + +inline void CodedInputStream::GetDirectBufferPointerInline(const void** data, + int* size) { + *data = buffer_; + *size = static_cast<int>(buffer_end_ - buffer_); +} + +inline bool CodedInputStream::ExpectAtEnd() { + // If we are at a limit we know no more bytes can be read. Otherwise, it's + // hard to say without calling Refresh(), and we'd rather not do that. + + if (buffer_ == buffer_end_ && ((buffer_size_after_limit_ != 0) || + (total_bytes_read_ == current_limit_))) { + last_tag_ = 0; // Pretend we called ReadTag()... + legitimate_message_end_ = true; // ... and it hit EOF. + return true; + } else { + return false; + } +} + +inline int CodedInputStream::CurrentPosition() const { + return total_bytes_read_ - (BufferSize() + buffer_size_after_limit_); +} + +inline void CodedInputStream::Advance(int amount) { buffer_ += amount; } + +inline void CodedInputStream::SetRecursionLimit(int limit) { + recursion_budget_ += limit - recursion_limit_; + recursion_limit_ = limit; +} + +inline bool CodedInputStream::IncrementRecursionDepth() { + --recursion_budget_; + return recursion_budget_ >= 0; +} + +inline void CodedInputStream::DecrementRecursionDepth() { + if (recursion_budget_ < recursion_limit_) ++recursion_budget_; +} + +inline void CodedInputStream::UnsafeDecrementRecursionDepth() { + assert(recursion_budget_ < recursion_limit_); + ++recursion_budget_; +} + +inline void CodedInputStream::SetExtensionRegistry(const DescriptorPool* pool, + MessageFactory* factory) { + extension_pool_ = pool; + extension_factory_ = factory; +} + +inline const DescriptorPool* CodedInputStream::GetExtensionPool() { + return extension_pool_; +} + +inline MessageFactory* CodedInputStream::GetExtensionFactory() { + return extension_factory_; +} + +inline int CodedInputStream::BufferSize() const { + return static_cast<int>(buffer_end_ - buffer_); +} + +inline CodedInputStream::CodedInputStream(ZeroCopyInputStream* input) + : buffer_(nullptr), + buffer_end_(nullptr), + input_(input), + total_bytes_read_(0), + overflow_bytes_(0), + last_tag_(0), + legitimate_message_end_(false), + aliasing_enabled_(false), + current_limit_(std::numeric_limits<arc_i32>::max()), + buffer_size_after_limit_(0), + total_bytes_limit_(kDefaultTotalBytesLimit), + recursion_budget_(default_recursion_limit_), + recursion_limit_(default_recursion_limit_), + extension_pool_(nullptr), + extension_factory_(nullptr) { + // Eagerly Refresh() so buffer space is immediately available. + Refresh(); +} + +inline CodedInputStream::CodedInputStream(const uint8_t* buffer, int size) + : buffer_(buffer), + buffer_end_(buffer + size), + input_(nullptr), + total_bytes_read_(size), + overflow_bytes_(0), + last_tag_(0), + legitimate_message_end_(false), + aliasing_enabled_(false), + current_limit_(size), + buffer_size_after_limit_(0), + total_bytes_limit_(kDefaultTotalBytesLimit), + recursion_budget_(default_recursion_limit_), + recursion_limit_(default_recursion_limit_), + extension_pool_(nullptr), + extension_factory_(nullptr) { + // Note that setting current_limit_ == size is important to prevent some + // code paths from trying to access input_ and segfaulting. +} + +inline bool CodedInputStream::IsFlat() const { return input_ == nullptr; } + +inline bool CodedInputStream::Skip(int count) { + if (count < 0) return false; // security: count is often user-supplied + + const int original_buffer_size = BufferSize(); + + if (count <= original_buffer_size) { + // Just skipping within the current buffer. Easy. + Advance(count); + return true; + } + + return SkipFallback(count, original_buffer_size); +} + +inline uint8_t* CodedOutputStream::WriteVarint32ToArray(arc_ui32 value, + uint8_t* target) { + return EpsCopyOutputStream::UnsafeVarint(value, target); +} + +inline uint8_t* CodedOutputStream::WriteVarint32ToArrayOutOfLine( + arc_ui32 value, uint8_t* target) { + target[0] = static_cast<uint8_t>(value); + if (value < 0x80) { + return target + 1; + } else { + return WriteVarint32ToArrayOutOfLineHelper(value, target); + } +} + +inline uint8_t* CodedOutputStream::WriteVarint64ToArray(arc_ui64 value, + uint8_t* target) { + return EpsCopyOutputStream::UnsafeVarint(value, target); +} + +inline void CodedOutputStream::WriteVarint32SignExtended(arc_i32 value) { + WriteVarint64(static_cast<arc_ui64>(value)); +} + +inline uint8_t* CodedOutputStream::WriteVarint32SignExtendedToArray( + arc_i32 value, uint8_t* target) { + return WriteVarint64ToArray(static_cast<arc_ui64>(value), target); +} + +inline uint8_t* CodedOutputStream::WriteLittleEndian32ToArray(arc_ui32 value, + uint8_t* target) { +#if defined(PROTOBUF_LITTLE_ENDIAN) + memcpy(target, &value, sizeof(value)); +#else + target[0] = static_cast<uint8_t>(value); + target[1] = static_cast<uint8_t>(value >> 8); + target[2] = static_cast<uint8_t>(value >> 16); + target[3] = static_cast<uint8_t>(value >> 24); +#endif + return target + sizeof(value); +} + +inline uint8_t* CodedOutputStream::WriteLittleEndian64ToArray(arc_ui64 value, + uint8_t* target) { +#if defined(PROTOBUF_LITTLE_ENDIAN) + memcpy(target, &value, sizeof(value)); +#else + arc_ui32 part0 = static_cast<arc_ui32>(value); + arc_ui32 part1 = static_cast<arc_ui32>(value >> 32); + + target[0] = static_cast<uint8_t>(part0); + target[1] = static_cast<uint8_t>(part0 >> 8); + target[2] = static_cast<uint8_t>(part0 >> 16); + target[3] = static_cast<uint8_t>(part0 >> 24); + target[4] = static_cast<uint8_t>(part1); + target[5] = static_cast<uint8_t>(part1 >> 8); + target[6] = static_cast<uint8_t>(part1 >> 16); + target[7] = static_cast<uint8_t>(part1 >> 24); +#endif + return target + sizeof(value); +} + +inline void CodedOutputStream::WriteVarint32(arc_ui32 value) { + cur_ = impl_.EnsureSpace(cur_); + SetCur(WriteVarint32ToArray(value, Cur())); +} + +inline void CodedOutputStream::WriteVarint64(arc_ui64 value) { + cur_ = impl_.EnsureSpace(cur_); + SetCur(WriteVarint64ToArray(value, Cur())); +} + +inline void CodedOutputStream::WriteTag(arc_ui32 value) { + WriteVarint32(value); +} + +inline uint8_t* CodedOutputStream::WriteTagToArray(arc_ui32 value, + uint8_t* target) { + return WriteVarint32ToArray(value, target); +} + +inline size_t CodedOutputStream::VarintSize32(arc_ui32 value) { + // This computes value == 0 ? 1 : floor(log2(value)) / 7 + 1 + // Use an explicit multiplication to implement the divide of + // a number in the 1..31 range. + // Explicit OR 0x1 to avoid calling Bits::Log2FloorNonZero(0), which is + // undefined. + arc_ui32 log2value = Bits::Log2FloorNonZero(value | 0x1); + return static_cast<size_t>((log2value * 9 + 73) / 64); +} + +inline size_t CodedOutputStream::VarintSize32PlusOne(arc_ui32 value) { + // Same as above, but one more. + arc_ui32 log2value = Bits::Log2FloorNonZero(value | 0x1); + return static_cast<size_t>((log2value * 9 + 73 + 64) / 64); +} + +inline size_t CodedOutputStream::VarintSize64(arc_ui64 value) { + // This computes value == 0 ? 1 : floor(log2(value)) / 7 + 1 + // Use an explicit multiplication to implement the divide of + // a number in the 1..63 range. + // Explicit OR 0x1 to avoid calling Bits::Log2FloorNonZero(0), which is + // undefined. + arc_ui32 log2value = Bits::Log2FloorNonZero64(value | 0x1); + return static_cast<size_t>((log2value * 9 + 73) / 64); +} + +inline size_t CodedOutputStream::VarintSize64PlusOne(arc_ui64 value) { + // Same as above, but one more. + arc_ui32 log2value = Bits::Log2FloorNonZero64(value | 0x1); + return static_cast<size_t>((log2value * 9 + 73 + 64) / 64); +} + +inline size_t CodedOutputStream::VarintSize32SignExtended(arc_i32 value) { + return VarintSize64(static_cast<arc_ui64>(arc_i64{value})); +} + +inline size_t CodedOutputStream::VarintSize32SignExtendedPlusOne( + arc_i32 value) { + return VarintSize64PlusOne(static_cast<arc_ui64>(arc_i64{value})); +} + +inline void CodedOutputStream::WriteString(const TProtoStringType& str) { + WriteRaw(str.data(), static_cast<int>(str.size())); +} + +inline void CodedOutputStream::WriteRawMaybeAliased(const void* data, + int size) { + cur_ = impl_.WriteRawMaybeAliased(data, size, cur_); +} + +inline uint8_t* CodedOutputStream::WriteRawToArray(const void* data, int size, + uint8_t* target) { + memcpy(target, data, size); + return target + size; +} + +inline uint8_t* CodedOutputStream::WriteStringToArray(const TProtoStringType& str, + uint8_t* target) { + return WriteRawToArray(str.data(), static_cast<int>(str.size()), target); +} + +} // namespace io +} // namespace protobuf +} // namespace google + +#if defined(_MSC_VER) && _MSC_VER >= 1300 && !defined(__INTEL_COMPILER) +#pragma runtime_checks("c", restore) +#endif // _MSC_VER && !defined(__INTEL_COMPILER) + +#include <google/protobuf/port_undef.inc> + +#endif // GOOGLE_PROTOBUF_IO_CODED_STREAM_H__ diff --git a/contrib/libs/protobuf_old/src/google/protobuf/io/gzip_stream.cc b/contrib/libs/protobuf_old/src/google/protobuf/io/gzip_stream.cc new file mode 100644 index 0000000000..05c7772bd5 --- /dev/null +++ b/contrib/libs/protobuf_old/src/google/protobuf/io/gzip_stream.cc @@ -0,0 +1,333 @@ +// 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: brianolson@google.com (Brian Olson) +// +// This file contains the implementation of classes GzipInputStream and +// GzipOutputStream. + + +#if HAVE_ZLIB +#include <google/protobuf/io/gzip_stream.h> + +#include <google/protobuf/stubs/common.h> +#include <google/protobuf/stubs/logging.h> + +namespace google { +namespace protobuf { +namespace io { + +static const int kDefaultBufferSize = 65536; + +GzipInputStream::GzipInputStream(ZeroCopyInputStream* sub_stream, Format format, + int buffer_size) + : format_(format), sub_stream_(sub_stream), zerror_(Z_OK), byte_count_(0) { + zcontext_.state = Z_NULL; + zcontext_.zalloc = Z_NULL; + zcontext_.zfree = Z_NULL; + zcontext_.opaque = Z_NULL; + zcontext_.total_out = 0; + zcontext_.next_in = NULL; + zcontext_.avail_in = 0; + zcontext_.total_in = 0; + zcontext_.msg = NULL; + if (buffer_size == -1) { + output_buffer_length_ = kDefaultBufferSize; + } else { + output_buffer_length_ = buffer_size; + } + output_buffer_ = operator new(output_buffer_length_); + GOOGLE_CHECK(output_buffer_ != NULL); + zcontext_.next_out = static_cast<Bytef*>(output_buffer_); + zcontext_.avail_out = output_buffer_length_; + output_position_ = output_buffer_; +} +GzipInputStream::~GzipInputStream() { + operator delete(output_buffer_); + zerror_ = inflateEnd(&zcontext_); +} + +static inline int internalInflateInit2(z_stream* zcontext, + GzipInputStream::Format format) { + int windowBitsFormat = 0; + switch (format) { + case GzipInputStream::GZIP: + windowBitsFormat = 16; + break; + case GzipInputStream::AUTO: + windowBitsFormat = 32; + break; + case GzipInputStream::ZLIB: + windowBitsFormat = 0; + break; + } + return inflateInit2(zcontext, /* windowBits */ 15 | windowBitsFormat); +} + +int GzipInputStream::Inflate(int flush) { + if ((zerror_ == Z_OK) && (zcontext_.avail_out == 0)) { + // previous inflate filled output buffer. don't change input params yet. + } else if (zcontext_.avail_in == 0) { + const void* in; + int in_size; + bool first = zcontext_.next_in == NULL; + bool ok = sub_stream_->Next(&in, &in_size); + if (!ok) { + zcontext_.next_out = NULL; + zcontext_.avail_out = 0; + return Z_STREAM_END; + } + zcontext_.next_in = static_cast<Bytef*>(const_cast<void*>(in)); + zcontext_.avail_in = in_size; + if (first) { + int error = internalInflateInit2(&zcontext_, format_); + if (error != Z_OK) { + return error; + } + } + } + zcontext_.next_out = static_cast<Bytef*>(output_buffer_); + zcontext_.avail_out = output_buffer_length_; + output_position_ = output_buffer_; + int error = inflate(&zcontext_, flush); + return error; +} + +void GzipInputStream::DoNextOutput(const void** data, int* size) { + *data = output_position_; + *size = ((uintptr_t)zcontext_.next_out) - ((uintptr_t)output_position_); + output_position_ = zcontext_.next_out; +} + +// implements ZeroCopyInputStream ---------------------------------- +bool GzipInputStream::Next(const void** data, int* size) { + bool ok = (zerror_ == Z_OK) || (zerror_ == Z_STREAM_END) || + (zerror_ == Z_BUF_ERROR); + if ((!ok) || (zcontext_.next_out == NULL)) { + return false; + } + if (zcontext_.next_out != output_position_) { + DoNextOutput(data, size); + return true; + } + if (zerror_ == Z_STREAM_END) { + if (zcontext_.next_out != NULL) { + // sub_stream_ may have concatenated streams to follow + zerror_ = inflateEnd(&zcontext_); + byte_count_ += zcontext_.total_out; + if (zerror_ != Z_OK) { + return false; + } + zerror_ = internalInflateInit2(&zcontext_, format_); + if (zerror_ != Z_OK) { + return false; + } + } else { + *data = NULL; + *size = 0; + return false; + } + } + zerror_ = Inflate(Z_NO_FLUSH); + if ((zerror_ == Z_STREAM_END) && (zcontext_.next_out == NULL)) { + // The underlying stream's Next returned false inside Inflate. + return false; + } + ok = (zerror_ == Z_OK) || (zerror_ == Z_STREAM_END) || + (zerror_ == Z_BUF_ERROR); + if (!ok) { + return false; + } + DoNextOutput(data, size); + return true; +} +void GzipInputStream::BackUp(int count) { + output_position_ = reinterpret_cast<void*>( + reinterpret_cast<uintptr_t>(output_position_) - count); +} +bool GzipInputStream::Skip(int count) { + const void* data; + int size = 0; + bool ok = Next(&data, &size); + while (ok && (size < count)) { + count -= size; + ok = Next(&data, &size); + } + if (size > count) { + BackUp(size - count); + } + return ok; +} +int64_t GzipInputStream::ByteCount() const { + arc_i64 ret = byte_count_ + zcontext_.total_out; + if (zcontext_.next_out != NULL && output_position_ != NULL) { + ret += reinterpret_cast<uintptr_t>(zcontext_.next_out) - + reinterpret_cast<uintptr_t>(output_position_); + } + return ret; +} + +// ========================================================================= + +GzipOutputStream::Options::Options() + : format(GZIP), + buffer_size(kDefaultBufferSize), + compression_level(Z_DEFAULT_COMPRESSION), + compression_strategy(Z_DEFAULT_STRATEGY) {} + +GzipOutputStream::GzipOutputStream(ZeroCopyOutputStream* sub_stream) { + Init(sub_stream, Options()); +} + +GzipOutputStream::GzipOutputStream(ZeroCopyOutputStream* sub_stream, + const Options& options) { + Init(sub_stream, options); +} + +void GzipOutputStream::Init(ZeroCopyOutputStream* sub_stream, + const Options& options) { + sub_stream_ = sub_stream; + sub_data_ = NULL; + sub_data_size_ = 0; + + input_buffer_length_ = options.buffer_size; + input_buffer_ = operator new(input_buffer_length_); + GOOGLE_CHECK(input_buffer_ != NULL); + + zcontext_.zalloc = Z_NULL; + zcontext_.zfree = Z_NULL; + zcontext_.opaque = Z_NULL; + zcontext_.next_out = NULL; + zcontext_.avail_out = 0; + zcontext_.total_out = 0; + zcontext_.next_in = NULL; + zcontext_.avail_in = 0; + zcontext_.total_in = 0; + zcontext_.msg = NULL; + // default to GZIP format + int windowBitsFormat = 16; + if (options.format == ZLIB) { + windowBitsFormat = 0; + } + zerror_ = + deflateInit2(&zcontext_, options.compression_level, Z_DEFLATED, + /* windowBits */ 15 | windowBitsFormat, + /* memLevel (default) */ 8, options.compression_strategy); +} + +GzipOutputStream::~GzipOutputStream() { + Close(); + operator delete(input_buffer_); +} + +// private +int GzipOutputStream::Deflate(int flush) { + int error = Z_OK; + do { + if ((sub_data_ == NULL) || (zcontext_.avail_out == 0)) { + bool ok = sub_stream_->Next(&sub_data_, &sub_data_size_); + if (!ok) { + sub_data_ = NULL; + sub_data_size_ = 0; + return Z_BUF_ERROR; + } + GOOGLE_CHECK_GT(sub_data_size_, 0); + zcontext_.next_out = static_cast<Bytef*>(sub_data_); + zcontext_.avail_out = sub_data_size_; + } + error = deflate(&zcontext_, flush); + } while (error == Z_OK && zcontext_.avail_out == 0); + if ((flush == Z_FULL_FLUSH) || (flush == Z_FINISH)) { + // Notify lower layer of data. + sub_stream_->BackUp(zcontext_.avail_out); + // We don't own the buffer anymore. + sub_data_ = NULL; + sub_data_size_ = 0; + } + return error; +} + +// implements ZeroCopyOutputStream --------------------------------- +bool GzipOutputStream::Next(void** data, int* size) { + if ((zerror_ != Z_OK) && (zerror_ != Z_BUF_ERROR)) { + return false; + } + if (zcontext_.avail_in != 0) { + zerror_ = Deflate(Z_NO_FLUSH); + if (zerror_ != Z_OK) { + return false; + } + } + if (zcontext_.avail_in == 0) { + // all input was consumed. reset the buffer. + zcontext_.next_in = static_cast<Bytef*>(input_buffer_); + zcontext_.avail_in = input_buffer_length_; + *data = input_buffer_; + *size = input_buffer_length_; + } else { + // The loop in Deflate should consume all avail_in + GOOGLE_LOG(DFATAL) << "Deflate left bytes unconsumed"; + } + return true; +} +void GzipOutputStream::BackUp(int count) { + GOOGLE_CHECK_GE(zcontext_.avail_in, static_cast<uInt>(count)); + zcontext_.avail_in -= count; +} +int64_t GzipOutputStream::ByteCount() const { + return zcontext_.total_in + zcontext_.avail_in; +} + +bool GzipOutputStream::Flush() { + zerror_ = Deflate(Z_FULL_FLUSH); + // Return true if the flush succeeded or if it was a no-op. + return (zerror_ == Z_OK) || + (zerror_ == Z_BUF_ERROR && zcontext_.avail_in == 0 && + zcontext_.avail_out != 0); +} + +bool GzipOutputStream::Close() { + if ((zerror_ != Z_OK) && (zerror_ != Z_BUF_ERROR)) { + return false; + } + do { + zerror_ = Deflate(Z_FINISH); + } while (zerror_ == Z_OK); + zerror_ = deflateEnd(&zcontext_); + bool ok = zerror_ == Z_OK; + zerror_ = Z_STREAM_END; + return ok; +} + +} // namespace io +} // namespace protobuf +} // namespace google + +#endif // HAVE_ZLIB diff --git a/contrib/libs/protobuf_old/src/google/protobuf/io/gzip_stream.h b/contrib/libs/protobuf_old/src/google/protobuf/io/gzip_stream.h new file mode 100644 index 0000000000..43c740c78d --- /dev/null +++ b/contrib/libs/protobuf_old/src/google/protobuf/io/gzip_stream.h @@ -0,0 +1,202 @@ +// 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: brianolson@google.com (Brian Olson) +// +// This file contains the definition for classes GzipInputStream and +// GzipOutputStream. +// +// GzipInputStream decompresses data from an underlying +// ZeroCopyInputStream and provides the decompressed data as a +// ZeroCopyInputStream. +// +// GzipOutputStream is an ZeroCopyOutputStream that compresses data to +// an underlying ZeroCopyOutputStream. + +#ifndef GOOGLE_PROTOBUF_IO_GZIP_STREAM_H__ +#define GOOGLE_PROTOBUF_IO_GZIP_STREAM_H__ + + +#include <google/protobuf/stubs/common.h> +#include <google/protobuf/io/zero_copy_stream.h> +#include <google/protobuf/port.h> +#include <zlib.h> + +#include <google/protobuf/port_def.inc> + +namespace google { +namespace protobuf { +namespace io { + +// A ZeroCopyInputStream that reads compressed data through zlib +class PROTOBUF_EXPORT GzipInputStream : public ZeroCopyInputStream { + public: + // Format key for constructor + enum Format { + // zlib will autodetect gzip header or deflate stream + AUTO = 0, + + // GZIP streams have some extra header data for file attributes. + GZIP = 1, + + // Simpler zlib stream format. + ZLIB = 2, + }; + + // buffer_size and format may be -1 for default of 64kB and GZIP format + explicit GzipInputStream(ZeroCopyInputStream* sub_stream, + Format format = AUTO, int buffer_size = -1); + virtual ~GzipInputStream(); + + // Return last error message or NULL if no error. + inline const char* ZlibErrorMessage() const { return zcontext_.msg; } + inline int ZlibErrorCode() const { return zerror_; } + + // implements ZeroCopyInputStream ---------------------------------- + bool Next(const void** data, int* size) override; + void BackUp(int count) override; + bool Skip(int count) override; + int64_t ByteCount() const override; + + private: + Format format_; + + ZeroCopyInputStream* sub_stream_; + + z_stream zcontext_; + int zerror_; + + void* output_buffer_; + void* output_position_; + size_t output_buffer_length_; + arc_i64 byte_count_; + + int Inflate(int flush); + void DoNextOutput(const void** data, int* size); + + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(GzipInputStream); +}; + +class PROTOBUF_EXPORT GzipOutputStream : public ZeroCopyOutputStream { + public: + // Format key for constructor + enum Format { + // GZIP streams have some extra header data for file attributes. + GZIP = 1, + + // Simpler zlib stream format. + ZLIB = 2, + }; + + struct PROTOBUF_EXPORT Options { + // Defaults to GZIP. + Format format; + + // What size buffer to use internally. Defaults to 64kB. + int buffer_size; + + // A number between 0 and 9, where 0 is no compression and 9 is best + // compression. Defaults to Z_DEFAULT_COMPRESSION (see zlib.h). + int compression_level; + + // Defaults to Z_DEFAULT_STRATEGY. Can also be set to Z_FILTERED, + // Z_HUFFMAN_ONLY, or Z_RLE. See the documentation for deflateInit2 in + // zlib.h for definitions of these constants. + int compression_strategy; + + Options(); // Initializes with default values. + }; + + // Create a GzipOutputStream with default options. + explicit GzipOutputStream(ZeroCopyOutputStream* sub_stream); + + // Create a GzipOutputStream with the given options. + GzipOutputStream(ZeroCopyOutputStream* sub_stream, const Options& options); + + virtual ~GzipOutputStream(); + + // Return last error message or NULL if no error. + inline const char* ZlibErrorMessage() const { return zcontext_.msg; } + inline int ZlibErrorCode() const { return zerror_; } + + // Flushes data written so far to zipped data in the underlying stream. + // It is the caller's responsibility to flush the underlying stream if + // necessary. + // Compression may be less efficient stopping and starting around flushes. + // Returns true if no error. + // + // Please ensure that block size is > 6. Here is an excerpt from the zlib + // doc that explains why: + // + // In the case of a Z_FULL_FLUSH or Z_SYNC_FLUSH, make sure that avail_out + // is greater than six to avoid repeated flush markers due to + // avail_out == 0 on return. + bool Flush(); + + // Writes out all data and closes the gzip stream. + // It is the caller's responsibility to close the underlying stream if + // necessary. + // Returns true if no error. + bool Close(); + + // implements ZeroCopyOutputStream --------------------------------- + bool Next(void** data, int* size) override; + void BackUp(int count) override; + int64_t ByteCount() const override; + + private: + ZeroCopyOutputStream* sub_stream_; + // Result from calling Next() on sub_stream_ + void* sub_data_; + int sub_data_size_; + + z_stream zcontext_; + int zerror_; + void* input_buffer_; + size_t input_buffer_length_; + + // Shared constructor code. + void Init(ZeroCopyOutputStream* sub_stream, const Options& options); + + // Do some compression. + // Takes zlib flush mode. + // Returns zlib error code. + int Deflate(int flush); + + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(GzipOutputStream); +}; + +} // namespace io +} // namespace protobuf +} // namespace google + +#include <google/protobuf/port_undef.inc> + +#endif // GOOGLE_PROTOBUF_IO_GZIP_STREAM_H__ diff --git a/contrib/libs/protobuf_old/src/google/protobuf/io/io_win32.cc b/contrib/libs/protobuf_old/src/google/protobuf/io/io_win32.cc new file mode 100644 index 0000000000..903cb36fc3 --- /dev/null +++ b/contrib/libs/protobuf_old/src/google/protobuf/io/io_win32.cc @@ -0,0 +1,470 @@ +// 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: laszlocsomor@google.com (Laszlo Csomor) +// Based on original Protocol Buffers design by +// Sanjay Ghemawat, Jeff Dean, and others. + +// Implementation for long-path-aware open/mkdir/access/etc. on Windows, as well +// as for the supporting utility functions. +// +// These functions convert the input path to an absolute Windows path +// with "\\?\" prefix, then pass that to _wopen/_wmkdir/_waccess/etc. +// (declared in <io.h>) respectively. This allows working with files/directories +// whose paths are longer than MAX_PATH (260 chars). +// +// This file is only used on Windows, it's empty on other platforms. + +#if defined(_WIN32) && !defined(_XBOX_ONE) + +// Comment this out to fall back to using the ANSI versions (open, mkdir, ...) +// instead of the Unicode ones (_wopen, _wmkdir, ...). Doing so can be useful to +// debug failing tests if that's caused by the long path support. +#define SUPPORT_LONGPATHS + +#include <google/protobuf/io/io_win32.h> + +#include <ctype.h> +#include <direct.h> +#include <errno.h> +#include <fcntl.h> +#include <io.h> +#include <sys/stat.h> +#include <sys/types.h> +#include <wctype.h> + +#ifndef WIN32_LEAN_AND_MEAN +#define WIN32_LEAN_AND_MEAN 1 +#endif + +#include <windows.h> + +#include <memory> +#include <sstream> +#include <string> +#include <vector> + +namespace google { +namespace protobuf { +namespace io { +namespace win32 { +namespace { + +using string = TProtoStringType; +using std::wstring; + +template <typename char_type> +struct CharTraits { + static bool is_alpha(char_type ch); +}; + +template <> +struct CharTraits<char> { + static bool is_alpha(char ch) { return isalpha(ch); } +}; + +template <> +struct CharTraits<wchar_t> { + static bool is_alpha(wchar_t ch) { return iswalpha(ch); } +}; + +template <typename char_type> +bool null_or_empty(const char_type* s) { + return s == nullptr || *s == 0; +} + +// Returns true if the path starts with a drive letter, e.g. "c:". +// Note that this won't check for the "\" after the drive letter, so this also +// returns true for "c:foo" (which is "c:\${PWD}\foo"). +// This check requires that a path not have a longpath prefix ("\\?\"). +template <typename char_type> +bool has_drive_letter(const char_type* ch) { + return CharTraits<char_type>::is_alpha(ch[0]) && ch[1] == ':'; +} + +// Returns true if the path starts with a longpath prefix ("\\?\"). +template <typename char_type> +bool has_longpath_prefix(const char_type* path) { + return path[0] == '\\' && path[1] == '\\' && path[2] == '?' && + path[3] == '\\'; +} + +template <typename char_type> +bool is_separator(char_type c) { + return c == '/' || c == '\\'; +} + +// Returns true if the path starts with a drive specifier (e.g. "c:\"). +template <typename char_type> +bool is_path_absolute(const char_type* path) { + return has_drive_letter(path) && is_separator(path[2]); +} + +template <typename char_type> +bool is_drive_relative(const char_type* path) { + return has_drive_letter(path) && (path[2] == 0 || !is_separator(path[2])); +} + +wstring join_paths(const wstring& path1, const wstring& path2) { + if (path1.empty() || is_path_absolute(path2.c_str()) || + has_longpath_prefix(path2.c_str())) { + return path2; + } + if (path2.empty()) { + return path1; + } + + if (is_separator(path1[path1.size() - 1])) { + return is_separator(path2[0]) ? (path1 + path2.substr(1)) + : (path1 + path2); + } else { + return is_separator(path2[0]) ? (path1 + path2) + : (path1 + L'\\' + path2); + } +} + +wstring normalize(wstring path) { + if (has_longpath_prefix(path.c_str())) { + path = path.substr(4); + } + + static const wstring dot(L"."); + static const wstring dotdot(L".."); + const WCHAR* p = path.c_str(); + + std::vector<wstring> segments; + int segment_start = -1; + // Find the path segments in `path` (separated by "/"). + for (int i = 0;; ++i) { + if (!is_separator(p[i]) && p[i] != L'\0') { + // The current character does not end a segment, so start one unless it's + // already started. + if (segment_start < 0) { + segment_start = i; + } + } else if (segment_start >= 0 && i > segment_start) { + // The current character is "/" or "\0", so this ends a segment. + // Add that to `segments` if there's anything to add; handle "." and "..". + wstring segment(p, segment_start, i - segment_start); + segment_start = -1; + if (segment == dotdot) { + if (!segments.empty() && + (!has_drive_letter(segments[0].c_str()) || segments.size() > 1)) { + segments.pop_back(); + } + } else if (segment != dot && !segment.empty()) { + segments.push_back(segment); + } + } + if (p[i] == L'\0') { + break; + } + } + + // Handle the case when `path` is just a drive specifier (or some degenerate + // form of it, e.g. "c:\.."). + if (segments.size() == 1 && segments[0].size() == 2 && + has_drive_letter(segments[0].c_str())) { + return segments[0] + L'\\'; + } + + // Join all segments. + bool first = true; + std::wstringstream result; + for (int i = 0; i < segments.size(); ++i) { + if (!first) { + result << L'\\'; + } + first = false; + result << segments[i]; + } + // Preserve trailing separator if the input contained it. + if (!path.empty() && is_separator(p[path.size() - 1])) { + result << L'\\'; + } + return result.str(); +} + +bool as_windows_path(const char* path, wstring* result) { + if (null_or_empty(path)) { + result->clear(); + return true; + } + wstring wpath; + if (!strings::utf8_to_wcs(path, &wpath)) { + return false; + } + if (has_longpath_prefix(wpath.c_str())) { + *result = wpath; + return true; + } + if (is_separator(path[0]) || is_drive_relative(path)) { + return false; + } + + + if (!is_path_absolute(wpath.c_str())) { + int size = ::GetCurrentDirectoryW(0, nullptr); + if (size == 0 && GetLastError() != ERROR_INSUFFICIENT_BUFFER) { + return false; + } + std::unique_ptr<WCHAR[]> wcwd(new WCHAR[size]); + ::GetCurrentDirectoryW(size, wcwd.get()); + wpath = join_paths(wcwd.get(), wpath); + } + wpath = normalize(wpath); + if (!has_longpath_prefix(wpath.c_str())) { + // Add the "\\?\" prefix unconditionally. This way we prevent the Win32 API + // from processing the path and "helpfully" removing trailing dots from the + // path, for example. + // See https://github.com/bazelbuild/bazel/issues/2935 + wpath = wstring(L"\\\\?\\") + wpath; + } + *result = wpath; + return true; +} + +} // namespace + +int open(const char* path, int flags, int mode) { +#ifdef SUPPORT_LONGPATHS + wstring wpath; + if (!as_windows_path(path, &wpath)) { + errno = ENOENT; + return -1; + } + return ::_wopen(wpath.c_str(), flags, mode); +#else + return ::_open(path, flags, mode); +#endif +} + +int mkdir(const char* path, int /*_mode*/) { +#ifdef SUPPORT_LONGPATHS + wstring wpath; + if (!as_windows_path(path, &wpath)) { + errno = ENOENT; + return -1; + } + return ::_wmkdir(wpath.c_str()); +#else // not SUPPORT_LONGPATHS + return ::_mkdir(path); +#endif // not SUPPORT_LONGPATHS +} + +int access(const char* path, int mode) { +#ifdef SUPPORT_LONGPATHS + wstring wpath; + if (!as_windows_path(path, &wpath)) { + errno = ENOENT; + return -1; + } + return ::_waccess(wpath.c_str(), mode); +#else + return ::_access(path, mode); +#endif +} + +int chdir(const char* path) { +#ifdef SUPPORT_LONGPATHS + wstring wpath; + if (!as_windows_path(path, &wpath)) { + errno = ENOENT; + return -1; + } + return ::_wchdir(wpath.c_str()); +#else + return ::_chdir(path); +#endif +} + +int stat(const char* path, struct _stat* buffer) { +#ifdef SUPPORT_LONGPATHS + wstring wpath; + if (!as_windows_path(path, &wpath)) { + errno = ENOENT; + return -1; + } + return ::_wstat(wpath.c_str(), buffer); +#else // not SUPPORT_LONGPATHS + return ::_stat(path, buffer); +#endif // not SUPPORT_LONGPATHS +} + +FILE* fopen(const char* path, const char* mode) { +#ifdef SUPPORT_LONGPATHS + if (null_or_empty(path)) { + errno = EINVAL; + return nullptr; + } + wstring wpath; + if (!as_windows_path(path, &wpath)) { + errno = ENOENT; + return nullptr; + } + wstring wmode; + if (!strings::utf8_to_wcs(mode, &wmode)) { + errno = EINVAL; + return nullptr; + } + return ::_wfopen(wpath.c_str(), wmode.c_str()); +#else + return ::fopen(path, mode); +#endif +} + +int close(int fd) { return ::_close(fd); } + +int dup(int fd) { return ::_dup(fd); } + +int dup2(int fd1, int fd2) { return ::_dup2(fd1, fd2); } + +int read(int fd, void* buffer, size_t size) { + return ::_read(fd, buffer, size); +} + +int setmode(int fd, int mode) { return ::_setmode(fd, mode); } + +int write(int fd, const void* buffer, size_t size) { + return ::_write(fd, buffer, size); +} + +wstring testonly_utf8_to_winpath(const char* path) { + wstring wpath; + return as_windows_path(path, &wpath) ? wpath : wstring(); +} + +ExpandWildcardsResult ExpandWildcards( + const string& path, std::function<void(const string&)> consume) { + if (path.find_first_of("*?") == string::npos) { + // There are no wildcards in the path, we don't need to expand it. + consume(path); + return ExpandWildcardsResult::kSuccess; + } + + wstring wpath; + if (!as_windows_path(path.c_str(), &wpath)) { + return ExpandWildcardsResult::kErrorInputPathConversion; + } + + static const wstring kDot = L"."; + static const wstring kDotDot = L".."; + WIN32_FIND_DATAW metadata; + HANDLE handle = ::FindFirstFileW(wpath.c_str(), &metadata); + if (handle == INVALID_HANDLE_VALUE) { + // The pattern does not match any files (or directories). + return ExpandWildcardsResult::kErrorNoMatchingFile; + } + + string::size_type pos = path.find_last_of("\\/"); + string dirname; + if (pos != string::npos) { + dirname = path.substr(0, pos + 1); + } + + ExpandWildcardsResult matched = ExpandWildcardsResult::kErrorNoMatchingFile; + do { + // Ignore ".", "..", and directories. + if ((metadata.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) == 0 && + kDot != metadata.cFileName && kDotDot != metadata.cFileName) { + matched = ExpandWildcardsResult::kSuccess; + string filename; + if (!strings::wcs_to_utf8(metadata.cFileName, &filename)) { + return ExpandWildcardsResult::kErrorOutputPathConversion; + } + + if (dirname.empty()) { + consume(filename); + } else { + consume(dirname + filename); + } + } + } while (::FindNextFileW(handle, &metadata)); + FindClose(handle); + return matched; +} + +namespace strings { + +bool wcs_to_mbs(const WCHAR* s, string* out, bool outUtf8) { + if (null_or_empty(s)) { + out->clear(); + return true; + } + BOOL usedDefaultChar = FALSE; + SetLastError(0); + int size = WideCharToMultiByte( + outUtf8 ? CP_UTF8 : CP_ACP, 0, s, -1, nullptr, 0, nullptr, + outUtf8 ? nullptr : &usedDefaultChar); + if ((size == 0 && GetLastError() != ERROR_INSUFFICIENT_BUFFER) + || usedDefaultChar) { + return false; + } + std::unique_ptr<CHAR[]> astr(new CHAR[size]); + WideCharToMultiByte( + outUtf8 ? CP_UTF8 : CP_ACP, 0, s, -1, astr.get(), size, nullptr, nullptr); + out->assign(astr.get()); + return true; +} + +bool mbs_to_wcs(const char* s, wstring* out, bool inUtf8) { + if (null_or_empty(s)) { + out->clear(); + return true; + } + + SetLastError(0); + int size = + MultiByteToWideChar(inUtf8 ? CP_UTF8 : CP_ACP, 0, s, -1, nullptr, 0); + if (size == 0 && GetLastError() != ERROR_INSUFFICIENT_BUFFER) { + return false; + } + std::unique_ptr<WCHAR[]> wstr(new WCHAR[size]); + MultiByteToWideChar( + inUtf8 ? CP_UTF8 : CP_ACP, 0, s, -1, wstr.get(), size + 1); + out->assign(wstr.get()); + return true; +} + +bool utf8_to_wcs(const char* input, wstring* out) { + return mbs_to_wcs(input, out, true); +} + +bool wcs_to_utf8(const wchar_t* input, string* out) { + return wcs_to_mbs(input, out, true); +} + +} // namespace strings +} // namespace win32 +} // namespace io +} // namespace protobuf +} // namespace google + +#endif // defined(_WIN32) diff --git a/contrib/libs/protobuf_old/src/google/protobuf/io/io_win32.h b/contrib/libs/protobuf_old/src/google/protobuf/io/io_win32.h new file mode 100644 index 0000000000..8fb782f753 --- /dev/null +++ b/contrib/libs/protobuf_old/src/google/protobuf/io/io_win32.h @@ -0,0 +1,140 @@ +// 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: laszlocsomor@google.com (Laszlo Csomor) +// Based on original Protocol Buffers design by +// Sanjay Ghemawat, Jeff Dean, and others. + +// This file contains the declarations for Windows implementations of +// commonly used POSIX functions such as open(2) and access(2), as well +// as macro definitions for flags of these functions. +// +// By including this file you'll redefine open/access/etc. to +// ::google::protobuf::io::win32::{open/access/etc.}. +// Make sure you don't include a header that attempts to redeclare or +// redefine these functions, that'll lead to confusing compilation +// errors. It's best to #include this file as the last one to ensure that. +// +// This file is only used on Windows, it's empty on other platforms. + +#ifndef GOOGLE_PROTOBUF_IO_IO_WIN32_H__ +#define GOOGLE_PROTOBUF_IO_IO_WIN32_H__ + +#if defined(_WIN32) + +#include <functional> +#include <string> + +#include <google/protobuf/stubs/port.h> +#include <google/protobuf/port.h> +#include <google/protobuf/port_def.inc> + +// Compilers on Windows other than MSVC (e.g. Cygwin, MinGW32) define the +// following functions already, except for mkdir. +namespace google { +namespace protobuf { +namespace io { +namespace win32 { + +PROTOBUF_EXPORT FILE* fopen(const char* path, const char* mode); +PROTOBUF_EXPORT int access(const char* path, int mode); +PROTOBUF_EXPORT int chdir(const char* path); +PROTOBUF_EXPORT int close(int fd); +PROTOBUF_EXPORT int dup(int fd); +PROTOBUF_EXPORT int dup2(int fd1, int fd2); +PROTOBUF_EXPORT int mkdir(const char* path, int _mode); +PROTOBUF_EXPORT int open(const char* path, int flags, int mode = 0); +PROTOBUF_EXPORT int read(int fd, void* buffer, size_t size); +PROTOBUF_EXPORT int setmode(int fd, int mode); +PROTOBUF_EXPORT int stat(const char* path, struct _stat* buffer); +PROTOBUF_EXPORT int write(int fd, const void* buffer, size_t size); +PROTOBUF_EXPORT std::wstring testonly_utf8_to_winpath(const char* path); + +enum class ExpandWildcardsResult { + kSuccess = 0, + kErrorNoMatchingFile = 1, + kErrorInputPathConversion = 2, + kErrorOutputPathConversion = 3, +}; + +// Expand wildcards in a path pattern, feed the result to a consumer function. +// +// `path` must be a valid, Windows-style path. It may be absolute, or relative +// to the current working directory, and it may contain wildcards ("*" and "?") +// in the last path segment. This function passes all matching file names to +// `consume`. The resulting paths may not be absolute nor normalized. +// +// The function returns a value from `ExpandWildcardsResult`. +PROTOBUF_EXPORT ExpandWildcardsResult ExpandWildcards( + const TProtoStringType& path, std::function<void(const TProtoStringType&)> consume); + +namespace strings { + +// Convert from UTF-16 to Active-Code-Page-encoded or to UTF-8-encoded text. +PROTOBUF_EXPORT bool wcs_to_mbs(const wchar_t* s, TProtoStringType* out, + bool outUtf8); + +// Convert from Active-Code-Page-encoded or UTF-8-encoded text to UTF-16. +PROTOBUF_EXPORT bool mbs_to_wcs(const char* s, std::wstring* out, bool inUtf8); + +// Convert from UTF-8-encoded text to UTF-16. +PROTOBUF_EXPORT bool utf8_to_wcs(const char* input, std::wstring* out); + +// Convert from UTF-16-encoded text to UTF-8. +PROTOBUF_EXPORT bool wcs_to_utf8(const wchar_t* input, TProtoStringType* out); + +} // namespace strings + +} // namespace win32 +} // namespace io +} // namespace protobuf +} // namespace google + +#ifndef W_OK +#define W_OK 02 // not defined by MSVC for whatever reason +#endif + +#ifndef F_OK +#define F_OK 00 // not defined by MSVC for whatever reason +#endif + +#ifndef STDIN_FILENO +#define STDIN_FILENO 0 +#endif + +#ifndef STDOUT_FILENO +#define STDOUT_FILENO 1 +#endif + +#include <google/protobuf/port_undef.inc> + +#endif // defined(_WIN32) + +#endif // GOOGLE_PROTOBUF_IO_IO_WIN32_H__ diff --git a/contrib/libs/protobuf_old/src/google/protobuf/io/printer.cc b/contrib/libs/protobuf_old/src/google/protobuf/io/printer.cc new file mode 100644 index 0000000000..83ed7d1f69 --- /dev/null +++ b/contrib/libs/protobuf_old/src/google/protobuf/io/printer.cc @@ -0,0 +1,400 @@ +// 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: kenton@google.com (Kenton Varda) +// Based on original Protocol Buffers design by +// Sanjay Ghemawat, Jeff Dean, and others. + +#include <google/protobuf/io/printer.h> + +#include <cctype> + +#include <google/protobuf/stubs/logging.h> +#include <google/protobuf/stubs/common.h> +#include <google/protobuf/io/zero_copy_stream.h> + +namespace google { +namespace protobuf { +namespace io { + +Printer::Printer(ZeroCopyOutputStream* output, char variable_delimiter) + : variable_delimiter_(variable_delimiter), + output_(output), + buffer_(NULL), + buffer_size_(0), + offset_(0), + at_start_of_line_(true), + failed_(false), + annotation_collector_(NULL) {} + +Printer::Printer(ZeroCopyOutputStream* output, char variable_delimiter, + AnnotationCollector* annotation_collector) + : variable_delimiter_(variable_delimiter), + output_(output), + buffer_(NULL), + buffer_size_(0), + offset_(0), + at_start_of_line_(true), + failed_(false), + annotation_collector_(annotation_collector) {} + +Printer::~Printer() { + // Only BackUp() if we have called Next() at least once and never failed. + if (buffer_size_ > 0 && !failed_) { + output_->BackUp(buffer_size_); + } +} + +bool Printer::GetSubstitutionRange(const char* varname, + std::pair<size_t, size_t>* range) { + std::map<TProtoStringType, std::pair<size_t, size_t> >::const_iterator iter = + substitutions_.find(varname); + if (iter == substitutions_.end()) { + GOOGLE_LOG(DFATAL) << " Undefined variable in annotation: " << varname; + return false; + } + if (iter->second.first > iter->second.second) { + GOOGLE_LOG(DFATAL) << " Variable used for annotation used multiple times: " + << varname; + return false; + } + *range = iter->second; + return true; +} + +void Printer::Annotate(const char* begin_varname, const char* end_varname, + const TProtoStringType& file_path, + const std::vector<int>& path) { + if (annotation_collector_ == NULL) { + // Can't generate signatures with this Printer. + return; + } + std::pair<size_t, size_t> begin, end; + if (!GetSubstitutionRange(begin_varname, &begin) || + !GetSubstitutionRange(end_varname, &end)) { + return; + } + if (begin.first > end.second) { + GOOGLE_LOG(DFATAL) << " Annotation has negative length from " << begin_varname + << " to " << end_varname; + } else { + annotation_collector_->AddAnnotation(begin.first, end.second, file_path, + path); + } +} + +void Printer::Print(const std::map<TProtoStringType, TProtoStringType>& variables, + const char* text) { + int size = strlen(text); + int pos = 0; // The number of bytes we've written so far. + substitutions_.clear(); + line_start_variables_.clear(); + + for (int i = 0; i < size; i++) { + if (text[i] == '\n') { + // Saw newline. If there is more text, we may need to insert an indent + // here. So, write what we have so far, including the '\n'. + WriteRaw(text + pos, i - pos + 1); + pos = i + 1; + + // Setting this true will cause the next WriteRaw() to insert an indent + // first. + at_start_of_line_ = true; + line_start_variables_.clear(); + + } else if (text[i] == variable_delimiter_) { + // Saw the start of a variable name. + + // Write what we have so far. + WriteRaw(text + pos, i - pos); + pos = i + 1; + + // Find closing delimiter. + const char* end = strchr(text + pos, variable_delimiter_); + if (end == NULL) { + GOOGLE_LOG(DFATAL) << " Unclosed variable name."; + end = text + pos; + } + int endpos = end - text; + + TProtoStringType varname(text + pos, endpos - pos); + if (varname.empty()) { + // Two delimiters in a row reduce to a literal delimiter character. + WriteRaw(&variable_delimiter_, 1); + } else { + // Replace with the variable's value. + std::map<TProtoStringType, TProtoStringType>::const_iterator iter = + variables.find(varname); + if (iter == variables.end()) { + GOOGLE_LOG(DFATAL) << " Undefined variable: " << varname; + } else { + if (at_start_of_line_ && iter->second.empty()) { + line_start_variables_.push_back(varname); + } + WriteRaw(iter->second.data(), iter->second.size()); + std::pair<std::map<TProtoStringType, std::pair<size_t, size_t> >::iterator, + bool> + inserted = substitutions_.insert(std::make_pair( + varname, + std::make_pair(offset_ - iter->second.size(), offset_))); + if (!inserted.second) { + // This variable was used multiple times. Make its span have + // negative length so we can detect it if it gets used in an + // annotation. + inserted.first->second = std::make_pair(1, 0); + } + } + } + + // Advance past this variable. + i = endpos; + pos = endpos + 1; + } + } + + // Write the rest. + WriteRaw(text + pos, size - pos); +} + +void Printer::Indent() { indent_ += " "; } + +void Printer::Outdent() { + if (indent_.empty()) { + GOOGLE_LOG(DFATAL) << " Outdent() without matching Indent()."; + return; + } + + indent_.resize(indent_.size() - 2); +} + +void Printer::PrintRaw(const TProtoStringType& data) { + WriteRaw(data.data(), data.size()); +} + +void Printer::PrintRaw(const char* data) { + if (failed_) return; + WriteRaw(data, strlen(data)); +} + +void Printer::WriteRaw(const char* data, int size) { + if (failed_) return; + if (size == 0) return; + + if (at_start_of_line_ && (size > 0) && (data[0] != '\n')) { + // Insert an indent. + at_start_of_line_ = false; + CopyToBuffer(indent_.data(), indent_.size()); + if (failed_) return; + // Fix up empty variables (e.g., "{") that should be annotated as + // coming after the indent. + for (std::vector<TProtoStringType>::iterator i = line_start_variables_.begin(); + i != line_start_variables_.end(); ++i) { + substitutions_[*i].first += indent_.size(); + substitutions_[*i].second += indent_.size(); + } + } + + // If we're going to write any data, clear line_start_variables_, since + // we've either updated them in the block above or they no longer refer to + // the current line. + line_start_variables_.clear(); + + CopyToBuffer(data, size); +} + +bool Printer::Next() { + do { + void* void_buffer; + if (!output_->Next(&void_buffer, &buffer_size_)) { + failed_ = true; + return false; + } + buffer_ = reinterpret_cast<char*>(void_buffer); + } while (buffer_size_ == 0); + return true; +} + +void Printer::CopyToBuffer(const char* data, int size) { + if (failed_) return; + if (size == 0) return; + + while (size > buffer_size_) { + // Data exceeds space in the buffer. Copy what we can and request a + // new buffer. + if (buffer_size_ > 0) { + memcpy(buffer_, data, buffer_size_); + offset_ += buffer_size_; + data += buffer_size_; + size -= buffer_size_; + } + void* void_buffer; + failed_ = !output_->Next(&void_buffer, &buffer_size_); + if (failed_) return; + buffer_ = reinterpret_cast<char*>(void_buffer); + } + + // Buffer is big enough to receive the data; copy it. + memcpy(buffer_, data, size); + buffer_ += size; + buffer_size_ -= size; + offset_ += size; +} + +void Printer::IndentIfAtStart() { + if (at_start_of_line_) { + CopyToBuffer(indent_.data(), indent_.size()); + at_start_of_line_ = false; + } +} + +void Printer::FormatInternal(const std::vector<TProtoStringType>& args, + const std::map<TProtoStringType, TProtoStringType>& vars, + const char* format) { + auto save = format; + int arg_index = 0; + std::vector<AnnotationCollector::Annotation> annotations; + while (*format) { + char c = *format++; + switch (c) { + case '$': + format = WriteVariable(args, vars, format, &arg_index, &annotations); + continue; + case '\n': + at_start_of_line_ = true; + line_start_variables_.clear(); + break; + default: + IndentIfAtStart(); + break; + } + push_back(c); + } + if (arg_index != static_cast<int>(args.size())) { + GOOGLE_LOG(FATAL) << " Unused arguments. " << save; + } + if (!annotations.empty()) { + GOOGLE_LOG(FATAL) << " Annotation range is not-closed, expect $}$. " << save; + } +} + +const char* Printer::WriteVariable( + const std::vector<TProtoStringType>& args, + const std::map<TProtoStringType, TProtoStringType>& vars, const char* format, + int* arg_index, std::vector<AnnotationCollector::Annotation>* annotations) { + auto start = format; + auto end = strchr(format, '$'); + if (!end) { + GOOGLE_LOG(FATAL) << " Unclosed variable name."; + } + format = end + 1; + if (end == start) { + // "$$" is an escape for just '$' + IndentIfAtStart(); + push_back('$'); + return format; + } + if (*start == '{') { + GOOGLE_CHECK(std::isdigit(start[1])); + GOOGLE_CHECK_EQ(end - start, 2); + int idx = start[1] - '1'; + if (idx < 0 || static_cast<size_t>(idx) >= args.size()) { + GOOGLE_LOG(FATAL) << "Annotation ${" << idx + 1 << "$ is out of bounds."; + } + if (idx > *arg_index) { + GOOGLE_LOG(FATAL) << "Annotation arg must be in correct order as given. Expected" + << " ${" << (*arg_index) + 1 << "$ got ${" << idx + 1 << "$."; + } else if (idx == *arg_index) { + (*arg_index)++; + } + IndentIfAtStart(); + annotations->push_back({{offset_, 0}, args[idx]}); + return format; + } else if (*start == '}') { + GOOGLE_CHECK(annotations); + if (annotations->empty()) { + GOOGLE_LOG(FATAL) << "Unexpected end of annotation found."; + } + auto& a = annotations->back(); + a.first.second = offset_; + if (annotation_collector_) annotation_collector_->AddAnnotationNew(a); + annotations->pop_back(); + return format; + } + auto start_var = start; + while (start_var < end && *start_var == ' ') start_var++; + if (start_var == end) { + GOOGLE_LOG(FATAL) << " Empty variable."; + } + auto end_var = end; + while (start_var < end_var && *(end_var - 1) == ' ') end_var--; + TProtoStringType var_name{ + start_var, static_cast<TProtoStringType::size_type>(end_var - start_var)}; + TProtoStringType sub; + if (std::isdigit(var_name[0])) { + GOOGLE_CHECK_EQ(var_name.size(), 1U); // No need for multi-digits + int idx = var_name[0] - '1'; // Start counting at 1 + GOOGLE_CHECK_GE(idx, 0); + if (static_cast<size_t>(idx) >= args.size()) { + GOOGLE_LOG(FATAL) << "Argument $" << idx + 1 << "$ is out of bounds."; + } + if (idx > *arg_index) { + GOOGLE_LOG(FATAL) << "Arguments must be used in same order as given. Expected $" + << (*arg_index) + 1 << "$ got $" << idx + 1 << "$."; + } else if (idx == *arg_index) { + (*arg_index)++; + } + sub = args[idx]; + } else { + auto it = vars.find(var_name); + if (it == vars.end()) { + GOOGLE_LOG(FATAL) << " Unknown variable: " << var_name << "."; + } + sub = it->second; + } + + // By returning here in case of empty we also skip possible spaces inside + // the $...$, i.e. "void$ dllexpor$ f();" -> "void f();" in the empty case. + if (sub.empty()) return format; + + // We're going to write something non-empty so we need a possible indent. + IndentIfAtStart(); + + // Write the possible spaces in front. + CopyToBuffer(start, start_var - start); + // Write a non-empty substituted variable. + CopyToBuffer(sub.c_str(), sub.size()); + // Finish off with writing possible trailing spaces. + CopyToBuffer(end_var, end - end_var); + return format; +} + +} // namespace io +} // namespace protobuf +} // namespace google diff --git a/contrib/libs/protobuf_old/src/google/protobuf/io/printer.h b/contrib/libs/protobuf_old/src/google/protobuf/io/printer.h new file mode 100644 index 0000000000..5407e0e454 --- /dev/null +++ b/contrib/libs/protobuf_old/src/google/protobuf/io/printer.h @@ -0,0 +1,385 @@ +// 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: kenton@google.com (Kenton Varda) +// Based on original Protocol Buffers design by +// Sanjay Ghemawat, Jeff Dean, and others. +// +// Utility class for writing text to a ZeroCopyOutputStream. + +#ifndef GOOGLE_PROTOBUF_IO_PRINTER_H__ +#define GOOGLE_PROTOBUF_IO_PRINTER_H__ + + +#include <map> +#include <string> +#include <vector> + +#include <google/protobuf/stubs/common.h> +#include <google/protobuf/port_def.inc> + +namespace google { +namespace protobuf { +namespace io { + +class ZeroCopyOutputStream; // zero_copy_stream.h + +// Records annotations about a Printer's output. +class PROTOBUF_EXPORT AnnotationCollector { + public: + // Annotation is a offset range and a payload pair. + typedef std::pair<std::pair<size_t, size_t>, TProtoStringType> Annotation; + + // Records that the bytes in file_path beginning with begin_offset and ending + // before end_offset are associated with the SourceCodeInfo-style path. + virtual void AddAnnotation(size_t begin_offset, size_t end_offset, + const TProtoStringType& file_path, + const std::vector<int>& path) = 0; + + // TODO(gerbens) I don't see why we need virtuals here. Just a vector of + // range, payload pairs stored in a context should suffice. + virtual void AddAnnotationNew(Annotation& /* a */) {} + + virtual ~AnnotationCollector() {} +}; + +// Records annotations about a Printer's output to the given protocol buffer, +// assuming that the buffer has an ::Annotation message exposing path, +// source_file, begin and end fields. +template <typename AnnotationProto> +class AnnotationProtoCollector : public AnnotationCollector { + public: + // annotation_proto is the protocol buffer to which new Annotations should be + // added. It is not owned by the AnnotationProtoCollector. + explicit AnnotationProtoCollector(AnnotationProto* annotation_proto) + : annotation_proto_(annotation_proto) {} + + // Override for AnnotationCollector::AddAnnotation. + void AddAnnotation(size_t begin_offset, size_t end_offset, + const TProtoStringType& file_path, + const std::vector<int>& path) override { + typename AnnotationProto::Annotation* annotation = + annotation_proto_->add_annotation(); + for (int i = 0; i < path.size(); ++i) { + annotation->add_path(path[i]); + } + annotation->set_source_file(file_path); + annotation->set_begin(begin_offset); + annotation->set_end(end_offset); + } + // Override for AnnotationCollector::AddAnnotation. + void AddAnnotationNew(Annotation& a) override { + auto* annotation = annotation_proto_->add_annotation(); + annotation->ParseFromString(a.second); + annotation->set_begin(a.first.first); + annotation->set_end(a.first.second); + } + + private: + // The protocol buffer to which new annotations should be added. + AnnotationProto* const annotation_proto_; +}; + +// This simple utility class assists in code generation. It basically +// allows the caller to define a set of variables and then output some +// text with variable substitutions. Example usage: +// +// Printer printer(output, '$'); +// map<string, string> vars; +// vars["name"] = "Bob"; +// printer.Print(vars, "My name is $name$."); +// +// The above writes "My name is Bob." to the output stream. +// +// Printer aggressively enforces correct usage, crashing (with assert failures) +// in the case of undefined variables in debug builds. This helps greatly in +// debugging code which uses it. +// +// If a Printer is constructed with an AnnotationCollector, it will provide it +// with annotations that connect the Printer's output to paths that can identify +// various descriptors. In the above example, if person_ is a descriptor that +// identifies Bob, we can associate the output string "My name is Bob." with +// a source path pointing to that descriptor with: +// +// printer.Annotate("name", person_); +// +// The AnnotationCollector will be sent an annotation linking the output range +// covering "Bob" to the logical path provided by person_. Tools may use +// this association to (for example) link "Bob" in the output back to the +// source file that defined the person_ descriptor identifying Bob. +// +// Annotate can only examine variables substituted during the last call to +// Print. It is invalid to refer to a variable that was used multiple times +// in a single Print call. +// +// In full generality, one may specify a range of output text using a beginning +// substitution variable and an ending variable. The resulting annotation will +// span from the first character of the substituted value for the beginning +// variable to the last character of the substituted value for the ending +// variable. For example, the Annotate call above is equivalent to this one: +// +// printer.Annotate("name", "name", person_); +// +// This is useful if multiple variables combine to form a single span of output +// that should be annotated with the same source path. For example: +// +// Printer printer(output, '$'); +// map<string, string> vars; +// vars["first"] = "Alice"; +// vars["last"] = "Smith"; +// printer.Print(vars, "My name is $first$ $last$."); +// printer.Annotate("first", "last", person_); +// +// This code would associate the span covering "Alice Smith" in the output with +// the person_ descriptor. +// +// Note that the beginning variable must come before (or overlap with, in the +// case of zero-sized substitution values) the ending variable. +// +// It is also sometimes useful to use variables with zero-sized values as +// markers. This avoids issues with multiple references to the same variable +// and also allows annotation ranges to span literal text from the Print +// templates: +// +// Printer printer(output, '$'); +// map<string, string> vars; +// vars["foo"] = "bar"; +// vars["function"] = "call"; +// vars["mark"] = ""; +// printer.Print(vars, "$function$($foo$,$foo$)$mark$"); +// printer.Annotate("function", "mark", call_); +// +// This code associates the span covering "call(bar,bar)" in the output with the +// call_ descriptor. + +class PROTOBUF_EXPORT Printer { + public: + // Create a printer that writes text to the given output stream. Use the + // given character as the delimiter for variables. + Printer(ZeroCopyOutputStream* output, char variable_delimiter); + + // Create a printer that writes text to the given output stream. Use the + // given character as the delimiter for variables. If annotation_collector + // is not null, Printer will provide it with annotations about code written + // to the stream. annotation_collector is not owned by Printer. + Printer(ZeroCopyOutputStream* output, char variable_delimiter, + AnnotationCollector* annotation_collector); + + ~Printer(); + + // Link a substitution variable emitted by the last call to Print to the + // object described by descriptor. + template <typename SomeDescriptor> + void Annotate(const char* varname, const SomeDescriptor* descriptor) { + Annotate(varname, varname, descriptor); + } + + // Link the output range defined by the substitution variables as emitted by + // the last call to Print to the object described by descriptor. The range + // begins at begin_varname's value and ends after the last character of the + // value substituted for end_varname. + template <typename SomeDescriptor> + void Annotate(const char* begin_varname, const char* end_varname, + const SomeDescriptor* descriptor) { + if (annotation_collector_ == NULL) { + // Annotations aren't turned on for this Printer, so don't pay the cost + // of building the location path. + return; + } + std::vector<int> path; + descriptor->GetLocationPath(&path); + Annotate(begin_varname, end_varname, descriptor->file()->name(), path); + } + + // Link a substitution variable emitted by the last call to Print to the file + // with path file_name. + void Annotate(const char* varname, const TProtoStringType& file_name) { + Annotate(varname, varname, file_name); + } + + // Link the output range defined by the substitution variables as emitted by + // the last call to Print to the file with path file_name. The range begins + // at begin_varname's value and ends after the last character of the value + // substituted for end_varname. + void Annotate(const char* begin_varname, const char* end_varname, + const TProtoStringType& file_name) { + if (annotation_collector_ == NULL) { + // Annotations aren't turned on for this Printer. + return; + } + std::vector<int> empty_path; + Annotate(begin_varname, end_varname, file_name, empty_path); + } + + // Print some text after applying variable substitutions. If a particular + // variable in the text is not defined, this will crash. Variables to be + // substituted are identified by their names surrounded by delimiter + // characters (as given to the constructor). The variable bindings are + // defined by the given map. + void Print(const std::map<TProtoStringType, TProtoStringType>& variables, + const char* text); + + // Like the first Print(), except the substitutions are given as parameters. + template <typename... Args> + void Print(const char* text, const Args&... args) { + std::map<TProtoStringType, TProtoStringType> vars; + PrintInternal(&vars, text, args...); + } + + // Indent text by two spaces. After calling Indent(), two spaces will be + // inserted at the beginning of each line of text. Indent() may be called + // multiple times to produce deeper indents. + void Indent(); + + // Reduces the current indent level by two spaces, or crashes if the indent + // level is zero. + void Outdent(); + + // Write a string to the output buffer. + // This method does not look for newlines to add indentation. + void PrintRaw(const TProtoStringType& data); + + // Write a zero-delimited string to output buffer. + // This method does not look for newlines to add indentation. + void PrintRaw(const char* data); + + // Write some bytes to the output buffer. + // This method does not look for newlines to add indentation. + void WriteRaw(const char* data, int size); + + // FormatInternal is a helper function not meant to use directly, use + // compiler::cpp::Formatter instead. This function is meant to support + // formatting text using named variables (eq. "$foo$) from a lookup map (vars) + // and variables directly supplied by arguments (eq "$1$" meaning first + // argument which is the zero index element of args). + void FormatInternal(const std::vector<TProtoStringType>& args, + const std::map<TProtoStringType, TProtoStringType>& vars, + const char* format); + + // True if any write to the underlying stream failed. (We don't just + // crash in this case because this is an I/O failure, not a programming + // error.) + bool failed() const { return failed_; } + + private: + // Link the output range defined by the substitution variables as emitted by + // the last call to Print to the object found at the SourceCodeInfo-style path + // in a file with path file_path. The range begins at the start of + // begin_varname's value and ends after the last character of the value + // substituted for end_varname. Note that begin_varname and end_varname + // may refer to the same variable. + void Annotate(const char* begin_varname, const char* end_varname, + const TProtoStringType& file_path, const std::vector<int>& path); + + // Base case + void PrintInternal(std::map<TProtoStringType, TProtoStringType>* vars, + const char* text) { + Print(*vars, text); + } + + template <typename... Args> + void PrintInternal(std::map<TProtoStringType, TProtoStringType>* vars, const char* text, + const char* key, const TProtoStringType& value, + const Args&... args) { + (*vars)[key] = value; + PrintInternal(vars, text, args...); + } + + // Copy size worth of bytes from data to buffer_. + void CopyToBuffer(const char* data, int size); + + void push_back(char c) { + if (failed_) return; + if (buffer_size_ == 0) { + if (!Next()) return; + } + *buffer_++ = c; + buffer_size_--; + offset_++; + } + + bool Next(); + + inline void IndentIfAtStart(); + const char* WriteVariable( + const std::vector<TProtoStringType>& args, + const std::map<TProtoStringType, TProtoStringType>& vars, const char* format, + int* arg_index, + std::vector<AnnotationCollector::Annotation>* annotations); + + const char variable_delimiter_; + + ZeroCopyOutputStream* const output_; + char* buffer_; + int buffer_size_; + // The current position, in bytes, in the output stream. This is equivalent + // to the total number of bytes that have been written so far. This value is + // used to calculate annotation ranges in the substitutions_ map below. + size_t offset_; + + TProtoStringType indent_; + bool at_start_of_line_; + bool failed_; + + // A map from variable name to [start, end) offsets in the output buffer. + // These refer to the offsets used for a variable after the last call to + // Print. If a variable was used more than once, the entry used in + // this map is set to a negative-length span. For singly-used variables, the + // start offset is the beginning of the substitution; the end offset is the + // last byte of the substitution plus one (such that (end - start) is the + // length of the substituted string). + std::map<TProtoStringType, std::pair<size_t, size_t> > substitutions_; + + // Keeps track of the keys in substitutions_ that need to be updated when + // indents are inserted. These are keys that refer to the beginning of the + // current line. + std::vector<TProtoStringType> line_start_variables_; + + // Returns true and sets range to the substitution range in the output for + // varname if varname was used once in the last call to Print. If varname + // was not used, or if it was used multiple times, returns false (and + // fails a debug assertion). + bool GetSubstitutionRange(const char* varname, + std::pair<size_t, size_t>* range); + + // If non-null, annotation_collector_ is used to store annotations about + // generated code. + AnnotationCollector* const annotation_collector_; + + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(Printer); +}; + +} // namespace io +} // namespace protobuf +} // namespace google + +#include <google/protobuf/port_undef.inc> + +#endif // GOOGLE_PROTOBUF_IO_PRINTER_H__ diff --git a/contrib/libs/protobuf_old/src/google/protobuf/io/strtod.cc b/contrib/libs/protobuf_old/src/google/protobuf/io/strtod.cc new file mode 100644 index 0000000000..03acb5b294 --- /dev/null +++ b/contrib/libs/protobuf_old/src/google/protobuf/io/strtod.cc @@ -0,0 +1,82 @@ +// 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 <google/protobuf/io/strtod.h> + +#include <cstdio> +#include <cstring> +#include <limits> +#include <string> + +#include <google/protobuf/stubs/logging.h> +#include <google/protobuf/stubs/common.h> + +#include <google/protobuf/stubs/strutil.h> + +namespace google { +namespace protobuf { +namespace io { + +// This approximately 0x1.ffffffp127, but we don't use 0x1.ffffffp127 because +// it won't compile in MSVC. +const double MAX_FLOAT_AS_DOUBLE_ROUNDED = 3.4028235677973366e+38; + +float SafeDoubleToFloat(double value) { + // static_cast<float> on a number larger than float can result in illegal + // instruction error, so we need to manually convert it to infinity or max. + if (value > std::numeric_limits<float>::max()) { + // Max float value is about 3.4028234664E38 when represented as a double. + // However, when printing float as text, it will be rounded as + // 3.4028235e+38. If we parse the value of 3.4028235e+38 from text and + // compare it to 3.4028234664E38, we may think that it is larger, but + // actually, any number between these two numbers could only be represented + // as the same max float number in float, so we should treat them the same + // as max float. + if (value <= MAX_FLOAT_AS_DOUBLE_ROUNDED) { + return std::numeric_limits<float>::max(); + } + return std::numeric_limits<float>::infinity(); + } else if (value < -std::numeric_limits<float>::max()) { + if (value >= -MAX_FLOAT_AS_DOUBLE_ROUNDED) { + return -std::numeric_limits<float>::max(); + } + return -std::numeric_limits<float>::infinity(); + } else { + return static_cast<float>(value); + } +} + +double NoLocaleStrtod(const char* str, char** endptr) { + return google::protobuf::internal::NoLocaleStrtod(str, endptr); +} + +} // namespace io +} // namespace protobuf +} // namespace google diff --git a/contrib/libs/protobuf_old/src/google/protobuf/io/strtod.h b/contrib/libs/protobuf_old/src/google/protobuf/io/strtod.h new file mode 100644 index 0000000000..38f544af34 --- /dev/null +++ b/contrib/libs/protobuf_old/src/google/protobuf/io/strtod.h @@ -0,0 +1,55 @@ +// 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. + +// A locale-independent version of strtod(), used to parse floating +// point default values in .proto files, where the decimal separator +// is always a dot. + +#ifndef GOOGLE_PROTOBUF_IO_STRTOD_H__ +#define GOOGLE_PROTOBUF_IO_STRTOD_H__ + +namespace google { +namespace protobuf { +namespace io { + +// A locale-independent version of the standard strtod(), which always +// uses a dot as the decimal separator. +double NoLocaleStrtod(const char* str, char** endptr); + +// Casts a double value to a float value. If the value is outside of the +// representable range of float, it will be converted to positive or negative +// infinity. +float SafeDoubleToFloat(double value); + +} // namespace io +} // namespace protobuf +} // namespace google + +#endif // GOOGLE_PROTOBUF_IO_STRTOD_H__ diff --git a/contrib/libs/protobuf_old/src/google/protobuf/io/tokenizer.cc b/contrib/libs/protobuf_old/src/google/protobuf/io/tokenizer.cc new file mode 100644 index 0000000000..1fdb036cc2 --- /dev/null +++ b/contrib/libs/protobuf_old/src/google/protobuf/io/tokenizer.cc @@ -0,0 +1,1186 @@ +// 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: kenton@google.com (Kenton Varda) +// Based on original Protocol Buffers design by +// Sanjay Ghemawat, Jeff Dean, and others. +// +// Here we have a hand-written lexer. At first you might ask yourself, +// "Hand-written text processing? Is Kenton crazy?!" Well, first of all, +// yes I am crazy, but that's beside the point. There are actually reasons +// why I ended up writing this this way. +// +// The traditional approach to lexing is to use lex to generate a lexer for +// you. Unfortunately, lex's output is ridiculously ugly and difficult to +// integrate cleanly with C++ code, especially abstract code or code meant +// as a library. Better parser-generators exist but would add dependencies +// which most users won't already have, which we'd like to avoid. (GNU flex +// has a C++ output option, but it's still ridiculously ugly, non-abstract, +// and not library-friendly.) +// +// The next approach that any good software engineer should look at is to +// use regular expressions. And, indeed, I did. I have code which +// implements this same class using regular expressions. It's about 200 +// lines shorter. However: +// - Rather than error messages telling you "This string has an invalid +// escape sequence at line 5, column 45", you get error messages like +// "Parse error on line 5". Giving more precise errors requires adding +// a lot of code that ends up basically as complex as the hand-coded +// version anyway. +// - The regular expression to match a string literal looks like this: +// kString = new RE("(\"([^\"\\\\]|" // non-escaped +// "\\\\[abfnrtv?\"'\\\\0-7]|" // normal escape +// "\\\\x[0-9a-fA-F])*\"|" // hex escape +// "\'([^\'\\\\]|" // Also support single-quotes. +// "\\\\[abfnrtv?\"'\\\\0-7]|" +// "\\\\x[0-9a-fA-F])*\')"); +// Verifying the correctness of this line noise is actually harder than +// verifying the correctness of ConsumeString(), defined below. I'm not +// even confident that the above is correct, after staring at it for some +// time. +// - PCRE is fast, but there's still more overhead involved than the code +// below. +// - Sadly, regular expressions are not part of the C standard library, so +// using them would require depending on some other library. For the +// open source release, this could be really annoying. Nobody likes +// downloading one piece of software just to find that they need to +// download something else to make it work, and in all likelihood +// people downloading Protocol Buffers will already be doing so just +// to make something else work. We could include a copy of PCRE with +// our code, but that obligates us to keep it up-to-date and just seems +// like a big waste just to save 200 lines of code. +// +// On a similar but unrelated note, I'm even scared to use ctype.h. +// Apparently functions like isalpha() are locale-dependent. So, if we used +// that, then if this code is being called from some program that doesn't +// have its locale set to "C", it would behave strangely. We can't just set +// the locale to "C" ourselves since we might break the calling program that +// way, particularly if it is multi-threaded. WTF? Someone please let me +// (Kenton) know if I'm missing something here... +// +// I'd love to hear about other alternatives, though, as this code isn't +// exactly pretty. + +#include <google/protobuf/io/tokenizer.h> + +#include <google/protobuf/stubs/common.h> +#include <google/protobuf/stubs/logging.h> +#include <google/protobuf/stubs/stringprintf.h> +#include <google/protobuf/stubs/strutil.h> +#include <google/protobuf/io/strtod.h> +#include <google/protobuf/io/zero_copy_stream.h> +#include <google/protobuf/stubs/stl_util.h> + +namespace google { +namespace protobuf { +namespace io { +namespace { + +// As mentioned above, I don't trust ctype.h due to the presence of "locales". +// So, I have written replacement functions here. Someone please smack me if +// this is a bad idea or if there is some way around this. +// +// These "character classes" are designed to be used in template methods. +// For instance, Tokenizer::ConsumeZeroOrMore<Whitespace>() will eat +// whitespace. + +// Note: No class is allowed to contain '\0', since this is used to mark end- +// of-input and is handled specially. + +#define CHARACTER_CLASS(NAME, EXPRESSION) \ + class NAME { \ + public: \ + static inline bool InClass(char c) { return EXPRESSION; } \ + } + +CHARACTER_CLASS(Whitespace, c == ' ' || c == '\n' || c == '\t' || c == '\r' || + c == '\v' || c == '\f'); +CHARACTER_CLASS(WhitespaceNoNewline, + c == ' ' || c == '\t' || c == '\r' || c == '\v' || c == '\f'); + +CHARACTER_CLASS(Unprintable, c<' ' && c> '\0'); + +CHARACTER_CLASS(Digit, '0' <= c && c <= '9'); +CHARACTER_CLASS(OctalDigit, '0' <= c && c <= '7'); +CHARACTER_CLASS(HexDigit, ('0' <= c && c <= '9') || ('a' <= c && c <= 'f') || + ('A' <= c && c <= 'F')); + +CHARACTER_CLASS(Letter, + ('a' <= c && c <= 'z') || ('A' <= c && c <= 'Z') || (c == '_')); + +CHARACTER_CLASS(Alphanumeric, ('a' <= c && c <= 'z') || + ('A' <= c && c <= 'Z') || + ('0' <= c && c <= '9') || (c == '_')); + +CHARACTER_CLASS(Escape, c == 'a' || c == 'b' || c == 'f' || c == 'n' || + c == 'r' || c == 't' || c == 'v' || c == '\\' || + c == '?' || c == '\'' || c == '\"'); + +#undef CHARACTER_CLASS + +// Given a char, interpret it as a numeric digit and return its value. +// This supports any number base up to 36. +inline int DigitValue(char digit) { + if ('0' <= digit && digit <= '9') return digit - '0'; + if ('a' <= digit && digit <= 'z') return digit - 'a' + 10; + if ('A' <= digit && digit <= 'Z') return digit - 'A' + 10; + return -1; +} + +// Inline because it's only used in one place. +inline char TranslateEscape(char c) { + switch (c) { + case 'a': + return '\a'; + case 'b': + return '\b'; + case 'f': + return '\f'; + case 'n': + return '\n'; + case 'r': + return '\r'; + case 't': + return '\t'; + case 'v': + return '\v'; + case '\\': + return '\\'; + case '?': + return '\?'; // Trigraphs = :( + case '\'': + return '\''; + case '"': + return '\"'; + + // We expect escape sequences to have been validated separately. + default: + return '?'; + } +} + +} // anonymous namespace + +ErrorCollector::~ErrorCollector() {} + +// =================================================================== + +Tokenizer::Tokenizer(ZeroCopyInputStream* input, + ErrorCollector* error_collector) + : input_(input), + error_collector_(error_collector), + buffer_(NULL), + buffer_size_(0), + buffer_pos_(0), + read_error_(false), + line_(0), + column_(0), + record_target_(NULL), + record_start_(-1), + allow_f_after_float_(false), + comment_style_(CPP_COMMENT_STYLE), + require_space_after_number_(true), + allow_multiline_strings_(false) { + current_.line = 0; + current_.column = 0; + current_.end_column = 0; + current_.type = TYPE_START; + + Refresh(); +} + +Tokenizer::~Tokenizer() { + // If we had any buffer left unread, return it to the underlying stream + // so that someone else can read it. + if (buffer_size_ > buffer_pos_) { + input_->BackUp(buffer_size_ - buffer_pos_); + } +} + +bool Tokenizer::report_whitespace() const { return report_whitespace_; } +// Note: `set_report_whitespace(false)` implies `set_report_newlines(false)`. +void Tokenizer::set_report_whitespace(bool report) { + report_whitespace_ = report; + report_newlines_ &= report; +} + +// If true, newline tokens are reported by Next(). +bool Tokenizer::report_newlines() const { return report_newlines_; } +// Note: `set_report_newlines(true)` implies `set_report_whitespace(true)`. +void Tokenizer::set_report_newlines(bool report) { + report_newlines_ = report; + report_whitespace_ |= report; // enable report_whitespace if necessary +} + +// ------------------------------------------------------------------- +// Internal helpers. + +void Tokenizer::NextChar() { + // Update our line and column counters based on the character being + // consumed. + if (current_char_ == '\n') { + ++line_; + column_ = 0; + } else if (current_char_ == '\t') { + column_ += kTabWidth - column_ % kTabWidth; + } else { + ++column_; + } + + // Advance to the next character. + ++buffer_pos_; + if (buffer_pos_ < buffer_size_) { + current_char_ = buffer_[buffer_pos_]; + } else { + Refresh(); + } +} + +void Tokenizer::Refresh() { + if (read_error_) { + current_char_ = '\0'; + return; + } + + // If we're in a token, append the rest of the buffer to it. + if (record_target_ != NULL && record_start_ < buffer_size_) { + record_target_->append(buffer_ + record_start_, + buffer_size_ - record_start_); + record_start_ = 0; + } + + const void* data = NULL; + buffer_ = NULL; + buffer_pos_ = 0; + do { + if (!input_->Next(&data, &buffer_size_)) { + // end of stream (or read error) + buffer_size_ = 0; + read_error_ = true; + current_char_ = '\0'; + return; + } + } while (buffer_size_ == 0); + + buffer_ = static_cast<const char*>(data); + + current_char_ = buffer_[0]; +} + +inline void Tokenizer::RecordTo(TProtoStringType* target) { + record_target_ = target; + record_start_ = buffer_pos_; +} + +inline void Tokenizer::StopRecording() { + // Note: The if() is necessary because some STL implementations crash when + // you call string::append(NULL, 0), presumably because they are trying to + // be helpful by detecting the NULL pointer, even though there's nothing + // wrong with reading zero bytes from NULL. + if (buffer_pos_ != record_start_) { + record_target_->append(buffer_ + record_start_, + buffer_pos_ - record_start_); + } + record_target_ = NULL; + record_start_ = -1; +} + +inline void Tokenizer::StartToken() { + current_.type = TYPE_START; // Just for the sake of initializing it. + current_.text.clear(); + current_.line = line_; + current_.column = column_; + RecordTo(¤t_.text); +} + +inline void Tokenizer::EndToken() { + StopRecording(); + current_.end_column = column_; +} + +// ------------------------------------------------------------------- +// Helper methods that consume characters. + +template <typename CharacterClass> +inline bool Tokenizer::LookingAt() { + return CharacterClass::InClass(current_char_); +} + +template <typename CharacterClass> +inline bool Tokenizer::TryConsumeOne() { + if (CharacterClass::InClass(current_char_)) { + NextChar(); + return true; + } else { + return false; + } +} + +inline bool Tokenizer::TryConsume(char c) { + if (current_char_ == c) { + NextChar(); + return true; + } else { + return false; + } +} + +template <typename CharacterClass> +inline void Tokenizer::ConsumeZeroOrMore() { + while (CharacterClass::InClass(current_char_)) { + NextChar(); + } +} + +template <typename CharacterClass> +inline void Tokenizer::ConsumeOneOrMore(const char* error) { + if (!CharacterClass::InClass(current_char_)) { + AddError(error); + } else { + do { + NextChar(); + } while (CharacterClass::InClass(current_char_)); + } +} + +// ------------------------------------------------------------------- +// Methods that read whole patterns matching certain kinds of tokens +// or comments. + +void Tokenizer::ConsumeString(char delimiter) { + while (true) { + switch (current_char_) { + case '\0': + AddError("Unexpected end of string."); + return; + + case '\n': { + if (!allow_multiline_strings_) { + AddError("String literals cannot cross line boundaries."); + return; + } + NextChar(); + break; + } + + case '\\': { + // An escape sequence. + NextChar(); + if (TryConsumeOne<Escape>()) { + // Valid escape sequence. + } else if (TryConsumeOne<OctalDigit>()) { + // Possibly followed by two more octal digits, but these will + // just be consumed by the main loop anyway so we don't need + // to do so explicitly here. + } else if (TryConsume('x')) { + if (!TryConsumeOne<HexDigit>()) { + AddError("Expected hex digits for escape sequence."); + } + // Possibly followed by another hex digit, but again we don't care. + } else if (TryConsume('u')) { + if (!TryConsumeOne<HexDigit>() || !TryConsumeOne<HexDigit>() || + !TryConsumeOne<HexDigit>() || !TryConsumeOne<HexDigit>()) { + AddError("Expected four hex digits for \\u escape sequence."); + } + } else if (TryConsume('U')) { + // We expect 8 hex digits; but only the range up to 0x10ffff is + // legal. + if (!TryConsume('0') || !TryConsume('0') || + !(TryConsume('0') || TryConsume('1')) || + !TryConsumeOne<HexDigit>() || !TryConsumeOne<HexDigit>() || + !TryConsumeOne<HexDigit>() || !TryConsumeOne<HexDigit>() || + !TryConsumeOne<HexDigit>()) { + AddError( + "Expected eight hex digits up to 10ffff for \\U escape " + "sequence"); + } + } else { + AddError("Invalid escape sequence in string literal."); + } + break; + } + + default: { + if (current_char_ == delimiter) { + NextChar(); + return; + } + NextChar(); + break; + } + } + } +} + +Tokenizer::TokenType Tokenizer::ConsumeNumber(bool started_with_zero, + bool started_with_dot) { + bool is_float = false; + + if (started_with_zero && (TryConsume('x') || TryConsume('X'))) { + // A hex number (started with "0x"). + ConsumeOneOrMore<HexDigit>("\"0x\" must be followed by hex digits."); + + } else if (started_with_zero && LookingAt<Digit>()) { + // An octal number (had a leading zero). + ConsumeZeroOrMore<OctalDigit>(); + if (LookingAt<Digit>()) { + AddError("Numbers starting with leading zero must be in octal."); + ConsumeZeroOrMore<Digit>(); + } + + } else { + // A decimal number. + if (started_with_dot) { + is_float = true; + ConsumeZeroOrMore<Digit>(); + } else { + ConsumeZeroOrMore<Digit>(); + + if (TryConsume('.')) { + is_float = true; + ConsumeZeroOrMore<Digit>(); + } + } + + if (TryConsume('e') || TryConsume('E')) { + is_float = true; + TryConsume('-') || TryConsume('+'); + ConsumeOneOrMore<Digit>("\"e\" must be followed by exponent."); + } + + if (allow_f_after_float_ && (TryConsume('f') || TryConsume('F'))) { + is_float = true; + } + } + + if (LookingAt<Letter>() && require_space_after_number_) { + AddError("Need space between number and identifier."); + } else if (current_char_ == '.') { + if (is_float) { + AddError( + "Already saw decimal point or exponent; can't have another one."); + } else { + AddError("Hex and octal numbers must be integers."); + } + } + + return is_float ? TYPE_FLOAT : TYPE_INTEGER; +} + +void Tokenizer::ConsumeLineComment(TProtoStringType* content) { + if (content != NULL) RecordTo(content); + + while (current_char_ != '\0' && current_char_ != '\n') { + NextChar(); + } + TryConsume('\n'); + + if (content != NULL) StopRecording(); +} + +void Tokenizer::ConsumeBlockComment(TProtoStringType* content) { + int start_line = line_; + int start_column = column_ - 2; + + if (content != NULL) RecordTo(content); + + while (true) { + while (current_char_ != '\0' && current_char_ != '*' && + current_char_ != '/' && current_char_ != '\n') { + NextChar(); + } + + if (TryConsume('\n')) { + if (content != NULL) StopRecording(); + + // Consume leading whitespace and asterisk; + ConsumeZeroOrMore<WhitespaceNoNewline>(); + if (TryConsume('*')) { + if (TryConsume('/')) { + // End of comment. + break; + } + } + + if (content != NULL) RecordTo(content); + } else if (TryConsume('*') && TryConsume('/')) { + // End of comment. + if (content != NULL) { + StopRecording(); + // Strip trailing "*/". + content->erase(content->size() - 2); + } + break; + } else if (TryConsume('/') && current_char_ == '*') { + // Note: We didn't consume the '*' because if there is a '/' after it + // we want to interpret that as the end of the comment. + AddError( + "\"/*\" inside block comment. Block comments cannot be nested."); + } else if (current_char_ == '\0') { + AddError("End-of-file inside block comment."); + error_collector_->AddError(start_line, start_column, + " Comment started here."); + if (content != NULL) StopRecording(); + break; + } + } +} + +Tokenizer::NextCommentStatus Tokenizer::TryConsumeCommentStart() { + if (comment_style_ == CPP_COMMENT_STYLE && TryConsume('/')) { + if (TryConsume('/')) { + return LINE_COMMENT; + } else if (TryConsume('*')) { + return BLOCK_COMMENT; + } else { + // Oops, it was just a slash. Return it. + current_.type = TYPE_SYMBOL; + current_.text = "/"; + current_.line = line_; + current_.column = column_ - 1; + current_.end_column = column_; + return SLASH_NOT_COMMENT; + } + } else if (comment_style_ == SH_COMMENT_STYLE && TryConsume('#')) { + return LINE_COMMENT; + } else { + return NO_COMMENT; + } +} + +bool Tokenizer::TryConsumeWhitespace() { + if (report_newlines_) { + if (TryConsumeOne<WhitespaceNoNewline>()) { + ConsumeZeroOrMore<WhitespaceNoNewline>(); + current_.type = TYPE_WHITESPACE; + return true; + } + return false; + } + if (TryConsumeOne<Whitespace>()) { + ConsumeZeroOrMore<Whitespace>(); + current_.type = TYPE_WHITESPACE; + return report_whitespace_; + } + return false; +} + +bool Tokenizer::TryConsumeNewline() { + if (!report_whitespace_ || !report_newlines_) { + return false; + } + if (TryConsume('\n')) { + current_.type = TYPE_NEWLINE; + return true; + } + return false; +} + +// ------------------------------------------------------------------- + +bool Tokenizer::Next() { + previous_ = current_; + + while (!read_error_) { + StartToken(); + bool report_token = TryConsumeWhitespace() || TryConsumeNewline(); + EndToken(); + if (report_token) { + return true; + } + + switch (TryConsumeCommentStart()) { + case LINE_COMMENT: + ConsumeLineComment(NULL); + continue; + case BLOCK_COMMENT: + ConsumeBlockComment(NULL); + continue; + case SLASH_NOT_COMMENT: + return true; + case NO_COMMENT: + break; + } + + // Check for EOF before continuing. + if (read_error_) break; + + if (LookingAt<Unprintable>() || current_char_ == '\0') { + AddError("Invalid control characters encountered in text."); + NextChar(); + // Skip more unprintable characters, too. But, remember that '\0' is + // also what current_char_ is set to after EOF / read error. We have + // to be careful not to go into an infinite loop of trying to consume + // it, so make sure to check read_error_ explicitly before consuming + // '\0'. + while (TryConsumeOne<Unprintable>() || + (!read_error_ && TryConsume('\0'))) { + // Ignore. + } + + } else { + // Reading some sort of token. + StartToken(); + + if (TryConsumeOne<Letter>()) { + ConsumeZeroOrMore<Alphanumeric>(); + current_.type = TYPE_IDENTIFIER; + } else if (TryConsume('0')) { + current_.type = ConsumeNumber(true, false); + } else if (TryConsume('.')) { + // This could be the beginning of a floating-point number, or it could + // just be a '.' symbol. + + if (TryConsumeOne<Digit>()) { + // It's a floating-point number. + if (previous_.type == TYPE_IDENTIFIER && + current_.line == previous_.line && + current_.column == previous_.end_column) { + // We don't accept syntax like "blah.123". + error_collector_->AddError( + line_, column_ - 2, + "Need space between identifier and decimal point."); + } + current_.type = ConsumeNumber(false, true); + } else { + current_.type = TYPE_SYMBOL; + } + } else if (TryConsumeOne<Digit>()) { + current_.type = ConsumeNumber(false, false); + } else if (TryConsume('\"')) { + ConsumeString('\"'); + current_.type = TYPE_STRING; + } else if (TryConsume('\'')) { + ConsumeString('\''); + current_.type = TYPE_STRING; + } else { + // Check if the high order bit is set. + // The tokenizer is used to parse tomita grammars with non-ascii utf8 chars + // if (current_char_ & 0x80) { + // error_collector_->AddError( + // line_, column_, + // StringPrintf("Interpreting non ascii codepoint %d.", + // static_cast<unsigned char>(current_char_))); + // } + NextChar(); + current_.type = TYPE_SYMBOL; + } + + EndToken(); + return true; + } + } + + // EOF + current_.type = TYPE_END; + current_.text.clear(); + current_.line = line_; + current_.column = column_; + current_.end_column = column_; + return false; +} + +namespace { + +// Helper class for collecting comments and putting them in the right places. +// +// This basically just buffers the most recent comment until it can be decided +// exactly where that comment should be placed. When Flush() is called, the +// current comment goes into either prev_trailing_comments or detached_comments. +// When the CommentCollector is destroyed, the last buffered comment goes into +// next_leading_comments. +class CommentCollector { + public: + CommentCollector(TProtoStringType* prev_trailing_comments, + std::vector<TProtoStringType>* detached_comments, + TProtoStringType* next_leading_comments) + : prev_trailing_comments_(prev_trailing_comments), + detached_comments_(detached_comments), + next_leading_comments_(next_leading_comments), + has_comment_(false), + is_line_comment_(false), + can_attach_to_prev_(true) { + if (prev_trailing_comments != NULL) prev_trailing_comments->clear(); + if (detached_comments != NULL) detached_comments->clear(); + if (next_leading_comments != NULL) next_leading_comments->clear(); + } + + ~CommentCollector() { + // Whatever is in the buffer is a leading comment. + if (next_leading_comments_ != NULL && has_comment_) { + comment_buffer_.swap(*next_leading_comments_); + } + } + + // About to read a line comment. Get the comment buffer pointer in order to + // read into it. + TProtoStringType* GetBufferForLineComment() { + // We want to combine with previous line comments, but not block comments. + if (has_comment_ && !is_line_comment_) { + Flush(); + } + has_comment_ = true; + is_line_comment_ = true; + return &comment_buffer_; + } + + // About to read a block comment. Get the comment buffer pointer in order to + // read into it. + TProtoStringType* GetBufferForBlockComment() { + if (has_comment_) { + Flush(); + } + has_comment_ = true; + is_line_comment_ = false; + return &comment_buffer_; + } + + void ClearBuffer() { + comment_buffer_.clear(); + has_comment_ = false; + } + + // Called once we know that the comment buffer is complete and is *not* + // connected to the next token. + void Flush() { + if (has_comment_) { + if (can_attach_to_prev_) { + if (prev_trailing_comments_ != NULL) { + prev_trailing_comments_->append(comment_buffer_); + } + can_attach_to_prev_ = false; + } else { + if (detached_comments_ != NULL) { + detached_comments_->push_back(comment_buffer_); + } + } + ClearBuffer(); + } + } + + void DetachFromPrev() { can_attach_to_prev_ = false; } + + private: + TProtoStringType* prev_trailing_comments_; + std::vector<TProtoStringType>* detached_comments_; + TProtoStringType* next_leading_comments_; + + TProtoStringType comment_buffer_; + + // True if any comments were read into comment_buffer_. This can be true even + // if comment_buffer_ is empty, namely if the comment was "/**/". + bool has_comment_; + + // Is the comment in the comment buffer a line comment? + bool is_line_comment_; + + // Is it still possible that we could be reading a comment attached to the + // previous token? + bool can_attach_to_prev_; +}; + +} // namespace + +bool Tokenizer::NextWithComments(TProtoStringType* prev_trailing_comments, + std::vector<TProtoStringType>* detached_comments, + TProtoStringType* next_leading_comments) { + CommentCollector collector(prev_trailing_comments, detached_comments, + next_leading_comments); + + if (current_.type == TYPE_START) { + // Ignore unicode byte order mark(BOM) if it appears at the file + // beginning. Only UTF-8 BOM (0xEF 0xBB 0xBF) is accepted. + if (TryConsume(static_cast<char>(0xEF))) { + if (!TryConsume(static_cast<char>(0xBB)) || + !TryConsume(static_cast<char>(0xBF))) { + AddError( + "Proto file starts with 0xEF but not UTF-8 BOM. " + "Only UTF-8 is accepted for proto file."); + return false; + } + } + collector.DetachFromPrev(); + } else { + // A comment appearing on the same line must be attached to the previous + // declaration. + ConsumeZeroOrMore<WhitespaceNoNewline>(); + switch (TryConsumeCommentStart()) { + case LINE_COMMENT: + ConsumeLineComment(collector.GetBufferForLineComment()); + + // Don't allow comments on subsequent lines to be attached to a trailing + // comment. + collector.Flush(); + break; + case BLOCK_COMMENT: + ConsumeBlockComment(collector.GetBufferForBlockComment()); + + ConsumeZeroOrMore<WhitespaceNoNewline>(); + if (!TryConsume('\n')) { + // Oops, the next token is on the same line. If we recorded a comment + // we really have no idea which token it should be attached to. + collector.ClearBuffer(); + return Next(); + } + + // Don't allow comments on subsequent lines to be attached to a trailing + // comment. + collector.Flush(); + break; + case SLASH_NOT_COMMENT: + return true; + case NO_COMMENT: + if (!TryConsume('\n')) { + // The next token is on the same line. There are no comments. + return Next(); + } + break; + } + } + + // OK, we are now on the line *after* the previous token. + while (true) { + ConsumeZeroOrMore<WhitespaceNoNewline>(); + + switch (TryConsumeCommentStart()) { + case LINE_COMMENT: + ConsumeLineComment(collector.GetBufferForLineComment()); + break; + case BLOCK_COMMENT: + ConsumeBlockComment(collector.GetBufferForBlockComment()); + + // Consume the rest of the line so that we don't interpret it as a + // blank line the next time around the loop. + ConsumeZeroOrMore<WhitespaceNoNewline>(); + TryConsume('\n'); + break; + case SLASH_NOT_COMMENT: + return true; + case NO_COMMENT: + if (TryConsume('\n')) { + // Completely blank line. + collector.Flush(); + collector.DetachFromPrev(); + } else { + bool result = Next(); + if (!result || current_.text == "}" || current_.text == "]" || + current_.text == ")") { + // It looks like we're at the end of a scope. In this case it + // makes no sense to attach a comment to the following token. + collector.Flush(); + } + return result; + } + break; + } + } +} + +// ------------------------------------------------------------------- +// Token-parsing helpers. Remember that these don't need to report +// errors since any errors should already have been reported while +// tokenizing. Also, these can assume that whatever text they +// are given is text that the tokenizer actually parsed as a token +// of the given type. + +bool Tokenizer::ParseInteger(const TProtoStringType& text, arc_ui64 max_value, + arc_ui64* output) { + // Sadly, we can't just use strtoul() since it is only 32-bit and strtoull() + // is non-standard. I hate the C standard library. :( + + // return strtoull(text.c_str(), NULL, 0); + + const char* ptr = text.c_str(); + int base = 10; + if (ptr[0] == '0') { + if (ptr[1] == 'x' || ptr[1] == 'X') { + // This is hex. + base = 16; + ptr += 2; + } else { + // This is octal. + base = 8; + } + } + + arc_ui64 result = 0; + for (; *ptr != '\0'; ptr++) { + int digit = DigitValue(*ptr); + if (digit < 0 || digit >= base) { + // The token provided by Tokenizer is invalid. i.e., 099 is an invalid + // token, but Tokenizer still think it's integer. + return false; + } + if (static_cast<arc_ui64>(digit) > max_value || + result > (max_value - digit) / base) { + // Overflow. + return false; + } + result = result * base + digit; + } + + *output = result; + return true; +} + +double Tokenizer::ParseFloat(const TProtoStringType& text) { + const char* start = text.c_str(); + char* end; + double result = NoLocaleStrtod(start, &end); + + // "1e" is not a valid float, but if the tokenizer reads it, it will + // report an error but still return it as a valid token. We need to + // accept anything the tokenizer could possibly return, error or not. + if (*end == 'e' || *end == 'E') { + ++end; + if (*end == '-' || *end == '+') ++end; + } + + // If the Tokenizer had allow_f_after_float_ enabled, the float may be + // suffixed with the letter 'f'. + if (*end == 'f' || *end == 'F') { + ++end; + } + + GOOGLE_LOG_IF(DFATAL, + static_cast<size_t>(end - start) != text.size() || *start == '-') + << " Tokenizer::ParseFloat() passed text that could not have been" + " tokenized as a float: " + << CEscape(text); + return result; +} + +// Helper to append a Unicode code point to a string as UTF8, without bringing +// in any external dependencies. +static void AppendUTF8(arc_ui32 code_point, TProtoStringType* output) { + arc_ui32 tmp = 0; + int len = 0; + if (code_point <= 0x7f) { + tmp = code_point; + len = 1; + } else if (code_point <= 0x07ff) { + tmp = 0x0000c080 | ((code_point & 0x07c0) << 2) | (code_point & 0x003f); + len = 2; + } else if (code_point <= 0xffff) { + tmp = 0x00e08080 | ((code_point & 0xf000) << 4) | + ((code_point & 0x0fc0) << 2) | (code_point & 0x003f); + len = 3; + } else if (code_point <= 0x10ffff) { + tmp = 0xf0808080 | ((code_point & 0x1c0000) << 6) | + ((code_point & 0x03f000) << 4) | ((code_point & 0x000fc0) << 2) | + (code_point & 0x003f); + len = 4; + } else { + // Unicode code points end at 0x10FFFF, so this is out-of-range. + // ConsumeString permits hex values up to 0x1FFFFF, and FetchUnicodePoint + // doesn't perform a range check. + StringAppendF(output, "\\U%08x", code_point); + return; + } + tmp = ghtonl(tmp); + output->append(reinterpret_cast<const char*>(&tmp) + sizeof(tmp) - len, len); +} + +// Try to read <len> hex digits from ptr, and stuff the numeric result into +// *result. Returns true if that many digits were successfully consumed. +static bool ReadHexDigits(const char* ptr, int len, arc_ui32* result) { + *result = 0; + if (len == 0) return false; + for (const char* end = ptr + len; ptr < end; ++ptr) { + if (*ptr == '\0') return false; + *result = (*result << 4) + DigitValue(*ptr); + } + return true; +} + +// Handling UTF-16 surrogate pairs. UTF-16 encodes code points in the range +// 0x10000...0x10ffff as a pair of numbers, a head surrogate followed by a trail +// surrogate. These numbers are in a reserved range of Unicode code points, so +// if we encounter such a pair we know how to parse it and convert it into a +// single code point. +static const arc_ui32 kMinHeadSurrogate = 0xd800; +static const arc_ui32 kMaxHeadSurrogate = 0xdc00; +static const arc_ui32 kMinTrailSurrogate = 0xdc00; +static const arc_ui32 kMaxTrailSurrogate = 0xe000; + +static inline bool IsHeadSurrogate(arc_ui32 code_point) { + return (code_point >= kMinHeadSurrogate) && (code_point < kMaxHeadSurrogate); +} + +static inline bool IsTrailSurrogate(arc_ui32 code_point) { + return (code_point >= kMinTrailSurrogate) && + (code_point < kMaxTrailSurrogate); +} + +// Combine a head and trail surrogate into a single Unicode code point. +static arc_ui32 AssembleUTF16(arc_ui32 head_surrogate, + arc_ui32 trail_surrogate) { + GOOGLE_DCHECK(IsHeadSurrogate(head_surrogate)); + GOOGLE_DCHECK(IsTrailSurrogate(trail_surrogate)); + return 0x10000 + (((head_surrogate - kMinHeadSurrogate) << 10) | + (trail_surrogate - kMinTrailSurrogate)); +} + +// Convert the escape sequence parameter to a number of expected hex digits. +static inline int UnicodeLength(char key) { + if (key == 'u') return 4; + if (key == 'U') return 8; + return 0; +} + +// Given a pointer to the 'u' or 'U' starting a Unicode escape sequence, attempt +// to parse that sequence. On success, returns a pointer to the first char +// beyond that sequence, and fills in *code_point. On failure, returns ptr +// itself. +static const char* FetchUnicodePoint(const char* ptr, arc_ui32* code_point) { + const char* p = ptr; + // Fetch the code point. + const int len = UnicodeLength(*p++); + if (!ReadHexDigits(p, len, code_point)) return ptr; + p += len; + + // Check if the code point we read is a "head surrogate." If so, then we + // expect it to be immediately followed by another code point which is a valid + // "trail surrogate," and together they form a UTF-16 pair which decodes into + // a single Unicode point. Trail surrogates may only use \u, not \U. + if (IsHeadSurrogate(*code_point) && *p == '\\' && *(p + 1) == 'u') { + arc_ui32 trail_surrogate; + if (ReadHexDigits(p + 2, 4, &trail_surrogate) && + IsTrailSurrogate(trail_surrogate)) { + *code_point = AssembleUTF16(*code_point, trail_surrogate); + p += 6; + } + // If this failed, then we just emit the head surrogate as a code point. + // It's bogus, but so is the string. + } + + return p; +} + +// The text string must begin and end with single or double quote +// characters. +void Tokenizer::ParseStringAppend(const TProtoStringType& text, + TProtoStringType* output) { + // Reminder: text[0] is always a quote character. (If text is + // empty, it's invalid, so we'll just return). + const size_t text_size = text.size(); + if (text_size == 0) { + GOOGLE_LOG(DFATAL) << " Tokenizer::ParseStringAppend() passed text that could not" + " have been tokenized as a string: " + << CEscape(text); + return; + } + + // Reserve room for new string. The branch is necessary because if + // there is already space available the reserve() call might + // downsize the output. + const size_t new_len = text_size + output->size(); + if (new_len > output->capacity()) { + output->reserve(new_len); + } + + // Loop through the string copying characters to "output" and + // interpreting escape sequences. Note that any invalid escape + // sequences or other errors were already reported while tokenizing. + // In this case we do not need to produce valid results. + for (const char* ptr = text.c_str() + 1; *ptr != '\0'; ptr++) { + if (*ptr == '\\' && ptr[1] != '\0') { + // An escape sequence. + ++ptr; + + if (OctalDigit::InClass(*ptr)) { + // An octal escape. May one, two, or three digits. + int code = DigitValue(*ptr); + if (OctalDigit::InClass(ptr[1])) { + ++ptr; + code = code * 8 + DigitValue(*ptr); + } + if (OctalDigit::InClass(ptr[1])) { + ++ptr; + code = code * 8 + DigitValue(*ptr); + } + output->push_back(static_cast<char>(code)); + + } else if (*ptr == 'x') { + // A hex escape. May zero, one, or two digits. (The zero case + // will have been caught as an error earlier.) + int code = 0; + if (HexDigit::InClass(ptr[1])) { + ++ptr; + code = DigitValue(*ptr); + } + if (HexDigit::InClass(ptr[1])) { + ++ptr; + code = code * 16 + DigitValue(*ptr); + } + output->push_back(static_cast<char>(code)); + + } else if (*ptr == 'u' || *ptr == 'U') { + arc_ui32 unicode; + const char* end = FetchUnicodePoint(ptr, &unicode); + if (end == ptr) { + // Failure: Just dump out what we saw, don't try to parse it. + output->push_back(*ptr); + } else { + AppendUTF8(unicode, output); + ptr = end - 1; // Because we're about to ++ptr. + } + } else { + // Some other escape code. + output->push_back(TranslateEscape(*ptr)); + } + + } else if (*ptr == text[0] && ptr[1] == '\0') { + // Ignore final quote matching the starting quote. + } else { + output->push_back(*ptr); + } + } +} + +template <typename CharacterClass> +static bool AllInClass(const TProtoStringType& s) { + for (const char character : s) { + if (!CharacterClass::InClass(character)) return false; + } + return true; +} + +bool Tokenizer::IsIdentifier(const TProtoStringType& text) { + // Mirrors IDENTIFIER definition in Tokenizer::Next() above. + if (text.size() == 0) return false; + if (!Letter::InClass(text.at(0))) return false; + if (!AllInClass<Alphanumeric>(text.substr(1))) return false; + return true; +} + +} // namespace io +} // namespace protobuf +} // namespace google diff --git a/contrib/libs/protobuf_old/src/google/protobuf/io/tokenizer.h b/contrib/libs/protobuf_old/src/google/protobuf/io/tokenizer.h new file mode 100644 index 0000000000..de1abdf622 --- /dev/null +++ b/contrib/libs/protobuf_old/src/google/protobuf/io/tokenizer.h @@ -0,0 +1,440 @@ +// 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: kenton@google.com (Kenton Varda) +// Based on original Protocol Buffers design by +// Sanjay Ghemawat, Jeff Dean, and others. +// +// Class for parsing tokenized text from a ZeroCopyInputStream. + +#ifndef GOOGLE_PROTOBUF_IO_TOKENIZER_H__ +#define GOOGLE_PROTOBUF_IO_TOKENIZER_H__ + + +#include <string> +#include <vector> + +#include <google/protobuf/stubs/common.h> +#include <google/protobuf/stubs/logging.h> +#include <google/protobuf/port_def.inc> + +namespace google { +namespace protobuf { +namespace io { + +class ZeroCopyInputStream; // zero_copy_stream.h + +// Defined in this file. +class ErrorCollector; +class Tokenizer; + +// By "column number", the proto compiler refers to a count of the number +// of bytes before a given byte, except that a tab character advances to +// the next multiple of 8 bytes. Note in particular that column numbers +// are zero-based, while many user interfaces use one-based column numbers. +typedef int ColumnNumber; + +// Abstract interface for an object which collects the errors that occur +// during parsing. A typical implementation might simply print the errors +// to stdout. +class PROTOBUF_EXPORT ErrorCollector { + public: + inline ErrorCollector() {} + virtual ~ErrorCollector(); + + // Indicates that there was an error in the input at the given line and + // column numbers. The numbers are zero-based, so you may want to add + // 1 to each before printing them. + virtual void AddError(int line, ColumnNumber column, + const TProtoStringType& message) = 0; + + // Indicates that there was a warning in the input at the given line and + // column numbers. The numbers are zero-based, so you may want to add + // 1 to each before printing them. + virtual void AddWarning(int /* line */, ColumnNumber /* column */, + const TProtoStringType& /* message */) {} + + private: + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ErrorCollector); +}; + +// This class converts a stream of raw text into a stream of tokens for +// the protocol definition parser to parse. The tokens recognized are +// similar to those that make up the C language; see the TokenType enum for +// precise descriptions. Whitespace and comments are skipped. By default, +// C- and C++-style comments are recognized, but other styles can be used by +// calling set_comment_style(). +class PROTOBUF_EXPORT Tokenizer { + public: + // Construct a Tokenizer that reads and tokenizes text from the given + // input stream and writes errors to the given error_collector. + // The caller keeps ownership of input and error_collector. + Tokenizer(ZeroCopyInputStream* input, ErrorCollector* error_collector); + ~Tokenizer(); + + enum TokenType { + TYPE_START, // Next() has not yet been called. + TYPE_END, // End of input reached. "text" is empty. + + TYPE_IDENTIFIER, // A sequence of letters, digits, and underscores, not + // starting with a digit. It is an error for a number + // to be followed by an identifier with no space in + // between. + TYPE_INTEGER, // A sequence of digits representing an integer. Normally + // the digits are decimal, but a prefix of "0x" indicates + // a hex number and a leading zero indicates octal, just + // like with C numeric literals. A leading negative sign + // is NOT included in the token; it's up to the parser to + // interpret the unary minus operator on its own. + TYPE_FLOAT, // A floating point literal, with a fractional part and/or + // an exponent. Always in decimal. Again, never + // negative. + TYPE_STRING, // A quoted sequence of escaped characters. Either single + // or double quotes can be used, but they must match. + // A string literal cannot cross a line break. + TYPE_SYMBOL, // Any other printable character, like '!' or '+'. + // Symbols are always a single character, so "!+$%" is + // four tokens. + TYPE_WHITESPACE, // A sequence of whitespace. This token type is only + // produced if report_whitespace() is true. It is not + // reported for whitespace within comments or strings. + TYPE_NEWLINE, // A newline (\n). This token type is only + // produced if report_whitespace() is true and + // report_newlines() is true. It is not reported for + // newlines in comments or strings. + }; + + // Structure representing a token read from the token stream. + struct Token { + TokenType type; + TProtoStringType text; // The exact text of the token as it appeared in + // the input. e.g. tokens of TYPE_STRING will still + // be escaped and in quotes. + + // "line" and "column" specify the position of the first character of + // the token within the input stream. They are zero-based. + int line; + ColumnNumber column; + ColumnNumber end_column; + }; + + // Get the current token. This is updated when Next() is called. Before + // the first call to Next(), current() has type TYPE_START and no contents. + const Token& current(); + + // Return the previous token -- i.e. what current() returned before the + // previous call to Next(). + const Token& previous(); + + // Advance to the next token. Returns false if the end of the input is + // reached. + bool Next(); + + // Like Next(), but also collects comments which appear between the previous + // and next tokens. + // + // Comments which appear to be attached to the previous token are stored + // in *prev_tailing_comments. Comments which appear to be attached to the + // next token are stored in *next_leading_comments. Comments appearing in + // between which do not appear to be attached to either will be added to + // detached_comments. Any of these parameters can be NULL to simply discard + // the comments. + // + // A series of line comments appearing on consecutive lines, with no other + // tokens appearing on those lines, will be treated as a single comment. + // + // Only the comment content is returned; comment markers (e.g. //) are + // stripped out. For block comments, leading whitespace and an asterisk will + // be stripped from the beginning of each line other than the first. Newlines + // are included in the output. + // + // Examples: + // + // optional int32 foo = 1; // Comment attached to foo. + // // Comment attached to bar. + // optional int32 bar = 2; + // + // optional string baz = 3; + // // Comment attached to baz. + // // Another line attached to baz. + // + // // Comment attached to qux. + // // + // // Another line attached to qux. + // optional double qux = 4; + // + // // Detached comment. This is not attached to qux or corge + // // because there are blank lines separating it from both. + // + // optional string corge = 5; + // /* Block comment attached + // * to corge. Leading asterisks + // * will be removed. */ + // /* Block comment attached to + // * grault. */ + // optional int32 grault = 6; + bool NextWithComments(TProtoStringType* prev_trailing_comments, + std::vector<TProtoStringType>* detached_comments, + TProtoStringType* next_leading_comments); + + // Parse helpers --------------------------------------------------- + + // Parses a TYPE_FLOAT token. This never fails, so long as the text actually + // comes from a TYPE_FLOAT token parsed by Tokenizer. If it doesn't, the + // result is undefined (possibly an assert failure). + static double ParseFloat(const TProtoStringType& text); + + // Parses a TYPE_STRING token. This never fails, so long as the text actually + // comes from a TYPE_STRING token parsed by Tokenizer. If it doesn't, the + // result is undefined (possibly an assert failure). + static void ParseString(const TProtoStringType& text, TProtoStringType* output); + + // Identical to ParseString, but appends to output. + static void ParseStringAppend(const TProtoStringType& text, TProtoStringType* output); + + // Parses a TYPE_INTEGER token. Returns false if the result would be + // greater than max_value. Otherwise, returns true and sets *output to the + // result. If the text is not from a Token of type TYPE_INTEGER originally + // parsed by a Tokenizer, the result is undefined (possibly an assert + // failure). + static bool ParseInteger(const TProtoStringType& text, arc_ui64 max_value, + arc_ui64* output); + + // Options --------------------------------------------------------- + + // Set true to allow floats to be suffixed with the letter 'f'. Tokens + // which would otherwise be integers but which have the 'f' suffix will be + // forced to be interpreted as floats. For all other purposes, the 'f' is + // ignored. + void set_allow_f_after_float(bool value) { allow_f_after_float_ = value; } + + // Valid values for set_comment_style(). + enum CommentStyle { + // Line comments begin with "//", block comments are delimited by "/*" and + // "*/". + CPP_COMMENT_STYLE, + // Line comments begin with "#". No way to write block comments. + SH_COMMENT_STYLE + }; + + // Sets the comment style. + void set_comment_style(CommentStyle style) { comment_style_ = style; } + + // Whether to require whitespace between a number and a field name. + // Default is true. Do not use this; for Google-internal cleanup only. + void set_require_space_after_number(bool require) { + require_space_after_number_ = require; + } + + // Whether to allow string literals to span multiple lines. Default is false. + // Do not use this; for Google-internal cleanup only. + void set_allow_multiline_strings(bool allow) { + allow_multiline_strings_ = allow; + } + + // If true, whitespace tokens are reported by Next(). + // Note: `set_report_whitespace(false)` implies `set_report_newlines(false)`. + bool report_whitespace() const; + void set_report_whitespace(bool report); + + // If true, newline tokens are reported by Next(). + // Note: `set_report_newlines(true)` implies `set_report_whitespace(true)`. + bool report_newlines() const; + void set_report_newlines(bool report); + + // External helper: validate an identifier. + static bool IsIdentifier(const TProtoStringType& text); + + // ----------------------------------------------------------------- + private: + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(Tokenizer); + + Token current_; // Returned by current(). + Token previous_; // Returned by previous(). + + ZeroCopyInputStream* input_; + ErrorCollector* error_collector_; + + char current_char_; // == buffer_[buffer_pos_], updated by NextChar(). + const char* buffer_; // Current buffer returned from input_. + int buffer_size_; // Size of buffer_. + int buffer_pos_; // Current position within the buffer. + bool read_error_; // Did we previously encounter a read error? + + // Line and column number of current_char_ within the whole input stream. + int line_; + ColumnNumber column_; + + // String to which text should be appended as we advance through it. + // Call RecordTo(&str) to start recording and StopRecording() to stop. + // E.g. StartToken() calls RecordTo(¤t_.text). record_start_ is the + // position within the current buffer where recording started. + TProtoStringType* record_target_; + int record_start_; + + // Options. + bool allow_f_after_float_; + CommentStyle comment_style_; + bool require_space_after_number_; + bool allow_multiline_strings_; + bool report_whitespace_ = false; + bool report_newlines_ = false; + + // Since we count columns we need to interpret tabs somehow. We'll take + // the standard 8-character definition for lack of any way to do better. + // This must match the documentation of ColumnNumber. + static const int kTabWidth = 8; + + // ----------------------------------------------------------------- + // Helper methods. + + // Consume this character and advance to the next one. + void NextChar(); + + // Read a new buffer from the input. + void Refresh(); + + inline void RecordTo(TProtoStringType* target); + inline void StopRecording(); + + // Called when the current character is the first character of a new + // token (not including whitespace or comments). + inline void StartToken(); + // Called when the current character is the first character after the + // end of the last token. After this returns, current_.text will + // contain all text consumed since StartToken() was called. + inline void EndToken(); + + // Convenience method to add an error at the current line and column. + void AddError(const TProtoStringType& message) { + error_collector_->AddError(line_, column_, message); + } + + // ----------------------------------------------------------------- + // The following four methods are used to consume tokens of specific + // types. They are actually used to consume all characters *after* + // the first, since the calling function consumes the first character + // in order to decide what kind of token is being read. + + // Read and consume a string, ending when the given delimiter is + // consumed. + void ConsumeString(char delimiter); + + // Read and consume a number, returning TYPE_FLOAT or TYPE_INTEGER + // depending on what was read. This needs to know if the first + // character was a zero in order to correctly recognize hex and octal + // numbers. + // It also needs to know if the first character was a . to parse floating + // point correctly. + TokenType ConsumeNumber(bool started_with_zero, bool started_with_dot); + + // Consume the rest of a line. + void ConsumeLineComment(TProtoStringType* content); + // Consume until "*/". + void ConsumeBlockComment(TProtoStringType* content); + + enum NextCommentStatus { + // Started a line comment. + LINE_COMMENT, + + // Started a block comment. + BLOCK_COMMENT, + + // Consumed a slash, then realized it wasn't a comment. current_ has + // been filled in with a slash token. The caller should return it. + SLASH_NOT_COMMENT, + + // We do not appear to be starting a comment here. + NO_COMMENT + }; + + // If we're at the start of a new comment, consume it and return what kind + // of comment it is. + NextCommentStatus TryConsumeCommentStart(); + + // If we're looking at a TYPE_WHITESPACE token and `report_whitespace_` is + // true, consume it and return true. + bool TryConsumeWhitespace(); + + // If we're looking at a TYPE_NEWLINE token and `report_newlines_` is true, + // consume it and return true. + bool TryConsumeNewline(); + + // ----------------------------------------------------------------- + // These helper methods make the parsing code more readable. The + // "character classes" referred to are defined at the top of the .cc file. + // Basically it is a C++ class with one method: + // static bool InClass(char c); + // The method returns true if c is a member of this "class", like "Letter" + // or "Digit". + + // Returns true if the current character is of the given character + // class, but does not consume anything. + template <typename CharacterClass> + inline bool LookingAt(); + + // If the current character is in the given class, consume it and return + // true. Otherwise return false. + // e.g. TryConsumeOne<Letter>() + template <typename CharacterClass> + inline bool TryConsumeOne(); + + // Like above, but try to consume the specific character indicated. + inline bool TryConsume(char c); + + // Consume zero or more of the given character class. + template <typename CharacterClass> + inline void ConsumeZeroOrMore(); + + // Consume one or more of the given character class or log the given + // error message. + // e.g. ConsumeOneOrMore<Digit>("Expected digits."); + template <typename CharacterClass> + inline void ConsumeOneOrMore(const char* error); +}; + +// inline methods ==================================================== +inline const Tokenizer::Token& Tokenizer::current() { return current_; } + +inline const Tokenizer::Token& Tokenizer::previous() { return previous_; } + +inline void Tokenizer::ParseString(const TProtoStringType& text, + TProtoStringType* output) { + output->clear(); + ParseStringAppend(text, output); +} + +} // namespace io +} // namespace protobuf +} // namespace google + +#include <google/protobuf/port_undef.inc> + +#endif // GOOGLE_PROTOBUF_IO_TOKENIZER_H__ diff --git a/contrib/libs/protobuf_old/src/google/protobuf/io/zero_copy_stream.cc b/contrib/libs/protobuf_old/src/google/protobuf/io/zero_copy_stream.cc new file mode 100644 index 0000000000..f81555e554 --- /dev/null +++ b/contrib/libs/protobuf_old/src/google/protobuf/io/zero_copy_stream.cc @@ -0,0 +1,55 @@ +// 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: kenton@google.com (Kenton Varda) +// Based on original Protocol Buffers design by +// Sanjay Ghemawat, Jeff Dean, and others. + +#include <google/protobuf/io/zero_copy_stream.h> + +#include <google/protobuf/stubs/logging.h> +#include <google/protobuf/stubs/common.h> + +namespace google { +namespace protobuf { +namespace io { + + +bool ZeroCopyOutputStream::WriteAliasedRaw(const void* /* data */, + int /* size */) { + GOOGLE_LOG(FATAL) << "This ZeroCopyOutputStream doesn't support aliasing. " + "Reaching here usually means a ZeroCopyOutputStream " + "implementation bug."; + return false; +} + +} // namespace io +} // namespace protobuf +} // namespace google diff --git a/contrib/libs/protobuf_old/src/google/protobuf/io/zero_copy_stream.h b/contrib/libs/protobuf_old/src/google/protobuf/io/zero_copy_stream.h new file mode 100644 index 0000000000..d3bd6daed3 --- /dev/null +++ b/contrib/libs/protobuf_old/src/google/protobuf/io/zero_copy_stream.h @@ -0,0 +1,253 @@ +// 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: kenton@google.com (Kenton Varda) +// Based on original Protocol Buffers design by +// Sanjay Ghemawat, Jeff Dean, and others. +// +// This file contains the ZeroCopyInputStream and ZeroCopyOutputStream +// interfaces, which represent abstract I/O streams to and from which +// protocol buffers can be read and written. For a few simple +// implementations of these interfaces, see zero_copy_stream_impl.h. +// +// These interfaces are different from classic I/O streams in that they +// try to minimize the amount of data copying that needs to be done. +// To accomplish this, responsibility for allocating buffers is moved to +// the stream object, rather than being the responsibility of the caller. +// So, the stream can return a buffer which actually points directly into +// the final data structure where the bytes are to be stored, and the caller +// can interact directly with that buffer, eliminating an intermediate copy +// operation. +// +// As an example, consider the common case in which you are reading bytes +// from an array that is already in memory (or perhaps an mmap()ed file). +// With classic I/O streams, you would do something like: +// char buffer[BUFFER_SIZE]; +// input->Read(buffer, BUFFER_SIZE); +// DoSomething(buffer, BUFFER_SIZE); +// Then, the stream basically just calls memcpy() to copy the data from +// the array into your buffer. With a ZeroCopyInputStream, you would do +// this instead: +// const void* buffer; +// int size; +// input->Next(&buffer, &size); +// DoSomething(buffer, size); +// Here, no copy is performed. The input stream returns a pointer directly +// into the backing array, and the caller ends up reading directly from it. +// +// If you want to be able to read the old-fashion way, you can create +// a CodedInputStream or CodedOutputStream wrapping these objects and use +// their ReadRaw()/WriteRaw() methods. These will, of course, add a copy +// step, but Coded*Stream will handle buffering so at least it will be +// reasonably efficient. +// +// ZeroCopyInputStream example: +// // Read in a file and print its contents to stdout. +// int fd = open("myfile", O_RDONLY); +// ZeroCopyInputStream* input = new FileInputStream(fd); +// +// const void* buffer; +// int size; +// while (input->Next(&buffer, &size)) { +// cout.write(buffer, size); +// } +// +// delete input; +// close(fd); +// +// ZeroCopyOutputStream example: +// // Copy the contents of "infile" to "outfile", using plain read() for +// // "infile" but a ZeroCopyOutputStream for "outfile". +// int infd = open("infile", O_RDONLY); +// int outfd = open("outfile", O_WRONLY); +// ZeroCopyOutputStream* output = new FileOutputStream(outfd); +// +// void* buffer; +// int size; +// while (output->Next(&buffer, &size)) { +// int bytes = read(infd, buffer, size); +// if (bytes < size) { +// // Reached EOF. +// output->BackUp(size - bytes); +// break; +// } +// } +// +// delete output; +// close(infd); +// close(outfd); + +#ifndef GOOGLE_PROTOBUF_IO_ZERO_COPY_STREAM_H__ +#define GOOGLE_PROTOBUF_IO_ZERO_COPY_STREAM_H__ + + +#include <string> + +#include <google/protobuf/stubs/common.h> +#include <google/protobuf/port_def.inc> + + +namespace google { +namespace protobuf { +namespace io { + +// Defined in this file. +class ZeroCopyInputStream; +class ZeroCopyOutputStream; + +// Abstract interface similar to an input stream but designed to minimize +// copying. +class PROTOBUF_EXPORT ZeroCopyInputStream { + public: + ZeroCopyInputStream() {} + virtual ~ZeroCopyInputStream() {} + + // Obtains a chunk of data from the stream. + // + // Preconditions: + // * "size" and "data" are not NULL. + // + // Postconditions: + // * If the returned value is false, there is no more data to return or + // an error occurred. All errors are permanent. + // * Otherwise, "size" points to the actual number of bytes read and "data" + // points to a pointer to a buffer containing these bytes. + // * Ownership of this buffer remains with the stream, and the buffer + // remains valid only until some other method of the stream is called + // or the stream is destroyed. + // * It is legal for the returned buffer to have zero size, as long + // as repeatedly calling Next() eventually yields a buffer with non-zero + // size. + virtual bool Next(const void** data, int* size) = 0; + + // Backs up a number of bytes, so that the next call to Next() returns + // data again that was already returned by the last call to Next(). This + // is useful when writing procedures that are only supposed to read up + // to a certain point in the input, then return. If Next() returns a + // buffer that goes beyond what you wanted to read, you can use BackUp() + // to return to the point where you intended to finish. + // + // Preconditions: + // * The last method called must have been Next(). + // * count must be less than or equal to the size of the last buffer + // returned by Next(). + // + // Postconditions: + // * The last "count" bytes of the last buffer returned by Next() will be + // pushed back into the stream. Subsequent calls to Next() will return + // the same data again before producing new data. + virtual void BackUp(int count) = 0; + + // Skips a number of bytes. Returns false if the end of the stream is + // reached or some input error occurred. In the end-of-stream case, the + // stream is advanced to the end of the stream (so ByteCount() will return + // the total size of the stream). + virtual bool Skip(int count) = 0; + + // Returns the total number of bytes read since this object was created. + virtual int64_t ByteCount() const = 0; + + + private: + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ZeroCopyInputStream); +}; + +// Abstract interface similar to an output stream but designed to minimize +// copying. +class PROTOBUF_EXPORT ZeroCopyOutputStream { + public: + ZeroCopyOutputStream() {} + virtual ~ZeroCopyOutputStream() {} + + // Obtains a buffer into which data can be written. Any data written + // into this buffer will eventually (maybe instantly, maybe later on) + // be written to the output. + // + // Preconditions: + // * "size" and "data" are not NULL. + // + // Postconditions: + // * If the returned value is false, an error occurred. All errors are + // permanent. + // * Otherwise, "size" points to the actual number of bytes in the buffer + // and "data" points to the buffer. + // * Ownership of this buffer remains with the stream, and the buffer + // remains valid only until some other method of the stream is called + // or the stream is destroyed. + // * Any data which the caller stores in this buffer will eventually be + // written to the output (unless BackUp() is called). + // * It is legal for the returned buffer to have zero size, as long + // as repeatedly calling Next() eventually yields a buffer with non-zero + // size. + virtual bool Next(void** data, int* size) = 0; + + // Backs up a number of bytes, so that the end of the last buffer returned + // by Next() is not actually written. This is needed when you finish + // writing all the data you want to write, but the last buffer was bigger + // than you needed. You don't want to write a bunch of garbage after the + // end of your data, so you use BackUp() to back up. + // + // Preconditions: + // * The last method called must have been Next(). + // * count must be less than or equal to the size of the last buffer + // returned by Next(). + // * The caller must not have written anything to the last "count" bytes + // of that buffer. + // + // Postconditions: + // * The last "count" bytes of the last buffer returned by Next() will be + // ignored. + virtual void BackUp(int count) = 0; + + // Returns the total number of bytes written since this object was created. + virtual int64_t ByteCount() const = 0; + + // Write a given chunk of data to the output. Some output streams may + // implement this in a way that avoids copying. Check AllowsAliasing() before + // calling WriteAliasedRaw(). It will GOOGLE_CHECK fail if WriteAliasedRaw() is + // called on a stream that does not allow aliasing. + // + // NOTE: It is caller's responsibility to ensure that the chunk of memory + // remains live until all of the data has been consumed from the stream. + virtual bool WriteAliasedRaw(const void* data, int size); + virtual bool AllowsAliasing() const { return false; } + + + private: + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ZeroCopyOutputStream); +}; + +} // namespace io +} // namespace protobuf +} // namespace google + +#include <google/protobuf/port_undef.inc> + +#endif // GOOGLE_PROTOBUF_IO_ZERO_COPY_STREAM_H__ diff --git a/contrib/libs/protobuf_old/src/google/protobuf/io/zero_copy_stream_impl.cc b/contrib/libs/protobuf_old/src/google/protobuf/io/zero_copy_stream_impl.cc new file mode 100644 index 0000000000..7439a70d61 --- /dev/null +++ b/contrib/libs/protobuf_old/src/google/protobuf/io/zero_copy_stream_impl.cc @@ -0,0 +1,372 @@ +// 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: kenton@google.com (Kenton Varda) +// Based on original Protocol Buffers design by +// Sanjay Ghemawat, Jeff Dean, and others. + +#ifndef _MSC_VER +#include <fcntl.h> +#include <sys/stat.h> +#include <sys/types.h> +#include <unistd.h> +#endif +#include <errno.h> + +#include <algorithm> +#include <iostream> + +#include <google/protobuf/stubs/common.h> +#include <google/protobuf/stubs/logging.h> +#include <google/protobuf/io/io_win32.h> +#include <google/protobuf/io/zero_copy_stream_impl.h> +#include <google/protobuf/stubs/stl_util.h> + + +namespace google { +namespace protobuf { +namespace io { + +#ifdef _WIN32 +// Win32 lseek is broken: If invoked on a non-seekable file descriptor, its +// return value is undefined. We re-define it to always produce an error. +#define lseek(fd, offset, origin) ((off_t)-1) +// DO NOT include <io.h>, instead create functions in io_win32.{h,cc} and import +// them like we do below. +using google::protobuf::io::win32::access; +using google::protobuf::io::win32::close; +using google::protobuf::io::win32::open; +using google::protobuf::io::win32::read; +using google::protobuf::io::win32::write; +#endif + +namespace { + +// EINTR sucks. +int close_no_eintr(int fd) { + int result; + do { + result = close(fd); + } while (result < 0 && errno == EINTR); + return result; +} + +} // namespace + +// =================================================================== + +FileInputStream::FileInputStream(int file_descriptor, int block_size) + : copying_input_(file_descriptor), impl_(©ing_input_, block_size) {} + +bool FileInputStream::Close() { return copying_input_.Close(); } + +bool FileInputStream::Next(const void** data, int* size) { + return impl_.Next(data, size); +} + +void FileInputStream::BackUp(int count) { impl_.BackUp(count); } + +bool FileInputStream::Skip(int count) { return impl_.Skip(count); } + +int64_t FileInputStream::ByteCount() const { return impl_.ByteCount(); } + +FileInputStream::CopyingFileInputStream::CopyingFileInputStream( + int file_descriptor) + : file_(file_descriptor), + close_on_delete_(false), + is_closed_(false), + errno_(0), + previous_seek_failed_(false) { +#ifndef _WIN32 + int flags = fcntl(file_, F_GETFL); + flags &= ~O_NONBLOCK; + fcntl(file_, F_SETFL, flags); +#endif +} + +FileInputStream::CopyingFileInputStream::~CopyingFileInputStream() { + if (close_on_delete_) { + if (!Close()) { + GOOGLE_LOG(ERROR) << "close() failed: " << strerror(errno_); + } + } +} + +bool FileInputStream::CopyingFileInputStream::Close() { + GOOGLE_CHECK(!is_closed_); + + is_closed_ = true; + if (close_no_eintr(file_) != 0) { + // The docs on close() do not specify whether a file descriptor is still + // open after close() fails with EIO. However, the glibc source code + // seems to indicate that it is not. + errno_ = errno; + return false; + } + + return true; +} + +int FileInputStream::CopyingFileInputStream::Read(void* buffer, int size) { + GOOGLE_CHECK(!is_closed_); + + int result; + do { + result = read(file_, buffer, size); + } while (result < 0 && errno == EINTR); + + if (result < 0) { + // Read error (not EOF). + errno_ = errno; + } + + return result; +} + +int FileInputStream::CopyingFileInputStream::Skip(int count) { + GOOGLE_CHECK(!is_closed_); + + if (!previous_seek_failed_ && lseek(file_, count, SEEK_CUR) != (off_t)-1) { + // Seek succeeded. + return count; + } else { + // Failed to seek. + + // Note to self: Don't seek again. This file descriptor doesn't + // support it. + previous_seek_failed_ = true; + + // Use the default implementation. + return CopyingInputStream::Skip(count); + } +} + +// =================================================================== + +FileOutputStream::FileOutputStream(int file_descriptor, int /*block_size*/) + : CopyingOutputStreamAdaptor(©ing_output_), + copying_output_(file_descriptor) {} + +bool FileOutputStream::Close() { + bool flush_succeeded = Flush(); + return copying_output_.Close() && flush_succeeded; +} + +FileOutputStream::CopyingFileOutputStream::CopyingFileOutputStream( + int file_descriptor) + : file_(file_descriptor), + close_on_delete_(false), + is_closed_(false), + errno_(0) {} + +FileOutputStream::~FileOutputStream() { Flush(); } + +FileOutputStream::CopyingFileOutputStream::~CopyingFileOutputStream() { + if (close_on_delete_) { + if (!Close()) { + GOOGLE_LOG(ERROR) << "close() failed: " << strerror(errno_); + } + } +} + +bool FileOutputStream::CopyingFileOutputStream::Close() { + GOOGLE_CHECK(!is_closed_); + + is_closed_ = true; + if (close_no_eintr(file_) != 0) { + // The docs on close() do not specify whether a file descriptor is still + // open after close() fails with EIO. However, the glibc source code + // seems to indicate that it is not. + errno_ = errno; + return false; + } + + return true; +} + +bool FileOutputStream::CopyingFileOutputStream::Write(const void* buffer, + int size) { + GOOGLE_CHECK(!is_closed_); + int total_written = 0; + + const uint8_t* buffer_base = reinterpret_cast<const uint8_t*>(buffer); + + while (total_written < size) { + int bytes; + do { + bytes = write(file_, buffer_base + total_written, size - total_written); + } while (bytes < 0 && errno == EINTR); + + if (bytes <= 0) { + // Write error. + + // FIXME(kenton): According to the man page, if write() returns zero, + // there was no error; write() simply did not write anything. It's + // unclear under what circumstances this might happen, but presumably + // errno won't be set in this case. I am confused as to how such an + // event should be handled. For now I'm treating it as an error, since + // retrying seems like it could lead to an infinite loop. I suspect + // this never actually happens anyway. + + if (bytes < 0) { + errno_ = errno; + } + return false; + } + total_written += bytes; + } + + return true; +} + +// =================================================================== + +IstreamInputStream::IstreamInputStream(std::istream* input, int block_size) + : copying_input_(input), impl_(©ing_input_, block_size) {} + +bool IstreamInputStream::Next(const void** data, int* size) { + return impl_.Next(data, size); +} + +void IstreamInputStream::BackUp(int count) { impl_.BackUp(count); } + +bool IstreamInputStream::Skip(int count) { return impl_.Skip(count); } + +int64_t IstreamInputStream::ByteCount() const { return impl_.ByteCount(); } + +IstreamInputStream::CopyingIstreamInputStream::CopyingIstreamInputStream( + std::istream* input) + : input_(input) {} + +IstreamInputStream::CopyingIstreamInputStream::~CopyingIstreamInputStream() {} + +int IstreamInputStream::CopyingIstreamInputStream::Read(void* buffer, + int size) { + input_->read(reinterpret_cast<char*>(buffer), size); + int result = input_->gcount(); + if (result == 0 && input_->fail() && !input_->eof()) { + return -1; + } + return result; +} + +// =================================================================== + +OstreamOutputStream::OstreamOutputStream(std::ostream* output, int block_size) + : copying_output_(output), impl_(©ing_output_, block_size) {} + +OstreamOutputStream::~OstreamOutputStream() { impl_.Flush(); } + +bool OstreamOutputStream::Next(void** data, int* size) { + return impl_.Next(data, size); +} + +void OstreamOutputStream::BackUp(int count) { impl_.BackUp(count); } + +int64_t OstreamOutputStream::ByteCount() const { return impl_.ByteCount(); } + +OstreamOutputStream::CopyingOstreamOutputStream::CopyingOstreamOutputStream( + std::ostream* output) + : output_(output) {} + +OstreamOutputStream::CopyingOstreamOutputStream::~CopyingOstreamOutputStream() { +} + +bool OstreamOutputStream::CopyingOstreamOutputStream::Write(const void* buffer, + int size) { + output_->write(reinterpret_cast<const char*>(buffer), size); + return output_->good(); +} + +// =================================================================== + +ConcatenatingInputStream::ConcatenatingInputStream( + ZeroCopyInputStream* const streams[], int count) + : streams_(streams), stream_count_(count), bytes_retired_(0) { +} + +bool ConcatenatingInputStream::Next(const void** data, int* size) { + while (stream_count_ > 0) { + if (streams_[0]->Next(data, size)) return true; + + // That stream is done. Advance to the next one. + bytes_retired_ += streams_[0]->ByteCount(); + ++streams_; + --stream_count_; + } + + // No more streams. + return false; +} + +void ConcatenatingInputStream::BackUp(int count) { + if (stream_count_ > 0) { + streams_[0]->BackUp(count); + } else { + GOOGLE_LOG(DFATAL) << "Can't BackUp() after failed Next()."; + } +} + +bool ConcatenatingInputStream::Skip(int count) { + while (stream_count_ > 0) { + // Assume that ByteCount() can be used to find out how much we actually + // skipped when Skip() fails. + arc_i64 target_byte_count = streams_[0]->ByteCount() + count; + if (streams_[0]->Skip(count)) return true; + + // Hit the end of the stream. Figure out how many more bytes we still have + // to skip. + arc_i64 final_byte_count = streams_[0]->ByteCount(); + GOOGLE_DCHECK_LT(final_byte_count, target_byte_count); + count = target_byte_count - final_byte_count; + + // That stream is done. Advance to the next one. + bytes_retired_ += final_byte_count; + ++streams_; + --stream_count_; + } + + return false; +} + +int64_t ConcatenatingInputStream::ByteCount() const { + if (stream_count_ == 0) { + return bytes_retired_; + } else { + return bytes_retired_ + streams_[0]->ByteCount(); + } +} + + +// =================================================================== + +} // namespace io +} // namespace protobuf +} // namespace google diff --git a/contrib/libs/protobuf_old/src/google/protobuf/io/zero_copy_stream_impl.h b/contrib/libs/protobuf_old/src/google/protobuf/io/zero_copy_stream_impl.h new file mode 100644 index 0000000000..1f4426c628 --- /dev/null +++ b/contrib/libs/protobuf_old/src/google/protobuf/io/zero_copy_stream_impl.h @@ -0,0 +1,327 @@ +// 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: kenton@google.com (Kenton Varda) +// Based on original Protocol Buffers design by +// Sanjay Ghemawat, Jeff Dean, and others. +// +// This file contains common implementations of the interfaces defined in +// zero_copy_stream.h which are only included in the full (non-lite) +// protobuf library. These implementations include Unix file descriptors +// and C++ iostreams. See also: zero_copy_stream_impl_lite.h + +#ifndef GOOGLE_PROTOBUF_IO_ZERO_COPY_STREAM_IMPL_H__ +#define GOOGLE_PROTOBUF_IO_ZERO_COPY_STREAM_IMPL_H__ + + +#include <iosfwd> +#include <string> + +#include <google/protobuf/stubs/common.h> +#include <google/protobuf/io/zero_copy_stream.h> +#include <google/protobuf/io/zero_copy_stream_impl_lite.h> + +#include <google/protobuf/port_def.inc> + +namespace google { +namespace protobuf { +namespace io { + +// =================================================================== + +// A ZeroCopyInputStream which reads from a file descriptor. +// +// FileInputStream is preferred over using an ifstream with IstreamInputStream. +// The latter will introduce an extra layer of buffering, harming performance. +// Also, it's conceivable that FileInputStream could someday be enhanced +// to use zero-copy file descriptors on OSs which support them. +class PROTOBUF_EXPORT FileInputStream : public ZeroCopyInputStream { + public: + // Creates a stream that reads from the given Unix file descriptor. + // If a block_size is given, it specifies the number of bytes that + // should be read and returned with each call to Next(). Otherwise, + // a reasonable default is used. + explicit FileInputStream(int file_descriptor, int block_size = -1); + + // Flushes any buffers and closes the underlying file. Returns false if + // an error occurs during the process; use GetErrno() to examine the error. + // Even if an error occurs, the file descriptor is closed when this returns. + bool Close(); + + // By default, the file descriptor is not closed when the stream is + // destroyed. Call SetCloseOnDelete(true) to change that. WARNING: + // This leaves no way for the caller to detect if close() fails. If + // detecting close() errors is important to you, you should arrange + // to close the descriptor yourself. + void SetCloseOnDelete(bool value) { copying_input_.SetCloseOnDelete(value); } + + // If an I/O error has occurred on this file descriptor, this is the + // errno from that error. Otherwise, this is zero. Once an error + // occurs, the stream is broken and all subsequent operations will + // fail. + int GetErrno() const { return copying_input_.GetErrno(); } + + // implements ZeroCopyInputStream ---------------------------------- + bool Next(const void** data, int* size) override; + void BackUp(int count) override; + bool Skip(int count) override; + int64_t ByteCount() const override; + + private: + class PROTOBUF_EXPORT CopyingFileInputStream : public CopyingInputStream { + public: + CopyingFileInputStream(int file_descriptor); + ~CopyingFileInputStream() override; + + bool Close(); + void SetCloseOnDelete(bool value) { close_on_delete_ = value; } + int GetErrno() const { return errno_; } + + // implements CopyingInputStream --------------------------------- + int Read(void* buffer, int size) override; + int Skip(int count) override; + + private: + // The file descriptor. + const int file_; + bool close_on_delete_; + bool is_closed_; + + // The errno of the I/O error, if one has occurred. Otherwise, zero. + int errno_; + + // Did we try to seek once and fail? If so, we assume this file descriptor + // doesn't support seeking and won't try again. + bool previous_seek_failed_; + + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(CopyingFileInputStream); + }; + + CopyingFileInputStream copying_input_; + CopyingInputStreamAdaptor impl_; + + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(FileInputStream); +}; + +// =================================================================== + +// A ZeroCopyOutputStream which writes to a file descriptor. +// +// FileOutputStream is preferred over using an ofstream with +// OstreamOutputStream. The latter will introduce an extra layer of buffering, +// harming performance. Also, it's conceivable that FileOutputStream could +// someday be enhanced to use zero-copy file descriptors on OSs which +// support them. +class PROTOBUF_EXPORT FileOutputStream : public CopyingOutputStreamAdaptor { + public: + // Creates a stream that writes to the given Unix file descriptor. + // If a block_size is given, it specifies the size of the buffers + // that should be returned by Next(). Otherwise, a reasonable default + // is used. + explicit FileOutputStream(int file_descriptor, int block_size = -1); + + ~FileOutputStream() override; + + // Flushes any buffers and closes the underlying file. Returns false if + // an error occurs during the process; use GetErrno() to examine the error. + // Even if an error occurs, the file descriptor is closed when this returns. + bool Close(); + + // By default, the file descriptor is not closed when the stream is + // destroyed. Call SetCloseOnDelete(true) to change that. WARNING: + // This leaves no way for the caller to detect if close() fails. If + // detecting close() errors is important to you, you should arrange + // to close the descriptor yourself. + void SetCloseOnDelete(bool value) { copying_output_.SetCloseOnDelete(value); } + + // If an I/O error has occurred on this file descriptor, this is the + // errno from that error. Otherwise, this is zero. Once an error + // occurs, the stream is broken and all subsequent operations will + // fail. + int GetErrno() const { return copying_output_.GetErrno(); } + + private: + class PROTOBUF_EXPORT CopyingFileOutputStream : public CopyingOutputStream { + public: + CopyingFileOutputStream(int file_descriptor); + ~CopyingFileOutputStream() override; + + bool Close(); + void SetCloseOnDelete(bool value) { close_on_delete_ = value; } + int GetErrno() const { return errno_; } + + // implements CopyingOutputStream -------------------------------- + bool Write(const void* buffer, int size) override; + + private: + // The file descriptor. + const int file_; + bool close_on_delete_; + bool is_closed_; + + // The errno of the I/O error, if one has occurred. Otherwise, zero. + int errno_; + + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(CopyingFileOutputStream); + }; + + CopyingFileOutputStream copying_output_; + + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(FileOutputStream); +}; + +// =================================================================== + +// A ZeroCopyInputStream which reads from a C++ istream. +// +// Note that for reading files (or anything represented by a file descriptor), +// FileInputStream is more efficient. +class PROTOBUF_EXPORT IstreamInputStream : public ZeroCopyInputStream { + public: + // Creates a stream that reads from the given C++ istream. + // If a block_size is given, it specifies the number of bytes that + // should be read and returned with each call to Next(). Otherwise, + // a reasonable default is used. + explicit IstreamInputStream(std::istream* stream, int block_size = -1); + + // implements ZeroCopyInputStream ---------------------------------- + bool Next(const void** data, int* size) override; + void BackUp(int count) override; + bool Skip(int count) override; + int64_t ByteCount() const override; + + private: + class PROTOBUF_EXPORT CopyingIstreamInputStream : public CopyingInputStream { + public: + CopyingIstreamInputStream(std::istream* input); + ~CopyingIstreamInputStream() override; + + // implements CopyingInputStream --------------------------------- + int Read(void* buffer, int size) override; + // (We use the default implementation of Skip().) + + private: + // The stream. + std::istream* input_; + + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(CopyingIstreamInputStream); + }; + + CopyingIstreamInputStream copying_input_; + CopyingInputStreamAdaptor impl_; + + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(IstreamInputStream); +}; + +// =================================================================== + +// A ZeroCopyOutputStream which writes to a C++ ostream. +// +// Note that for writing files (or anything represented by a file descriptor), +// FileOutputStream is more efficient. +class PROTOBUF_EXPORT OstreamOutputStream : public ZeroCopyOutputStream { + public: + // Creates a stream that writes to the given C++ ostream. + // If a block_size is given, it specifies the size of the buffers + // that should be returned by Next(). Otherwise, a reasonable default + // is used. + explicit OstreamOutputStream(std::ostream* stream, int block_size = -1); + ~OstreamOutputStream() override; + + // implements ZeroCopyOutputStream --------------------------------- + bool Next(void** data, int* size) override; + void BackUp(int count) override; + int64_t ByteCount() const override; + + private: + class PROTOBUF_EXPORT CopyingOstreamOutputStream + : public CopyingOutputStream { + public: + CopyingOstreamOutputStream(std::ostream* output); + ~CopyingOstreamOutputStream() override; + + // implements CopyingOutputStream -------------------------------- + bool Write(const void* buffer, int size) override; + + private: + // The stream. + std::ostream* output_; + + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(CopyingOstreamOutputStream); + }; + + CopyingOstreamOutputStream copying_output_; + CopyingOutputStreamAdaptor impl_; + + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(OstreamOutputStream); +}; + +// =================================================================== + +// A ZeroCopyInputStream which reads from several other streams in sequence. +// ConcatenatingInputStream is unable to distinguish between end-of-stream +// and read errors in the underlying streams, so it assumes any errors mean +// end-of-stream. So, if the underlying streams fail for any other reason, +// ConcatenatingInputStream may do odd things. It is suggested that you do +// not use ConcatenatingInputStream on streams that might produce read errors +// other than end-of-stream. +class PROTOBUF_EXPORT ConcatenatingInputStream : public ZeroCopyInputStream { + public: + // All streams passed in as well as the array itself must remain valid + // until the ConcatenatingInputStream is destroyed. + ConcatenatingInputStream(ZeroCopyInputStream* const streams[], int count); + ~ConcatenatingInputStream() override = default; + + // implements ZeroCopyInputStream ---------------------------------- + bool Next(const void** data, int* size) override; + void BackUp(int count) override; + bool Skip(int count) override; + int64_t ByteCount() const override; + + + private: + // As streams are retired, streams_ is incremented and count_ is + // decremented. + ZeroCopyInputStream* const* streams_; + int stream_count_; + arc_i64 bytes_retired_; // Bytes read from previous streams. + + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ConcatenatingInputStream); +}; + +// =================================================================== + +} // namespace io +} // namespace protobuf +} // namespace google + +#include <google/protobuf/port_undef.inc> + +#endif // GOOGLE_PROTOBUF_IO_ZERO_COPY_STREAM_IMPL_H__ diff --git a/contrib/libs/protobuf_old/src/google/protobuf/io/zero_copy_stream_impl_lite.cc b/contrib/libs/protobuf_old/src/google/protobuf/io/zero_copy_stream_impl_lite.cc new file mode 100644 index 0000000000..1325f04e35 --- /dev/null +++ b/contrib/libs/protobuf_old/src/google/protobuf/io/zero_copy_stream_impl_lite.cc @@ -0,0 +1,467 @@ +// 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: kenton@google.com (Kenton Varda) +// Based on original Protocol Buffers design by +// Sanjay Ghemawat, Jeff Dean, and others. + +#include <google/protobuf/io/zero_copy_stream_impl_lite.h> + +#include <algorithm> +#include <limits> + +#include <google/protobuf/stubs/common.h> +#include <google/protobuf/stubs/logging.h> +#include <google/protobuf/stubs/casts.h> +#include <google/protobuf/stubs/stl_util.h> + +namespace google { +namespace protobuf { +namespace io { + +namespace { + +// Default block size for Copying{In,Out}putStreamAdaptor. +static const int kDefaultBlockSize = 8192; + +} // namespace + +// =================================================================== + +ArrayInputStream::ArrayInputStream(const void* data, int size, int block_size) + : data_(reinterpret_cast<const uint8_t*>(data)), + size_(size), + block_size_(block_size > 0 ? block_size : size), + position_(0), + last_returned_size_(0) {} + +bool ArrayInputStream::Next(const void** data, int* size) { + if (position_ < size_) { + last_returned_size_ = std::min(block_size_, size_ - position_); + *data = data_ + position_; + *size = last_returned_size_; + position_ += last_returned_size_; + return true; + } else { + // We're at the end of the array. + last_returned_size_ = 0; // Don't let caller back up. + return false; + } +} + +void ArrayInputStream::BackUp(int count) { + GOOGLE_CHECK_GT(last_returned_size_, 0) + << "BackUp() can only be called after a successful Next()."; + GOOGLE_CHECK_LE(count, last_returned_size_); + GOOGLE_CHECK_GE(count, 0); + position_ -= count; + last_returned_size_ = 0; // Don't let caller back up further. +} + +bool ArrayInputStream::Skip(int count) { + GOOGLE_CHECK_GE(count, 0); + last_returned_size_ = 0; // Don't let caller back up. + if (count > size_ - position_) { + position_ = size_; + return false; + } else { + position_ += count; + return true; + } +} + +int64_t ArrayInputStream::ByteCount() const { return position_; } + + +// =================================================================== + +ArrayOutputStream::ArrayOutputStream(void* data, int size, int block_size) + : data_(reinterpret_cast<uint8_t*>(data)), + size_(size), + block_size_(block_size > 0 ? block_size : size), + position_(0), + last_returned_size_(0) {} + +bool ArrayOutputStream::Next(void** data, int* size) { + if (position_ < size_) { + last_returned_size_ = std::min(block_size_, size_ - position_); + *data = data_ + position_; + *size = last_returned_size_; + position_ += last_returned_size_; + return true; + } else { + // We're at the end of the array. + last_returned_size_ = 0; // Don't let caller back up. + return false; + } +} + +void ArrayOutputStream::BackUp(int count) { + GOOGLE_CHECK_GT(last_returned_size_, 0) + << "BackUp() can only be called after a successful Next()."; + GOOGLE_CHECK_LE(count, last_returned_size_); + GOOGLE_CHECK_GE(count, 0); + position_ -= count; + last_returned_size_ = 0; // Don't let caller back up further. +} + +int64_t ArrayOutputStream::ByteCount() const { return position_; } + +// =================================================================== + +StringOutputStream::StringOutputStream(TProtoStringType* target) : target_(target) {} + +bool StringOutputStream::Next(void** data, int* size) { + GOOGLE_CHECK(target_ != NULL); + size_t old_size = target_->size(); + + // Grow the string. + size_t new_size; + if (old_size < target_->capacity()) { + // Resize the string to match its capacity, since we can get away + // without a memory allocation this way. + new_size = target_->capacity(); + } else { + // Size has reached capacity, try to double it. + new_size = old_size * 2; + } + // Avoid integer overflow in returned '*size'. + new_size = std::min(new_size, old_size + std::numeric_limits<int>::max()); + // Increase the size, also make sure that it is at least kMinimumSize. + STLStringResizeUninitialized( + target_, + std::max(new_size, + kMinimumSize + 0)); // "+ 0" works around GCC4 weirdness. + + *data = mutable_string_data(target_) + old_size; + *size = target_->size() - old_size; + return true; +} + +void StringOutputStream::BackUp(int count) { + GOOGLE_CHECK_GE(count, 0); + GOOGLE_CHECK(target_ != NULL); + GOOGLE_CHECK_LE(static_cast<size_t>(count), target_->size()); + target_->resize(target_->size() - count); +} + +int64_t StringOutputStream::ByteCount() const { + GOOGLE_CHECK(target_ != NULL); + return target_->size(); +} + +// =================================================================== + +int CopyingInputStream::Skip(int count) { + char junk[4096]; + int skipped = 0; + while (skipped < count) { + int bytes = Read(junk, std::min(count - skipped, + implicit_cast<int>(sizeof(junk)))); + if (bytes <= 0) { + // EOF or read error. + return skipped; + } + skipped += bytes; + } + return skipped; +} + +CopyingInputStreamAdaptor::CopyingInputStreamAdaptor( + CopyingInputStream* copying_stream, int block_size) + : copying_stream_(copying_stream), + owns_copying_stream_(false), + failed_(false), + position_(0), + buffer_size_(block_size > 0 ? block_size : kDefaultBlockSize), + buffer_used_(0), + backup_bytes_(0) {} + +CopyingInputStreamAdaptor::~CopyingInputStreamAdaptor() { + if (owns_copying_stream_) { + delete copying_stream_; + } +} + +bool CopyingInputStreamAdaptor::Next(const void** data, int* size) { + if (failed_) { + // Already failed on a previous read. + return false; + } + + AllocateBufferIfNeeded(); + + if (backup_bytes_ > 0) { + // We have data left over from a previous BackUp(), so just return that. + *data = buffer_.get() + buffer_used_ - backup_bytes_; + *size = backup_bytes_; + backup_bytes_ = 0; + return true; + } + + // Read new data into the buffer. + buffer_used_ = copying_stream_->Read(buffer_.get(), buffer_size_); + if (buffer_used_ <= 0) { + // EOF or read error. We don't need the buffer anymore. + if (buffer_used_ < 0) { + // Read error (not EOF). + failed_ = true; + } + FreeBuffer(); + return false; + } + position_ += buffer_used_; + + *size = buffer_used_; + *data = buffer_.get(); + return true; +} + +void CopyingInputStreamAdaptor::BackUp(int count) { + GOOGLE_CHECK(backup_bytes_ == 0 && buffer_.get() != NULL) + << " BackUp() can only be called after Next()."; + GOOGLE_CHECK_LE(count, buffer_used_) + << " Can't back up over more bytes than were returned by the last call" + " to Next()."; + GOOGLE_CHECK_GE(count, 0) << " Parameter to BackUp() can't be negative."; + + backup_bytes_ = count; +} + +bool CopyingInputStreamAdaptor::Skip(int count) { + GOOGLE_CHECK_GE(count, 0); + + if (failed_) { + // Already failed on a previous read. + return false; + } + + // First skip any bytes left over from a previous BackUp(). + if (backup_bytes_ >= count) { + // We have more data left over than we're trying to skip. Just chop it. + backup_bytes_ -= count; + return true; + } + + count -= backup_bytes_; + backup_bytes_ = 0; + + int skipped = copying_stream_->Skip(count); + position_ += skipped; + return skipped == count; +} + +int64_t CopyingInputStreamAdaptor::ByteCount() const { + return position_ - backup_bytes_; +} + +void CopyingInputStreamAdaptor::AllocateBufferIfNeeded() { + if (buffer_.get() == NULL) { + buffer_.reset(new uint8_t[buffer_size_]); + } +} + +void CopyingInputStreamAdaptor::FreeBuffer() { + GOOGLE_CHECK_EQ(backup_bytes_, 0); + buffer_used_ = 0; + buffer_.reset(); +} + +// =================================================================== + +CopyingOutputStreamAdaptor::CopyingOutputStreamAdaptor( + CopyingOutputStream* copying_stream, int block_size) + : copying_stream_(copying_stream), + owns_copying_stream_(false), + failed_(false), + position_(0), + buffer_size_(block_size > 0 ? block_size : kDefaultBlockSize), + buffer_used_(0) {} + +CopyingOutputStreamAdaptor::~CopyingOutputStreamAdaptor() { + WriteBuffer(); + if (owns_copying_stream_) { + delete copying_stream_; + } +} + +bool CopyingOutputStreamAdaptor::Flush() { return WriteBuffer(); } + +bool CopyingOutputStreamAdaptor::Next(void** data, int* size) { + if (buffer_used_ == buffer_size_) { + if (!WriteBuffer()) return false; + } + + AllocateBufferIfNeeded(); + + *data = buffer_.get() + buffer_used_; + *size = buffer_size_ - buffer_used_; + buffer_used_ = buffer_size_; + return true; +} + +void CopyingOutputStreamAdaptor::BackUp(int count) { + GOOGLE_CHECK_GE(count, 0); + GOOGLE_CHECK_EQ(buffer_used_, buffer_size_) + << " BackUp() can only be called after Next()."; + GOOGLE_CHECK_LE(count, buffer_used_) + << " Can't back up over more bytes than were returned by the last call" + " to Next()."; + + buffer_used_ -= count; +} + +int64_t CopyingOutputStreamAdaptor::ByteCount() const { + return position_ + buffer_used_; +} + +bool CopyingOutputStreamAdaptor::WriteAliasedRaw(const void* data, int size) { + if (size >= buffer_size_) { + if (!Flush() || !copying_stream_->Write(data, size)) { + return false; + } + GOOGLE_DCHECK_EQ(buffer_used_, 0); + position_ += size; + return true; + } + + void* out; + int out_size; + while (true) { + if (!Next(&out, &out_size)) { + return false; + } + + if (size <= out_size) { + std::memcpy(out, data, size); + BackUp(out_size - size); + return true; + } + + std::memcpy(out, data, out_size); + data = static_cast<const char*>(data) + out_size; + size -= out_size; + } + return true; +} + + +bool CopyingOutputStreamAdaptor::WriteBuffer() { + if (failed_) { + // Already failed on a previous write. + return false; + } + + if (buffer_used_ == 0) return true; + + if (copying_stream_->Write(buffer_.get(), buffer_used_)) { + position_ += buffer_used_; + buffer_used_ = 0; + return true; + } else { + failed_ = true; + FreeBuffer(); + return false; + } +} + +void CopyingOutputStreamAdaptor::AllocateBufferIfNeeded() { + if (buffer_ == NULL) { + buffer_.reset(new uint8_t[buffer_size_]); + } +} + +void CopyingOutputStreamAdaptor::FreeBuffer() { + buffer_used_ = 0; + buffer_.reset(); +} + +// =================================================================== + +LimitingInputStream::LimitingInputStream(ZeroCopyInputStream* input, + arc_i64 limit) + : input_(input), limit_(limit) { + prior_bytes_read_ = input_->ByteCount(); +} + +LimitingInputStream::~LimitingInputStream() { + // If we overshot the limit, back up. + if (limit_ < 0) input_->BackUp(-limit_); +} + +bool LimitingInputStream::Next(const void** data, int* size) { + if (limit_ <= 0) return false; + if (!input_->Next(data, size)) return false; + + limit_ -= *size; + if (limit_ < 0) { + // We overshot the limit. Reduce *size to hide the rest of the buffer. + *size += limit_; + } + return true; +} + +void LimitingInputStream::BackUp(int count) { + if (limit_ < 0) { + input_->BackUp(count - limit_); + limit_ = count; + } else { + input_->BackUp(count); + limit_ += count; + } +} + +bool LimitingInputStream::Skip(int count) { + if (count > limit_) { + if (limit_ < 0) return false; + input_->Skip(limit_); + limit_ = 0; + return false; + } else { + if (!input_->Skip(count)) return false; + limit_ -= count; + return true; + } +} + +int64_t LimitingInputStream::ByteCount() const { + if (limit_ < 0) { + return input_->ByteCount() + limit_ - prior_bytes_read_; + } else { + return input_->ByteCount() - prior_bytes_read_; + } +} + + +// =================================================================== + +} // namespace io +} // namespace protobuf +} // namespace google diff --git a/contrib/libs/protobuf_old/src/google/protobuf/io/zero_copy_stream_impl_lite.h b/contrib/libs/protobuf_old/src/google/protobuf/io/zero_copy_stream_impl_lite.h new file mode 100644 index 0000000000..b5ccd6c2e1 --- /dev/null +++ b/contrib/libs/protobuf_old/src/google/protobuf/io/zero_copy_stream_impl_lite.h @@ -0,0 +1,408 @@ +// 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: kenton@google.com (Kenton Varda) +// Based on original Protocol Buffers design by +// Sanjay Ghemawat, Jeff Dean, and others. +// +// This file contains common implementations of the interfaces defined in +// zero_copy_stream.h which are included in the "lite" protobuf library. +// These implementations cover I/O on raw arrays and strings, as well as +// adaptors which make it easy to implement streams based on traditional +// streams. Of course, many users will probably want to write their own +// implementations of these interfaces specific to the particular I/O +// abstractions they prefer to use, but these should cover the most common +// cases. + +#ifndef GOOGLE_PROTOBUF_IO_ZERO_COPY_STREAM_IMPL_LITE_H__ +#define GOOGLE_PROTOBUF_IO_ZERO_COPY_STREAM_IMPL_LITE_H__ + + +#include <iosfwd> +#include <memory> +#include <string> + +#include <google/protobuf/stubs/callback.h> +#include <google/protobuf/stubs/common.h> +#include <google/protobuf/io/zero_copy_stream.h> +#include <google/protobuf/stubs/stl_util.h> + + +#include <google/protobuf/port_def.inc> + +namespace google { +namespace protobuf { +namespace io { + +// =================================================================== + +// A ZeroCopyInputStream backed by an in-memory array of bytes. +class PROTOBUF_EXPORT ArrayInputStream : public ZeroCopyInputStream { + public: + // Create an InputStream that returns the bytes pointed to by "data". + // "data" remains the property of the caller but must remain valid until + // the stream is destroyed. If a block_size is given, calls to Next() + // will return data blocks no larger than the given size. Otherwise, the + // first call to Next() returns the entire array. block_size is mainly + // useful for testing; in production you would probably never want to set + // it. + ArrayInputStream(const void* data, int size, int block_size = -1); + ~ArrayInputStream() override = default; + + // implements ZeroCopyInputStream ---------------------------------- + bool Next(const void** data, int* size) override; + void BackUp(int count) override; + bool Skip(int count) override; + int64_t ByteCount() const override; + + + private: + const uint8_t* const data_; // The byte array. + const int size_; // Total size of the array. + const int block_size_; // How many bytes to return at a time. + + int position_; + int last_returned_size_; // How many bytes we returned last time Next() + // was called (used for error checking only). + + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ArrayInputStream); +}; + +// =================================================================== + +// A ZeroCopyOutputStream backed by an in-memory array of bytes. +class PROTOBUF_EXPORT ArrayOutputStream : public ZeroCopyOutputStream { + public: + // Create an OutputStream that writes to the bytes pointed to by "data". + // "data" remains the property of the caller but must remain valid until + // the stream is destroyed. If a block_size is given, calls to Next() + // will return data blocks no larger than the given size. Otherwise, the + // first call to Next() returns the entire array. block_size is mainly + // useful for testing; in production you would probably never want to set + // it. + ArrayOutputStream(void* data, int size, int block_size = -1); + ~ArrayOutputStream() override = default; + + // implements ZeroCopyOutputStream --------------------------------- + bool Next(void** data, int* size) override; + void BackUp(int count) override; + int64_t ByteCount() const override; + + private: + uint8_t* const data_; // The byte array. + const int size_; // Total size of the array. + const int block_size_; // How many bytes to return at a time. + + int position_; + int last_returned_size_; // How many bytes we returned last time Next() + // was called (used for error checking only). + + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ArrayOutputStream); +}; + +// =================================================================== + +// A ZeroCopyOutputStream which appends bytes to a string. +class PROTOBUF_EXPORT StringOutputStream : public ZeroCopyOutputStream { + public: + // Create a StringOutputStream which appends bytes to the given string. + // The string remains property of the caller, but it is mutated in arbitrary + // ways and MUST NOT be accessed in any way until you're done with the + // stream. Either be sure there's no further usage, or (safest) destroy the + // stream before using the contents. + // + // Hint: If you call target->reserve(n) before creating the stream, + // the first call to Next() will return at least n bytes of buffer + // space. + explicit StringOutputStream(TProtoStringType* target); + ~StringOutputStream() override = default; + + // implements ZeroCopyOutputStream --------------------------------- + bool Next(void** data, int* size) override; + void BackUp(int count) override; + int64_t ByteCount() const override; + + private: + static constexpr size_t kMinimumSize = 16; + + TProtoStringType* target_; + + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(StringOutputStream); +}; + +// Note: There is no StringInputStream. Instead, just create an +// ArrayInputStream as follows: +// ArrayInputStream input(str.data(), str.size()); + +// =================================================================== + +// A generic traditional input stream interface. +// +// Lots of traditional input streams (e.g. file descriptors, C stdio +// streams, and C++ iostreams) expose an interface where every read +// involves copying bytes into a buffer. If you want to take such an +// interface and make a ZeroCopyInputStream based on it, simply implement +// CopyingInputStream and then use CopyingInputStreamAdaptor. +// +// CopyingInputStream implementations should avoid buffering if possible. +// CopyingInputStreamAdaptor does its own buffering and will read data +// in large blocks. +class PROTOBUF_EXPORT CopyingInputStream { + public: + virtual ~CopyingInputStream() {} + + // Reads up to "size" bytes into the given buffer. Returns the number of + // bytes read. Read() waits until at least one byte is available, or + // returns zero if no bytes will ever become available (EOF), or -1 if a + // permanent read error occurred. + virtual int Read(void* buffer, int size) = 0; + + // Skips the next "count" bytes of input. Returns the number of bytes + // actually skipped. This will always be exactly equal to "count" unless + // EOF was reached or a permanent read error occurred. + // + // The default implementation just repeatedly calls Read() into a scratch + // buffer. + virtual int Skip(int count); +}; + +// A ZeroCopyInputStream which reads from a CopyingInputStream. This is +// useful for implementing ZeroCopyInputStreams that read from traditional +// streams. Note that this class is not really zero-copy. +// +// If you want to read from file descriptors or C++ istreams, this is +// already implemented for you: use FileInputStream or IstreamInputStream +// respectively. +class PROTOBUF_EXPORT CopyingInputStreamAdaptor : public ZeroCopyInputStream { + public: + // Creates a stream that reads from the given CopyingInputStream. + // If a block_size is given, it specifies the number of bytes that + // should be read and returned with each call to Next(). Otherwise, + // a reasonable default is used. The caller retains ownership of + // copying_stream unless SetOwnsCopyingStream(true) is called. + explicit CopyingInputStreamAdaptor(CopyingInputStream* copying_stream, + int block_size = -1); + ~CopyingInputStreamAdaptor() override; + + // Call SetOwnsCopyingStream(true) to tell the CopyingInputStreamAdaptor to + // delete the underlying CopyingInputStream when it is destroyed. + void SetOwnsCopyingStream(bool value) { owns_copying_stream_ = value; } + + // implements ZeroCopyInputStream ---------------------------------- + bool Next(const void** data, int* size) override; + void BackUp(int count) override; + bool Skip(int count) override; + int64_t ByteCount() const override; + + private: + // Insures that buffer_ is not NULL. + void AllocateBufferIfNeeded(); + // Frees the buffer and resets buffer_used_. + void FreeBuffer(); + + // The underlying copying stream. + CopyingInputStream* copying_stream_; + bool owns_copying_stream_; + + // True if we have seen a permanent error from the underlying stream. + bool failed_; + + // The current position of copying_stream_, relative to the point where + // we started reading. + arc_i64 position_; + + // Data is read into this buffer. It may be NULL if no buffer is currently + // in use. Otherwise, it points to an array of size buffer_size_. + std::unique_ptr<uint8_t[]> buffer_; + const int buffer_size_; + + // Number of valid bytes currently in the buffer (i.e. the size last + // returned by Next()). 0 <= buffer_used_ <= buffer_size_. + int buffer_used_; + + // Number of bytes in the buffer which were backed up over by a call to + // BackUp(). These need to be returned again. + // 0 <= backup_bytes_ <= buffer_used_ + int backup_bytes_; + + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(CopyingInputStreamAdaptor); +}; + +// =================================================================== + +// A generic traditional output stream interface. +// +// Lots of traditional output streams (e.g. file descriptors, C stdio +// streams, and C++ iostreams) expose an interface where every write +// involves copying bytes from a buffer. If you want to take such an +// interface and make a ZeroCopyOutputStream based on it, simply implement +// CopyingOutputStream and then use CopyingOutputStreamAdaptor. +// +// CopyingOutputStream implementations should avoid buffering if possible. +// CopyingOutputStreamAdaptor does its own buffering and will write data +// in large blocks. +class PROTOBUF_EXPORT CopyingOutputStream { + public: + virtual ~CopyingOutputStream() {} + + // Writes "size" bytes from the given buffer to the output. Returns true + // if successful, false on a write error. + virtual bool Write(const void* buffer, int size) = 0; +}; + +// A ZeroCopyOutputStream which writes to a CopyingOutputStream. This is +// useful for implementing ZeroCopyOutputStreams that write to traditional +// streams. Note that this class is not really zero-copy. +// +// If you want to write to file descriptors or C++ ostreams, this is +// already implemented for you: use FileOutputStream or OstreamOutputStream +// respectively. +class PROTOBUF_EXPORT CopyingOutputStreamAdaptor : public ZeroCopyOutputStream { + public: + // Creates a stream that writes to the given Unix file descriptor. + // If a block_size is given, it specifies the size of the buffers + // that should be returned by Next(). Otherwise, a reasonable default + // is used. + explicit CopyingOutputStreamAdaptor(CopyingOutputStream* copying_stream, + int block_size = -1); + ~CopyingOutputStreamAdaptor() override; + + // Writes all pending data to the underlying stream. Returns false if a + // write error occurred on the underlying stream. (The underlying + // stream itself is not necessarily flushed.) + bool Flush(); + + // Call SetOwnsCopyingStream(true) to tell the CopyingOutputStreamAdaptor to + // delete the underlying CopyingOutputStream when it is destroyed. + void SetOwnsCopyingStream(bool value) { owns_copying_stream_ = value; } + + // implements ZeroCopyOutputStream --------------------------------- + bool Next(void** data, int* size) override; + void BackUp(int count) override; + int64_t ByteCount() const override; + bool WriteAliasedRaw(const void* data, int size) override; + bool AllowsAliasing() const override { return true; } + + private: + // Write the current buffer, if it is present. + bool WriteBuffer(); + // Insures that buffer_ is not NULL. + void AllocateBufferIfNeeded(); + // Frees the buffer. + void FreeBuffer(); + + // The underlying copying stream. + CopyingOutputStream* copying_stream_; + bool owns_copying_stream_; + + // True if we have seen a permanent error from the underlying stream. + bool failed_; + + // The current position of copying_stream_, relative to the point where + // we started writing. + arc_i64 position_; + + // Data is written from this buffer. It may be NULL if no buffer is + // currently in use. Otherwise, it points to an array of size buffer_size_. + std::unique_ptr<uint8_t[]> buffer_; + const int buffer_size_; + + // Number of valid bytes currently in the buffer (i.e. the size last + // returned by Next()). When BackUp() is called, we just reduce this. + // 0 <= buffer_used_ <= buffer_size_. + int buffer_used_; + + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(CopyingOutputStreamAdaptor); +}; + +// =================================================================== + +// A ZeroCopyInputStream which wraps some other stream and limits it to +// a particular byte count. +class PROTOBUF_EXPORT LimitingInputStream : public ZeroCopyInputStream { + public: + LimitingInputStream(ZeroCopyInputStream* input, arc_i64 limit); + ~LimitingInputStream() override; + + // implements ZeroCopyInputStream ---------------------------------- + bool Next(const void** data, int* size) override; + void BackUp(int count) override; + bool Skip(int count) override; + int64_t ByteCount() const override; + + + private: + ZeroCopyInputStream* input_; + arc_i64 limit_; // Decreases as we go, becomes negative if we overshoot. + arc_i64 prior_bytes_read_; // Bytes read on underlying stream at construction + + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(LimitingInputStream); +}; + + +// =================================================================== + +// mutable_string_data() and as_string_data() are workarounds to improve +// the performance of writing new data to an existing string. Unfortunately +// the methods provided by the string class are suboptimal, and using memcpy() +// is mildly annoying because it requires its pointer args to be non-NULL even +// if we ask it to copy 0 bytes. Furthermore, string_as_array() has the +// property that it always returns NULL if its arg is the empty string, exactly +// what we want to avoid if we're using it in conjunction with memcpy()! +// With C++11, the desired memcpy() boils down to memcpy(..., &(*s)[0], size), +// where s is a string*. Without C++11, &(*s)[0] is not guaranteed to be safe, +// so we use string_as_array(), and live with the extra logic that tests whether +// *s is empty. + +// Return a pointer to mutable characters underlying the given string. The +// return value is valid until the next time the string is resized. We +// trust the caller to treat the return value as an array of length s->size(). +inline char* mutable_string_data(TProtoStringType* s) { + // This should be simpler & faster than string_as_array() because the latter + // is guaranteed to return NULL when *s is empty, so it has to check for that. + return &(*s)[0]; +} + +// as_string_data(s) is equivalent to +// ({ char* p = mutable_string_data(s); make_pair(p, p != NULL); }) +// Sometimes it's faster: in some scenarios p cannot be NULL, and then the +// code can avoid that check. +inline std::pair<char*, bool> as_string_data(TProtoStringType* s) { + char* p = mutable_string_data(s); + return std::make_pair(p, true); +} + +} // namespace io +} // namespace protobuf +} // namespace google + +#include <google/protobuf/port_undef.inc> + +#endif // GOOGLE_PROTOBUF_IO_ZERO_COPY_STREAM_IMPL_LITE_H__ diff --git a/contrib/libs/protobuf_old/src/google/protobuf/json_util.cc b/contrib/libs/protobuf_old/src/google/protobuf/json_util.cc new file mode 100644 index 0000000000..450ce1da57 --- /dev/null +++ b/contrib/libs/protobuf_old/src/google/protobuf/json_util.cc @@ -0,0 +1,33 @@ +#include <google/protobuf/json_util.h> + +namespace google { +namespace protobuf { +namespace io { + +void PrintJSONString(IOutputStream& stream, const TProtoStringType& string) { + stream << '"'; + for (const char c: string) { + switch(c) { + case '"' : stream << "\\\""; continue; + case '\\': stream << "\\\\"; continue; + case '\b': stream << "\\b"; continue; + case '\f': stream << "\\f"; continue; + case '\n': stream << "\\n"; continue; + case '\r': stream << "\\r"; continue; + case '\t': stream << "\\t"; continue; + } + if ((unsigned char)c < 0x20) { + stream << "\\u00"; + static const char hexDigits[] = "0123456789ABCDEF"; + stream << hexDigits[(c & 0xf0) >> 4]; + stream << hexDigits[(c & 0x0f)]; + continue; + } + stream << c; + } + stream << '"'; +} + +} +} +} diff --git a/contrib/libs/protobuf_old/src/google/protobuf/json_util.h b/contrib/libs/protobuf_old/src/google/protobuf/json_util.h new file mode 100644 index 0000000000..66a77a0fae --- /dev/null +++ b/contrib/libs/protobuf_old/src/google/protobuf/json_util.h @@ -0,0 +1,30 @@ +#pragma once + +#include <google/protobuf/stubs/common.h> + +namespace google { +namespace protobuf { +namespace io { + +void PrintJSONString(IOutputStream& stream, const TProtoStringType& string); + +template<class T> +struct TAsJSON { +public: + TAsJSON(const T& t) + : T_(t) + { + } + + const T& T_; +}; + +template<class T> +inline IOutputStream& operator <<(IOutputStream& stream, const TAsJSON<T>& protoAsJSON) { + protoAsJSON.T_.PrintJSON(stream); + return stream; +} + +} +} +} diff --git a/contrib/libs/protobuf_old/src/google/protobuf/map.cc b/contrib/libs/protobuf_old/src/google/protobuf/map.cc new file mode 100644 index 0000000000..d60a9a285c --- /dev/null +++ b/contrib/libs/protobuf_old/src/google/protobuf/map.cc @@ -0,0 +1,41 @@ +// 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 <google/protobuf/map.h> + +namespace google { +namespace protobuf { +namespace internal { + +void* const kGlobalEmptyTable[kGlobalEmptyTableSize] = {nullptr}; + +} // namespace internal +} // namespace protobuf +} // namespace google diff --git a/contrib/libs/protobuf_old/src/google/protobuf/map.h b/contrib/libs/protobuf_old/src/google/protobuf/map.h new file mode 100644 index 0000000000..6b56354e4d --- /dev/null +++ b/contrib/libs/protobuf_old/src/google/protobuf/map.h @@ -0,0 +1,1378 @@ +// 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 defines the map container and its helpers to support protobuf maps. +// +// The Map and MapIterator types are provided by this header file. +// Please avoid using other types defined here, unless they are public +// types within Map or MapIterator, such as Map::value_type. + +#ifndef GOOGLE_PROTOBUF_MAP_H__ +#define GOOGLE_PROTOBUF_MAP_H__ + +#include <functional> +#include <initializer_list> +#include <iterator> +#include <limits> // To support Visual Studio 2008 +#include <map> +#include <string> +#include <type_traits> +#include <utility> + +#if defined(__cpp_lib_string_view) +#include <string_view> +#endif // defined(__cpp_lib_string_view) + +#if !defined(GOOGLE_PROTOBUF_NO_RDTSC) && defined(__APPLE__) +#define GOOGLE_PROTOBUF_NO_RDTSC 1 +//#include <mach/mach_time.h> +#endif + +#include <google/protobuf/stubs/common.h> +#include <google/protobuf/arena.h> +#include <google/protobuf/generated_enum_util.h> +#include <google/protobuf/map_type_handler.h> +#include <google/protobuf/stubs/hash.h> + +#ifdef SWIG +#error "You cannot SWIG proto headers" +#endif + +#include <google/protobuf/port_def.inc> + +namespace google { +namespace protobuf { + +template <typename Key, typename T> +class Map; + +class MapIterator; + +template <typename Enum> +struct is_proto_enum; + +namespace internal { +template <typename Derived, typename Key, typename T, + WireFormatLite::FieldType key_wire_type, + WireFormatLite::FieldType value_wire_type> +class MapFieldLite; + +template <typename Derived, typename Key, typename T, + WireFormatLite::FieldType key_wire_type, + WireFormatLite::FieldType value_wire_type> +class MapField; + +template <typename Key, typename T> +class TypeDefinedMapFieldBase; + +class DynamicMapField; + +class GeneratedMessageReflection; + +// re-implement std::allocator to use arena allocator for memory allocation. +// Used for Map implementation. Users should not use this class +// directly. +template <typename U> +class MapAllocator { + public: + using value_type = U; + using pointer = value_type*; + using const_pointer = const value_type*; + using reference = value_type&; + using const_reference = const value_type&; + using size_type = size_t; + using difference_type = ptrdiff_t; + + constexpr MapAllocator() : arena_(nullptr) {} + explicit constexpr MapAllocator(Arena* arena) : arena_(arena) {} + template <typename X> + MapAllocator(const MapAllocator<X>& allocator) // NOLINT(runtime/explicit) + : arena_(allocator.arena()) {} + + pointer allocate(size_type n, const void* /* hint */ = nullptr) { + // If arena is not given, malloc needs to be called which doesn't + // construct element object. + if (arena_ == nullptr) { + return static_cast<pointer>(::operator new(n * sizeof(value_type))); + } else { + return reinterpret_cast<pointer>( + Arena::CreateArray<uint8_t>(arena_, n * sizeof(value_type))); + } + } + + void deallocate(pointer p, size_type n) { + if (arena_ == nullptr) { +#if defined(__GXX_DELETE_WITH_SIZE__) || defined(__cpp_sized_deallocation) + ::operator delete(p, n * sizeof(value_type)); +#else + (void)n; + ::operator delete(p); +#endif + } + } + +#if !defined(GOOGLE_PROTOBUF_OS_APPLE) && !defined(GOOGLE_PROTOBUF_OS_NACL) && \ + !defined(GOOGLE_PROTOBUF_OS_EMSCRIPTEN) + template <class NodeType, class... Args> + void construct(NodeType* p, Args&&... args) { + // Clang 3.6 doesn't compile static casting to void* directly. (Issue + // #1266) According C++ standard 5.2.9/1: "The static_cast operator shall + // not cast away constness". So first the maybe const pointer is casted to + // const void* and after the const void* is const casted. + new (const_cast<void*>(static_cast<const void*>(p))) + NodeType(std::forward<Args>(args)...); + } + + template <class NodeType> + void destroy(NodeType* p) { + p->~NodeType(); + } +#else + void construct(pointer p, const_reference t) { new (p) value_type(t); } + + void destroy(pointer p) { p->~value_type(); } +#endif + + template <typename X> + struct rebind { + using other = MapAllocator<X>; + }; + + template <typename X> + bool operator==(const MapAllocator<X>& other) const { + return arena_ == other.arena_; + } + + template <typename X> + bool operator!=(const MapAllocator<X>& other) const { + return arena_ != other.arena_; + } + + // To support Visual Studio 2008 + size_type max_size() const { + // parentheses around (std::...:max) prevents macro warning of max() + return (std::numeric_limits<size_type>::max)(); + } + + // To support gcc-4.4, which does not properly + // support templated friend classes + Arena* arena() const { return arena_; } + + private: + using DestructorSkippable_ = void; + Arena* arena_; +}; + +template <typename T> +using KeyForTree = + typename std::conditional<std::is_scalar<T>::value, T, + std::reference_wrapper<const T>>::type; + +// Default case: Not transparent. +// We use std::hash<key_type>/std::less<key_type> and all the lookup functions +// only accept `key_type`. +template <typename key_type> +struct TransparentSupport { + using hash = std::hash<key_type>; + using less = std::less<key_type>; + + static bool Equals(const key_type& a, const key_type& b) { return a == b; } + + template <typename K> + using key_arg = key_type; +}; + +#if defined(__cpp_lib_string_view) +// If std::string_view is available, we add transparent support for TProtoStringType +// keys. We use std::hash<std::string_view> as it supports the input types we +// care about. The lookup functions accept arbitrary `K`. This will include any +// key type that is convertible to std::string_view. +template <> +struct TransparentSupport<TProtoStringType> { + static std::string_view ImplicitConvert(std::string_view str) { return str; } + // If the element is not convertible to std::string_view, try to convert to + // TProtoStringType first. + // The template makes this overload lose resolution when both have the same + // rank otherwise. + template <typename = void> + static std::string_view ImplicitConvert(const TProtoStringType& str) { + return str; + } + + struct hash : private std::hash<std::string_view> { + using is_transparent = void; + + template <typename T> + size_t operator()(const T& str) const { + return base()(ImplicitConvert(str)); + } + + private: + const std::hash<std::string_view>& base() const { return *this; } + }; + struct less { + using is_transparent = void; + + template <typename T, typename U> + bool operator()(const T& t, const U& u) const { + return ImplicitConvert(t) < ImplicitConvert(u); + } + }; + + template <typename T, typename U> + static bool Equals(const T& t, const U& u) { + return ImplicitConvert(t) == ImplicitConvert(u); + } + + template <typename K> + using key_arg = K; +}; +#endif // defined(__cpp_lib_string_view) + +template <typename Key> +using TreeForMap = + std::map<KeyForTree<Key>, void*, typename TransparentSupport<Key>::less, + MapAllocator<std::pair<const KeyForTree<Key>, void*>>>; + +inline bool TableEntryIsEmpty(void* const* table, size_t b) { + return table[b] == nullptr; +} +inline bool TableEntryIsNonEmptyList(void* const* table, size_t b) { + return table[b] != nullptr && table[b] != table[b ^ 1]; +} +inline bool TableEntryIsTree(void* const* table, size_t b) { + return !TableEntryIsEmpty(table, b) && !TableEntryIsNonEmptyList(table, b); +} +inline bool TableEntryIsList(void* const* table, size_t b) { + return !TableEntryIsTree(table, b); +} + +// This captures all numeric types. +inline size_t MapValueSpaceUsedExcludingSelfLong(bool) { return 0; } +inline size_t MapValueSpaceUsedExcludingSelfLong(const TProtoStringType& str) { + return StringSpaceUsedExcludingSelfLong(str); +} +template <typename T, + typename = decltype(std::declval<const T&>().SpaceUsedLong())> +size_t MapValueSpaceUsedExcludingSelfLong(const T& message) { + return message.SpaceUsedLong() - sizeof(T); +} + +constexpr size_t kGlobalEmptyTableSize = 1; +PROTOBUF_EXPORT extern void* const kGlobalEmptyTable[kGlobalEmptyTableSize]; + +// Space used for the table, trees, and nodes. +// Does not include the indirect space used. Eg the data of a TProtoStringType. +template <typename Key> +PROTOBUF_NOINLINE size_t SpaceUsedInTable(void** table, size_t num_buckets, + size_t num_elements, + size_t sizeof_node) { + size_t size = 0; + // The size of the table. + size += sizeof(void*) * num_buckets; + // All the nodes. + size += sizeof_node * num_elements; + // For each tree, count the overhead of the those nodes. + // Two buckets at a time because we only care about trees. + for (size_t b = 0; b < num_buckets; b += 2) { + if (internal::TableEntryIsTree(table, b)) { + using Tree = TreeForMap<Key>; + Tree* tree = static_cast<Tree*>(table[b]); + // Estimated cost of the red-black tree nodes, 3 pointers plus a + // bool (plus alignment, so 4 pointers). + size += tree->size() * + (sizeof(typename Tree::value_type) + sizeof(void*) * 4); + } + } + return size; +} + +template <typename Map, + typename = typename std::enable_if< + !std::is_scalar<typename Map::key_type>::value || + !std::is_scalar<typename Map::mapped_type>::value>::type> +size_t SpaceUsedInValues(const Map* map) { + size_t size = 0; + for (const auto& v : *map) { + size += internal::MapValueSpaceUsedExcludingSelfLong(v.first) + + internal::MapValueSpaceUsedExcludingSelfLong(v.second); + } + return size; +} + +inline size_t SpaceUsedInValues(const void*) { return 0; } + +} // namespace internal + +// This is the class for Map's internal value_type. Instead of using +// std::pair as value_type, we use this class which provides us more control of +// its process of construction and destruction. +template <typename Key, typename T> +struct MapPair { + using first_type = const Key; + using second_type = T; + + MapPair(const Key& other_first, const T& other_second) + : first(other_first), second(other_second) {} + explicit MapPair(const Key& other_first) : first(other_first), second() {} + explicit MapPair(Key&& other_first) + : first(std::move(other_first)), second() {} + MapPair(const MapPair& other) : first(other.first), second(other.second) {} + + ~MapPair() {} + + // Implicitly convertible to std::pair of compatible types. + template <typename T1, typename T2> + operator std::pair<T1, T2>() const { // NOLINT(runtime/explicit) + return std::pair<T1, T2>(first, second); + } + + const Key first; + T second; + + private: + friend class Arena; + friend class Map<Key, T>; +}; + +// Map is an associative container type used to store protobuf map +// fields. Each Map instance may or may not use a different hash function, a +// different iteration order, and so on. E.g., please don't examine +// implementation details to decide if the following would work: +// Map<int, int> m0, m1; +// m0[0] = m1[0] = m0[1] = m1[1] = 0; +// assert(m0.begin()->first == m1.begin()->first); // Bug! +// +// Map's interface is similar to std::unordered_map, except that Map is not +// designed to play well with exceptions. +template <typename Key, typename T> +class Map { + public: + using key_type = Key; + using mapped_type = T; + using value_type = MapPair<Key, T>; + + using pointer = value_type*; + using const_pointer = const value_type*; + using reference = value_type&; + using const_reference = const value_type&; + + using size_type = size_t; + using hasher = typename internal::TransparentSupport<Key>::hash; + + constexpr Map() : elements_(nullptr) {} + explicit Map(Arena* arena) : elements_(arena) {} + + Map(const Map& other) : Map() { insert(other.begin(), other.end()); } + + Map(Map&& other) noexcept : Map() { + if (other.arena() != nullptr) { + *this = other; + } else { + swap(other); + } + } + + Map& operator=(Map&& other) noexcept { + if (this != &other) { + if (arena() != other.arena()) { + *this = other; + } else { + swap(other); + } + } + return *this; + } + + template <class InputIt> + Map(const InputIt& first, const InputIt& last) : Map() { + insert(first, last); + } + + ~Map() {} + + private: + using Allocator = internal::MapAllocator<void*>; + + // InnerMap is a generic hash-based map. It doesn't contain any + // protocol-buffer-specific logic. It is a chaining hash map with the + // additional feature that some buckets can be converted to use an ordered + // container. This ensures O(lg n) bounds on find, insert, and erase, while + // avoiding the overheads of ordered containers most of the time. + // + // The implementation doesn't need the full generality of unordered_map, + // and it doesn't have it. More bells and whistles can be added as needed. + // Some implementation details: + // 1. The hash function has type hasher and the equality function + // equal_to<Key>. We inherit from hasher to save space + // (empty-base-class optimization). + // 2. The number of buckets is a power of two. + // 3. Buckets are converted to trees in pairs: if we convert bucket b then + // buckets b and b^1 will share a tree. Invariant: buckets b and b^1 have + // the same non-null value iff they are sharing a tree. (An alternative + // implementation strategy would be to have a tag bit per bucket.) + // 4. As is typical for hash_map and such, the Keys and Values are always + // stored in linked list nodes. Pointers to elements are never invalidated + // until the element is deleted. + // 5. The trees' payload type is pointer to linked-list node. Tree-converting + // a bucket doesn't copy Key-Value pairs. + // 6. Once we've tree-converted a bucket, it is never converted back. However, + // the items a tree contains may wind up assigned to trees or lists upon a + // rehash. + // 7. The code requires no C++ features from C++14 or later. + // 8. Mutations to a map do not invalidate the map's iterators, pointers to + // elements, or references to elements. + // 9. Except for erase(iterator), any non-const method can reorder iterators. + // 10. InnerMap uses KeyForTree<Key> when using the Tree representation, which + // is either `Key`, if Key is a scalar, or `reference_wrapper<const Key>` + // otherwise. This avoids unnecessary copies of string keys, for example. + class InnerMap : private hasher { + public: + explicit constexpr InnerMap(Arena* arena) + : hasher(), + num_elements_(0), + num_buckets_(internal::kGlobalEmptyTableSize), + seed_(0), + index_of_first_non_null_(internal::kGlobalEmptyTableSize), + table_(const_cast<void**>(internal::kGlobalEmptyTable)), + alloc_(arena) {} + + ~InnerMap() { + if (alloc_.arena() == nullptr && + num_buckets_ != internal::kGlobalEmptyTableSize) { + clear(); + Dealloc<void*>(table_, num_buckets_); + } + } + + private: + enum { kMinTableSize = 8 }; + + // Linked-list nodes, as one would expect for a chaining hash table. + struct Node { + value_type kv; + Node* next; + }; + + // Trees. The payload type is a copy of Key, so that we can query the tree + // with Keys that are not in any particular data structure. + // The value is a void* pointing to Node. We use void* instead of Node* to + // avoid code bloat. That way there is only one instantiation of the tree + // class per key type. + using Tree = internal::TreeForMap<Key>; + using TreeIterator = typename Tree::iterator; + + static Node* NodeFromTreeIterator(TreeIterator it) { + return static_cast<Node*>(it->second); + } + + // iterator and const_iterator are instantiations of iterator_base. + template <typename KeyValueType> + class iterator_base { + public: + using reference = KeyValueType&; + using pointer = KeyValueType*; + + // Invariants: + // node_ is always correct. This is handy because the most common + // operations are operator* and operator-> and they only use node_. + // When node_ is set to a non-null value, all the other non-const fields + // are updated to be correct also, but those fields can become stale + // if the underlying map is modified. When those fields are needed they + // are rechecked, and updated if necessary. + iterator_base() : node_(nullptr), m_(nullptr), bucket_index_(0) {} + + explicit iterator_base(const InnerMap* m) : m_(m) { + SearchFrom(m->index_of_first_non_null_); + } + + // Any iterator_base can convert to any other. This is overkill, and we + // rely on the enclosing class to use it wisely. The standard "iterator + // can convert to const_iterator" is OK but the reverse direction is not. + template <typename U> + explicit iterator_base(const iterator_base<U>& it) + : node_(it.node_), m_(it.m_), bucket_index_(it.bucket_index_) {} + + iterator_base(Node* n, const InnerMap* m, size_type index) + : node_(n), m_(m), bucket_index_(index) {} + + iterator_base(TreeIterator tree_it, const InnerMap* m, size_type index) + : node_(NodeFromTreeIterator(tree_it)), m_(m), bucket_index_(index) { + // Invariant: iterators that use buckets with trees have an even + // bucket_index_. + GOOGLE_DCHECK_EQ(bucket_index_ % 2, 0u); + } + + // Advance through buckets, looking for the first that isn't empty. + // If nothing non-empty is found then leave node_ == nullptr. + void SearchFrom(size_type start_bucket) { + GOOGLE_DCHECK(m_->index_of_first_non_null_ == m_->num_buckets_ || + m_->table_[m_->index_of_first_non_null_] != nullptr); + node_ = nullptr; + for (bucket_index_ = start_bucket; bucket_index_ < m_->num_buckets_; + bucket_index_++) { + if (m_->TableEntryIsNonEmptyList(bucket_index_)) { + node_ = static_cast<Node*>(m_->table_[bucket_index_]); + break; + } else if (m_->TableEntryIsTree(bucket_index_)) { + Tree* tree = static_cast<Tree*>(m_->table_[bucket_index_]); + GOOGLE_DCHECK(!tree->empty()); + node_ = NodeFromTreeIterator(tree->begin()); + break; + } + } + } + + reference operator*() const { return node_->kv; } + pointer operator->() const { return &(operator*()); } + + friend bool operator==(const iterator_base& a, const iterator_base& b) { + return a.node_ == b.node_; + } + friend bool operator!=(const iterator_base& a, const iterator_base& b) { + return a.node_ != b.node_; + } + + iterator_base& operator++() { + if (node_->next == nullptr) { + TreeIterator tree_it; + const bool is_list = revalidate_if_necessary(&tree_it); + if (is_list) { + SearchFrom(bucket_index_ + 1); + } else { + GOOGLE_DCHECK_EQ(bucket_index_ & 1, 0u); + Tree* tree = static_cast<Tree*>(m_->table_[bucket_index_]); + if (++tree_it == tree->end()) { + SearchFrom(bucket_index_ + 2); + } else { + node_ = NodeFromTreeIterator(tree_it); + } + } + } else { + node_ = node_->next; + } + return *this; + } + + iterator_base operator++(int /* unused */) { + iterator_base tmp = *this; + ++*this; + return tmp; + } + + // Assumes node_ and m_ are correct and non-null, but other fields may be + // stale. Fix them as needed. Then return true iff node_ points to a + // Node in a list. If false is returned then *it is modified to be + // a valid iterator for node_. + bool revalidate_if_necessary(TreeIterator* it) { + GOOGLE_DCHECK(node_ != nullptr && m_ != nullptr); + // Force bucket_index_ to be in range. + bucket_index_ &= (m_->num_buckets_ - 1); + // Common case: the bucket we think is relevant points to node_. + if (m_->table_[bucket_index_] == static_cast<void*>(node_)) return true; + // Less common: the bucket is a linked list with node_ somewhere in it, + // but not at the head. + if (m_->TableEntryIsNonEmptyList(bucket_index_)) { + Node* l = static_cast<Node*>(m_->table_[bucket_index_]); + while ((l = l->next) != nullptr) { + if (l == node_) { + return true; + } + } + } + // Well, bucket_index_ still might be correct, but probably + // not. Revalidate just to be sure. This case is rare enough that we + // don't worry about potential optimizations, such as having a custom + // find-like method that compares Node* instead of the key. + iterator_base i(m_->find(node_->kv.first, it)); + bucket_index_ = i.bucket_index_; + return m_->TableEntryIsList(bucket_index_); + } + + Node* node_; + const InnerMap* m_; + size_type bucket_index_; + }; + + public: + using iterator = iterator_base<value_type>; + using const_iterator = iterator_base<const value_type>; + + Arena* arena() const { return alloc_.arena(); } + + void Swap(InnerMap* other) { + std::swap(num_elements_, other->num_elements_); + std::swap(num_buckets_, other->num_buckets_); + std::swap(seed_, other->seed_); + std::swap(index_of_first_non_null_, other->index_of_first_non_null_); + std::swap(table_, other->table_); + std::swap(alloc_, other->alloc_); + } + + iterator begin() { return iterator(this); } + iterator end() { return iterator(); } + const_iterator begin() const { return const_iterator(this); } + const_iterator end() const { return const_iterator(); } + + void clear() { + for (size_type b = 0; b < num_buckets_; b++) { + if (TableEntryIsNonEmptyList(b)) { + Node* node = static_cast<Node*>(table_[b]); + table_[b] = nullptr; + do { + Node* next = node->next; + DestroyNode(node); + node = next; + } while (node != nullptr); + } else if (TableEntryIsTree(b)) { + Tree* tree = static_cast<Tree*>(table_[b]); + GOOGLE_DCHECK(table_[b] == table_[b + 1] && (b & 1) == 0); + table_[b] = table_[b + 1] = nullptr; + typename Tree::iterator tree_it = tree->begin(); + do { + Node* node = NodeFromTreeIterator(tree_it); + typename Tree::iterator next = tree_it; + ++next; + tree->erase(tree_it); + DestroyNode(node); + tree_it = next; + } while (tree_it != tree->end()); + DestroyTree(tree); + b++; + } + } + num_elements_ = 0; + index_of_first_non_null_ = num_buckets_; + } + + const hasher& hash_function() const { return *this; } + + static size_type max_size() { + return static_cast<size_type>(1) << (sizeof(void**) >= 8 ? 60 : 28); + } + size_type size() const { return num_elements_; } + bool empty() const { return size() == 0; } + + template <typename K> + iterator find(const K& k) { + return iterator(FindHelper(k).first); + } + + template <typename K> + const_iterator find(const K& k) const { + return FindHelper(k).first; + } + + // Insert the key into the map, if not present. In that case, the value will + // be value initialized. + template <typename K> + std::pair<iterator, bool> insert(K&& k) { + std::pair<const_iterator, size_type> p = FindHelper(k); + // Case 1: key was already present. + if (p.first.node_ != nullptr) + return std::make_pair(iterator(p.first), false); + // Case 2: insert. + if (ResizeIfLoadIsOutOfRange(num_elements_ + 1)) { + p = FindHelper(k); + } + const size_type b = p.second; // bucket number + // If K is not key_type, make the conversion to key_type explicit. + using TypeToInit = typename std::conditional< + std::is_same<typename std::decay<K>::type, key_type>::value, K&&, + key_type>::type; + Node* node = Alloc<Node>(1); + // Even when arena is nullptr, CreateInArenaStorage is still used to + // ensure the arena of submessage will be consistent. Otherwise, + // submessage may have its own arena when message-owned arena is enabled. + Arena::CreateInArenaStorage(const_cast<Key*>(&node->kv.first), + alloc_.arena(), + static_cast<TypeToInit>(std::forward<K>(k))); + Arena::CreateInArenaStorage(&node->kv.second, alloc_.arena()); + + iterator result = InsertUnique(b, node); + ++num_elements_; + return std::make_pair(result, true); + } + + template <typename K> + value_type& operator[](K&& k) { + return *insert(std::forward<K>(k)).first; + } + + void erase(iterator it) { + GOOGLE_DCHECK_EQ(it.m_, this); + typename Tree::iterator tree_it; + const bool is_list = it.revalidate_if_necessary(&tree_it); + size_type b = it.bucket_index_; + Node* const item = it.node_; + if (is_list) { + GOOGLE_DCHECK(TableEntryIsNonEmptyList(b)); + Node* head = static_cast<Node*>(table_[b]); + head = EraseFromLinkedList(item, head); + table_[b] = static_cast<void*>(head); + } else { + GOOGLE_DCHECK(TableEntryIsTree(b)); + Tree* tree = static_cast<Tree*>(table_[b]); + tree->erase(tree_it); + if (tree->empty()) { + // Force b to be the minimum of b and b ^ 1. This is important + // only because we want index_of_first_non_null_ to be correct. + b &= ~static_cast<size_type>(1); + DestroyTree(tree); + table_[b] = table_[b + 1] = nullptr; + } + } + DestroyNode(item); + --num_elements_; + if (PROTOBUF_PREDICT_FALSE(b == index_of_first_non_null_)) { + while (index_of_first_non_null_ < num_buckets_ && + table_[index_of_first_non_null_] == nullptr) { + ++index_of_first_non_null_; + } + } + } + + size_t SpaceUsedInternal() const { + return internal::SpaceUsedInTable<Key>(table_, num_buckets_, + num_elements_, sizeof(Node)); + } + + private: + const_iterator find(const Key& k, TreeIterator* it) const { + return FindHelper(k, it).first; + } + template <typename K> + std::pair<const_iterator, size_type> FindHelper(const K& k) const { + return FindHelper(k, nullptr); + } + template <typename K> + std::pair<const_iterator, size_type> FindHelper(const K& k, + TreeIterator* it) const { + size_type b = BucketNumber(k); + if (TableEntryIsNonEmptyList(b)) { + Node* node = static_cast<Node*>(table_[b]); + do { + if (internal::TransparentSupport<Key>::Equals(node->kv.first, k)) { + return std::make_pair(const_iterator(node, this, b), b); + } else { + node = node->next; + } + } while (node != nullptr); + } else if (TableEntryIsTree(b)) { + GOOGLE_DCHECK_EQ(table_[b], table_[b ^ 1]); + b &= ~static_cast<size_t>(1); + Tree* tree = static_cast<Tree*>(table_[b]); + auto tree_it = tree->find(k); + if (tree_it != tree->end()) { + if (it != nullptr) *it = tree_it; + return std::make_pair(const_iterator(tree_it, this, b), b); + } + } + return std::make_pair(end(), b); + } + + // Insert the given Node in bucket b. If that would make bucket b too big, + // and bucket b is not a tree, create a tree for buckets b and b^1 to share. + // Requires count(*KeyPtrFromNodePtr(node)) == 0 and that b is the correct + // bucket. num_elements_ is not modified. + iterator InsertUnique(size_type b, Node* node) { + GOOGLE_DCHECK(index_of_first_non_null_ == num_buckets_ || + table_[index_of_first_non_null_] != nullptr); + // In practice, the code that led to this point may have already + // determined whether we are inserting into an empty list, a short list, + // or whatever. But it's probably cheap enough to recompute that here; + // it's likely that we're inserting into an empty or short list. + iterator result; + GOOGLE_DCHECK(find(node->kv.first) == end()); + if (TableEntryIsEmpty(b)) { + result = InsertUniqueInList(b, node); + } else if (TableEntryIsNonEmptyList(b)) { + if (PROTOBUF_PREDICT_FALSE(TableEntryIsTooLong(b))) { + TreeConvert(b); + result = InsertUniqueInTree(b, node); + GOOGLE_DCHECK_EQ(result.bucket_index_, b & ~static_cast<size_type>(1)); + } else { + // Insert into a pre-existing list. This case cannot modify + // index_of_first_non_null_, so we skip the code to update it. + return InsertUniqueInList(b, node); + } + } else { + // Insert into a pre-existing tree. This case cannot modify + // index_of_first_non_null_, so we skip the code to update it. + return InsertUniqueInTree(b, node); + } + // parentheses around (std::min) prevents macro expansion of min(...) + index_of_first_non_null_ = + (std::min)(index_of_first_non_null_, result.bucket_index_); + return result; + } + + // Returns whether we should insert after the head of the list. For + // non-optimized builds, we randomly decide whether to insert right at the + // head of the list or just after the head. This helps add a little bit of + // non-determinism to the map ordering. + bool ShouldInsertAfterHead(void* node) { +#ifdef NDEBUG + (void)node; + return false; +#else + // Doing modulo with a prime mixes the bits more. + return (reinterpret_cast<uintptr_t>(node) ^ seed_) % 13 > 6; +#endif + } + + // Helper for InsertUnique. Handles the case where bucket b is a + // not-too-long linked list. + iterator InsertUniqueInList(size_type b, Node* node) { + if (table_[b] != nullptr && ShouldInsertAfterHead(node)) { + Node* first = static_cast<Node*>(table_[b]); + node->next = first->next; + first->next = node; + return iterator(node, this, b); + } + + node->next = static_cast<Node*>(table_[b]); + table_[b] = static_cast<void*>(node); + return iterator(node, this, b); + } + + // Helper for InsertUnique. Handles the case where bucket b points to a + // Tree. + iterator InsertUniqueInTree(size_type b, Node* node) { + GOOGLE_DCHECK_EQ(table_[b], table_[b ^ 1]); + // Maintain the invariant that node->next is null for all Nodes in Trees. + node->next = nullptr; + return iterator( + static_cast<Tree*>(table_[b])->insert({node->kv.first, node}).first, + this, b & ~static_cast<size_t>(1)); + } + + // Returns whether it did resize. Currently this is only used when + // num_elements_ increases, though it could be used in other situations. + // It checks for load too low as well as load too high: because any number + // of erases can occur between inserts, the load could be as low as 0 here. + // Resizing to a lower size is not always helpful, but failing to do so can + // destroy the expected big-O bounds for some operations. By having the + // policy that sometimes we resize down as well as up, clients can easily + // keep O(size()) = O(number of buckets) if they want that. + bool ResizeIfLoadIsOutOfRange(size_type new_size) { + const size_type kMaxMapLoadTimes16 = 12; // controls RAM vs CPU tradeoff + const size_type hi_cutoff = num_buckets_ * kMaxMapLoadTimes16 / 16; + const size_type lo_cutoff = hi_cutoff / 4; + // We don't care how many elements are in trees. If a lot are, + // we may resize even though there are many empty buckets. In + // practice, this seems fine. + if (PROTOBUF_PREDICT_FALSE(new_size >= hi_cutoff)) { + if (num_buckets_ <= max_size() / 2) { + Resize(num_buckets_ * 2); + return true; + } + } else if (PROTOBUF_PREDICT_FALSE(new_size <= lo_cutoff && + num_buckets_ > kMinTableSize)) { + size_type lg2_of_size_reduction_factor = 1; + // It's possible we want to shrink a lot here... size() could even be 0. + // So, estimate how much to shrink by making sure we don't shrink so + // much that we would need to grow the table after a few inserts. + const size_type hypothetical_size = new_size * 5 / 4 + 1; + while ((hypothetical_size << lg2_of_size_reduction_factor) < + hi_cutoff) { + ++lg2_of_size_reduction_factor; + } + size_type new_num_buckets = std::max<size_type>( + kMinTableSize, num_buckets_ >> lg2_of_size_reduction_factor); + if (new_num_buckets != num_buckets_) { + Resize(new_num_buckets); + return true; + } + } + return false; + } + + // Resize to the given number of buckets. + void Resize(size_t new_num_buckets) { + if (num_buckets_ == internal::kGlobalEmptyTableSize) { + // This is the global empty array. + // Just overwrite with a new one. No need to transfer or free anything. + num_buckets_ = index_of_first_non_null_ = kMinTableSize; + table_ = CreateEmptyTable(num_buckets_); + seed_ = Seed(); + return; + } + + GOOGLE_DCHECK_GE(new_num_buckets, kMinTableSize); + void** const old_table = table_; + const size_type old_table_size = num_buckets_; + num_buckets_ = new_num_buckets; + table_ = CreateEmptyTable(num_buckets_); + const size_type start = index_of_first_non_null_; + index_of_first_non_null_ = num_buckets_; + for (size_type i = start; i < old_table_size; i++) { + if (internal::TableEntryIsNonEmptyList(old_table, i)) { + TransferList(old_table, i); + } else if (internal::TableEntryIsTree(old_table, i)) { + TransferTree(old_table, i++); + } + } + Dealloc<void*>(old_table, old_table_size); + } + + void TransferList(void* const* table, size_type index) { + Node* node = static_cast<Node*>(table[index]); + do { + Node* next = node->next; + InsertUnique(BucketNumber(node->kv.first), node); + node = next; + } while (node != nullptr); + } + + void TransferTree(void* const* table, size_type index) { + Tree* tree = static_cast<Tree*>(table[index]); + typename Tree::iterator tree_it = tree->begin(); + do { + InsertUnique(BucketNumber(std::cref(tree_it->first).get()), + NodeFromTreeIterator(tree_it)); + } while (++tree_it != tree->end()); + DestroyTree(tree); + } + + Node* EraseFromLinkedList(Node* item, Node* head) { + if (head == item) { + return head->next; + } else { + head->next = EraseFromLinkedList(item, head->next); + return head; + } + } + + bool TableEntryIsEmpty(size_type b) const { + return internal::TableEntryIsEmpty(table_, b); + } + bool TableEntryIsNonEmptyList(size_type b) const { + return internal::TableEntryIsNonEmptyList(table_, b); + } + bool TableEntryIsTree(size_type b) const { + return internal::TableEntryIsTree(table_, b); + } + bool TableEntryIsList(size_type b) const { + return internal::TableEntryIsList(table_, b); + } + + void TreeConvert(size_type b) { + GOOGLE_DCHECK(!TableEntryIsTree(b) && !TableEntryIsTree(b ^ 1)); + Tree* tree = + Arena::Create<Tree>(alloc_.arena(), typename Tree::key_compare(), + typename Tree::allocator_type(alloc_)); + size_type count = CopyListToTree(b, tree) + CopyListToTree(b ^ 1, tree); + GOOGLE_DCHECK_EQ(count, tree->size()); + table_[b] = table_[b ^ 1] = static_cast<void*>(tree); + } + + // Copy a linked list in the given bucket to a tree. + // Returns the number of things it copied. + size_type CopyListToTree(size_type b, Tree* tree) { + size_type count = 0; + Node* node = static_cast<Node*>(table_[b]); + while (node != nullptr) { + tree->insert({node->kv.first, node}); + ++count; + Node* next = node->next; + node->next = nullptr; + node = next; + } + return count; + } + + // Return whether table_[b] is a linked list that seems awfully long. + // Requires table_[b] to point to a non-empty linked list. + bool TableEntryIsTooLong(size_type b) { + const size_type kMaxLength = 8; + size_type count = 0; + Node* node = static_cast<Node*>(table_[b]); + do { + ++count; + node = node->next; + } while (node != nullptr); + // Invariant: no linked list ever is more than kMaxLength in length. + GOOGLE_DCHECK_LE(count, kMaxLength); + return count >= kMaxLength; + } + + template <typename K> + size_type BucketNumber(const K& k) const { + // We xor the hash value against the random seed so that we effectively + // have a random hash function. + arc_ui64 h = hash_function()(k) ^ seed_; + + // We use the multiplication method to determine the bucket number from + // the hash value. The constant kPhi (suggested by Knuth) is roughly + // (sqrt(5) - 1) / 2 * 2^64. + constexpr arc_ui64 kPhi = arc_ui64{0x9e3779b97f4a7c15}; + return ((kPhi * h) >> 32) & (num_buckets_ - 1); + } + + // Return a power of two no less than max(kMinTableSize, n). + // Assumes either n < kMinTableSize or n is a power of two. + size_type TableSize(size_type n) { + return n < static_cast<size_type>(kMinTableSize) + ? static_cast<size_type>(kMinTableSize) + : n; + } + + // Use alloc_ to allocate an array of n objects of type U. + template <typename U> + U* Alloc(size_type n) { + using alloc_type = typename Allocator::template rebind<U>::other; + return alloc_type(alloc_).allocate(n); + } + + // Use alloc_ to deallocate an array of n objects of type U. + template <typename U> + void Dealloc(U* t, size_type n) { + using alloc_type = typename Allocator::template rebind<U>::other; + alloc_type(alloc_).deallocate(t, n); + } + + void DestroyNode(Node* node) { + if (alloc_.arena() == nullptr) { + delete node; + } + } + + void DestroyTree(Tree* tree) { + if (alloc_.arena() == nullptr) { + delete tree; + } + } + + void** CreateEmptyTable(size_type n) { + GOOGLE_DCHECK(n >= kMinTableSize); + GOOGLE_DCHECK_EQ(n & (n - 1), 0u); + void** result = Alloc<void*>(n); + memset(result, 0, n * sizeof(result[0])); + return result; + } + + // Return a randomish value. + size_type Seed() const { + // We get a little bit of randomness from the address of the map. The + // lower bits are not very random, due to alignment, so we discard them + // and shift the higher bits into their place. + size_type s = reinterpret_cast<uintptr_t>(this) >> 4; +#if !defined(GOOGLE_PROTOBUF_NO_RDTSC) +#if defined(__APPLE__) + // Use a commpage-based fast time function on Apple environments (MacOS, + // iOS, tvOS, watchOS, etc). + s += mach_absolute_time(); +#elif defined(__x86_64__) && defined(__GNUC__) + arc_ui32 hi, lo; + asm volatile("rdtsc" : "=a"(lo), "=d"(hi)); + s += ((static_cast<arc_ui64>(hi) << 32) | lo); +#elif defined(__aarch64__) && defined(__GNUC__) + // There is no rdtsc on ARMv8. CNTVCT_EL0 is the virtual counter of the + // system timer. It runs at a different frequency than the CPU's, but is + // the best source of time-based entropy we get. + arc_ui64 virtual_timer_value; + asm volatile("mrs %0, cntvct_el0" : "=r"(virtual_timer_value)); + s += virtual_timer_value; +#endif +#endif // !defined(GOOGLE_PROTOBUF_NO_RDTSC) + return s; + } + + friend class Arena; + using InternalArenaConstructable_ = void; + using DestructorSkippable_ = void; + + size_type num_elements_; + size_type num_buckets_; + size_type seed_; + size_type index_of_first_non_null_; + void** table_; // an array with num_buckets_ entries + Allocator alloc_; + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(InnerMap); + }; // end of class InnerMap + + template <typename LookupKey> + using key_arg = typename internal::TransparentSupport< + key_type>::template key_arg<LookupKey>; + + public: + // Iterators + class const_iterator { + using InnerIt = typename InnerMap::const_iterator; + + public: + using iterator_category = std::forward_iterator_tag; + using value_type = typename Map::value_type; + using difference_type = ptrdiff_t; + using pointer = const value_type*; + using reference = const value_type&; + + const_iterator() {} + explicit const_iterator(const InnerIt& it) : it_(it) {} + + const_reference operator*() const { return *it_; } + const_pointer operator->() const { return &(operator*()); } + + const_iterator& operator++() { + ++it_; + return *this; + } + const_iterator operator++(int) { return const_iterator(it_++); } + + friend bool operator==(const const_iterator& a, const const_iterator& b) { + return a.it_ == b.it_; + } + friend bool operator!=(const const_iterator& a, const const_iterator& b) { + return !(a == b); + } + + private: + InnerIt it_; + }; + + class iterator { + using InnerIt = typename InnerMap::iterator; + + public: + using iterator_category = std::forward_iterator_tag; + using value_type = typename Map::value_type; + using difference_type = ptrdiff_t; + using pointer = value_type*; + using reference = value_type&; + + iterator() {} + explicit iterator(const InnerIt& it) : it_(it) {} + + reference operator*() const { return *it_; } + pointer operator->() const { return &(operator*()); } + + iterator& operator++() { + ++it_; + return *this; + } + iterator operator++(int) { return iterator(it_++); } + + // Allow implicit conversion to const_iterator. + operator const_iterator() const { // NOLINT(runtime/explicit) + return const_iterator(typename InnerMap::const_iterator(it_)); + } + + friend bool operator==(const iterator& a, const iterator& b) { + return a.it_ == b.it_; + } + friend bool operator!=(const iterator& a, const iterator& b) { + return !(a == b); + } + + private: + friend class Map; + + InnerIt it_; + }; + + iterator begin() { return iterator(elements_.begin()); } + iterator end() { return iterator(elements_.end()); } + const_iterator begin() const { return const_iterator(elements_.begin()); } + const_iterator end() const { return const_iterator(elements_.end()); } + const_iterator cbegin() const { return begin(); } + const_iterator cend() const { return end(); } + + // Capacity + size_type size() const { return elements_.size(); } + bool empty() const { return size() == 0; } + + // Element access + template <typename K = key_type> + T& operator[](const key_arg<K>& key) { + return elements_[key].second; + } + template < + typename K = key_type, + // Disable for integral types to reduce code bloat. + typename = typename std::enable_if<!std::is_integral<K>::value>::type> + T& operator[](key_arg<K>&& key) { + return elements_[std::forward<K>(key)].second; + } + + template <typename K = key_type> + const T& at(const key_arg<K>& key) const { + const_iterator it = find(key); + GOOGLE_CHECK(it != end()) << "key not found: " << static_cast<Key>(key); + return it->second; + } + + template <typename K = key_type> + T& at(const key_arg<K>& key) { + iterator it = find(key); + GOOGLE_CHECK(it != end()) << "key not found: " << static_cast<Key>(key); + return it->second; + } + + // Lookup + template <typename K = key_type> + size_type count(const key_arg<K>& key) const { + return find(key) == end() ? 0 : 1; + } + + template <typename K = key_type> + const_iterator find(const key_arg<K>& key) const { + return const_iterator(elements_.find(key)); + } + template <typename K = key_type> + iterator find(const key_arg<K>& key) { + return iterator(elements_.find(key)); + } + + template <typename K = key_type> + bool contains(const key_arg<K>& key) const { + return find(key) != end(); + } + + template <typename K = key_type> + std::pair<const_iterator, const_iterator> equal_range( + const key_arg<K>& key) const { + const_iterator it = find(key); + if (it == end()) { + return std::pair<const_iterator, const_iterator>(it, it); + } else { + const_iterator begin = it++; + return std::pair<const_iterator, const_iterator>(begin, it); + } + } + + template <typename K = key_type> + std::pair<iterator, iterator> equal_range(const key_arg<K>& key) { + iterator it = find(key); + if (it == end()) { + return std::pair<iterator, iterator>(it, it); + } else { + iterator begin = it++; + return std::pair<iterator, iterator>(begin, it); + } + } + + // insert + std::pair<iterator, bool> insert(const value_type& value) { + std::pair<typename InnerMap::iterator, bool> p = + elements_.insert(value.first); + if (p.second) { + p.first->second = value.second; + } + return std::pair<iterator, bool>(iterator(p.first), p.second); + } + template <class InputIt> + void insert(InputIt first, InputIt last) { + for (InputIt it = first; it != last; ++it) { + iterator exist_it = find(it->first); + if (exist_it == end()) { + operator[](it->first) = it->second; + } + } + } + void insert(std::initializer_list<value_type> values) { + insert(values.begin(), values.end()); + } + + // Erase and clear + template <typename K = key_type> + size_type erase(const key_arg<K>& key) { + iterator it = find(key); + if (it == end()) { + return 0; + } else { + erase(it); + return 1; + } + } + iterator erase(iterator pos) { + iterator i = pos++; + elements_.erase(i.it_); + return pos; + } + void erase(iterator first, iterator last) { + while (first != last) { + first = erase(first); + } + } + void clear() { elements_.clear(); } + + // Assign + Map& operator=(const Map& other) { + if (this != &other) { + clear(); + insert(other.begin(), other.end()); + } + return *this; + } + + void swap(Map& other) { + if (arena() == other.arena()) { + InternalSwap(other); + } else { + // TODO(zuguang): optimize this. The temporary copy can be allocated + // in the same arena as the other message, and the "other = copy" can + // be replaced with the fast-path swap above. + Map copy = *this; + *this = other; + other = copy; + } + } + + void InternalSwap(Map& other) { elements_.Swap(&other.elements_); } + + // Access to hasher. Currently this returns a copy, but it may + // be modified to return a const reference in the future. + hasher hash_function() const { return elements_.hash_function(); } + + size_t SpaceUsedExcludingSelfLong() const { + if (empty()) return 0; + return elements_.SpaceUsedInternal() + internal::SpaceUsedInValues(this); + } + + private: + Arena* arena() const { return elements_.arena(); } + InnerMap elements_; + + friend class Arena; + using InternalArenaConstructable_ = void; + using DestructorSkippable_ = void; + template <typename Derived, typename K, typename V, + internal::WireFormatLite::FieldType key_wire_type, + internal::WireFormatLite::FieldType value_wire_type> + friend class internal::MapFieldLite; +}; + +} // namespace protobuf +} // namespace google + +#include <google/protobuf/port_undef.inc> + +#endif // GOOGLE_PROTOBUF_MAP_H__ diff --git a/contrib/libs/protobuf_old/src/google/protobuf/map_entry.h b/contrib/libs/protobuf_old/src/google/protobuf/map_entry.h new file mode 100644 index 0000000000..250dc59384 --- /dev/null +++ b/contrib/libs/protobuf_old/src/google/protobuf/map_entry.h @@ -0,0 +1,160 @@ +// 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_MAP_ENTRY_H__ +#define GOOGLE_PROTOBUF_MAP_ENTRY_H__ + +#include <google/protobuf/generated_message_reflection.h> +#include <google/protobuf/map_entry_lite.h> +#include <google/protobuf/map_type_handler.h> +#include <google/protobuf/port.h> +#include <google/protobuf/reflection_ops.h> +#include <google/protobuf/unknown_field_set.h> +#include <google/protobuf/wire_format_lite.h> + +#include <google/protobuf/port_def.inc> + +#ifdef SWIG +#error "You cannot SWIG proto headers" +#endif + +namespace google { +namespace protobuf { +class Arena; +namespace internal { +template <typename Derived, typename Key, typename Value, + WireFormatLite::FieldType kKeyFieldType, + WireFormatLite::FieldType kValueFieldType> +class MapField; +} +} // namespace protobuf +} // namespace google + +namespace google { +namespace protobuf { +namespace internal { + +// MapEntry is the returned google::protobuf::Message when calling AddMessage of +// google::protobuf::Reflection. In order to let it work with generated message +// reflection, its in-memory type is the same as generated message with the same +// fields. However, in order to decide the in-memory type of key/value, we need +// to know both their cpp type in generated api and proto type. In +// implementation, all in-memory types have related wire format functions to +// support except ArenaStringPtr. Therefore, we need to define another type with +// supporting wire format functions. Since this type is only used as return type +// of MapEntry accessors, it's named MapEntry accessor type. +// +// cpp type: the type visible to users in public API. +// proto type: WireFormatLite::FieldType of the field. +// in-memory type: type of the data member used to stored this field. +// MapEntry accessor type: type used in MapEntry getters/mutators to access the +// field. +// +// cpp type | proto type | in-memory type | MapEntry accessor type +// arc_i32 TYPE_INT32 arc_i32 arc_i32 +// arc_i32 TYPE_FIXED32 arc_i32 arc_i32 +// string TYPE_STRING ArenaStringPtr string +// FooEnum TYPE_ENUM int int +// FooMessage TYPE_MESSAGE FooMessage* FooMessage +// +// The in-memory types of primitive types can be inferred from its proto type, +// while we need to explicitly specify the cpp type if proto type is +// TYPE_MESSAGE to infer the in-memory type. +template <typename Derived, typename Key, typename Value, + WireFormatLite::FieldType kKeyFieldType, + WireFormatLite::FieldType kValueFieldType> +class MapEntry : public MapEntryImpl<Derived, Message, Key, Value, + kKeyFieldType, kValueFieldType> { + public: + constexpr MapEntry() : _internal_metadata_() {} + explicit MapEntry(Arena* arena) + : MapEntryImpl<Derived, Message, Key, Value, kKeyFieldType, + kValueFieldType>(arena), + _internal_metadata_(arena) {} + ~MapEntry() { + Message::_internal_metadata_.template Delete<UnknownFieldSet>(); + _internal_metadata_.Delete<UnknownFieldSet>(); + } + typedef void InternalArenaConstructable_; + typedef void DestructorSkippable_; + + typedef typename MapEntryImpl<Derived, Message, Key, Value, kKeyFieldType, + kValueFieldType>::KeyTypeHandler KeyTypeHandler; + typedef + typename MapEntryImpl<Derived, Message, Key, Value, kKeyFieldType, + kValueFieldType>::ValueTypeHandler ValueTypeHandler; + size_t SpaceUsedLong() const override { + size_t size = sizeof(Derived); + size += KeyTypeHandler::SpaceUsedInMapEntryLong(this->key_); + size += ValueTypeHandler::SpaceUsedInMapEntryLong(this->value_); + return size; + } + + InternalMetadata _internal_metadata_; + + private: + friend class ::PROTOBUF_NAMESPACE_ID::Arena; + template <typename C, typename K, typename V, + WireFormatLite::FieldType k_wire_type, WireFormatLite::FieldType> + friend class internal::MapField; + + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(MapEntry); +}; + +// Specialization for the full runtime +template <typename Derived, typename Key, typename Value, + WireFormatLite::FieldType kKeyFieldType, + WireFormatLite::FieldType kValueFieldType> +struct MapEntryHelper< + MapEntry<Derived, Key, Value, kKeyFieldType, kValueFieldType> > + : MapEntryHelper< + MapEntryLite<Derived, Key, Value, kKeyFieldType, kValueFieldType> > { + explicit MapEntryHelper(const MapPair<Key, Value>& map_pair) + : MapEntryHelper< + MapEntryLite<Derived, Key, Value, kKeyFieldType, kValueFieldType> >( + map_pair) {} +}; + +template <typename Derived, typename K, typename V, + WireFormatLite::FieldType key, WireFormatLite::FieldType value> +struct DeconstructMapEntry<MapEntry<Derived, K, V, key, value> > { + typedef K Key; + typedef V Value; + static constexpr WireFormatLite::FieldType kKeyFieldType = key; + static constexpr WireFormatLite::FieldType kValueFieldType = value; +}; + +} // namespace internal +} // namespace protobuf +} // namespace google + +#include <google/protobuf/port_undef.inc> + +#endif // GOOGLE_PROTOBUF_MAP_ENTRY_H__ diff --git a/contrib/libs/protobuf_old/src/google/protobuf/map_entry_lite.h b/contrib/libs/protobuf_old/src/google/protobuf/map_entry_lite.h new file mode 100644 index 0000000000..d9880b2abb --- /dev/null +++ b/contrib/libs/protobuf_old/src/google/protobuf/map_entry_lite.h @@ -0,0 +1,654 @@ +// 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_MAP_ENTRY_LITE_H__ +#define GOOGLE_PROTOBUF_MAP_ENTRY_LITE_H__ + +#include <assert.h> +#include <string> + +#include <google/protobuf/stubs/casts.h> +#include <google/protobuf/parse_context.h> +#include <google/protobuf/io/coded_stream.h> +#include <google/protobuf/arena.h> +#include <google/protobuf/arenastring.h> +#include <google/protobuf/generated_message_util.h> +#include <google/protobuf/map.h> +#include <google/protobuf/map_type_handler.h> +#include <google/protobuf/port.h> +#include <google/protobuf/wire_format_lite.h> + +#include <google/protobuf/port_def.inc> +#ifdef SWIG +#error "You cannot SWIG proto headers" +#endif + +namespace google { +namespace protobuf { +namespace internal { +template <typename Derived, typename Key, typename Value, + WireFormatLite::FieldType kKeyFieldType, + WireFormatLite::FieldType kValueFieldType> +class MapEntry; +template <typename Derived, typename Key, typename Value, + WireFormatLite::FieldType kKeyFieldType, + WireFormatLite::FieldType kValueFieldType> +class MapFieldLite; +} // namespace internal +} // namespace protobuf +} // namespace google + +namespace google { +namespace protobuf { +namespace internal { + +// MoveHelper::Move is used to set *dest. It copies *src, or moves it (in +// the C++11 sense), or swaps it. *src is left in a sane state for +// subsequent destruction, but shouldn't be used for anything. +template <bool is_enum, bool is_message, bool is_stringlike, typename T> +struct MoveHelper { // primitives + static void Move(T* src, T* dest) { *dest = *src; } +}; + +template <bool is_message, bool is_stringlike, typename T> +struct MoveHelper<true, is_message, is_stringlike, T> { // enums + static void Move(T* src, T* dest) { *dest = *src; } + // T is an enum here, so allow conversions to and from int. + static void Move(T* src, int* dest) { *dest = static_cast<int>(*src); } + static void Move(int* src, T* dest) { *dest = static_cast<T>(*src); } +}; + +template <bool is_stringlike, typename T> +struct MoveHelper<false, true, is_stringlike, T> { // messages + static void Move(T* src, T* dest) { dest->Swap(src); } +}; + +template <typename T> +struct MoveHelper<false, false, true, T> { // strings and similar + static void Move(T* src, T* dest) { + *dest = std::move(*src); + } +}; + +// Functions for operating on a map entry. Does not contain any representation +// (this class is not intended to be instantiated). +template <typename Key, typename Value, WireFormatLite::FieldType kKeyFieldType, + WireFormatLite::FieldType kValueFieldType> +struct MapEntryFuncs { + typedef MapTypeHandler<kKeyFieldType, Key> KeyTypeHandler; + typedef MapTypeHandler<kValueFieldType, Value> ValueTypeHandler; + static const int kKeyFieldNumber = 1; + static const int kValueFieldNumber = 2; + + static uint8_t* InternalSerialize(int field_number, const Key& key, + const Value& value, uint8_t* ptr, + io::EpsCopyOutputStream* stream) { + ptr = stream->EnsureSpace(ptr); + ptr = WireFormatLite::WriteTagToArray( + field_number, WireFormatLite::WIRETYPE_LENGTH_DELIMITED, ptr); + ptr = io::CodedOutputStream::WriteVarint32ToArray(GetCachedSize(key, value), + ptr); + + ptr = KeyTypeHandler::Write(kKeyFieldNumber, key, ptr, stream); + return ValueTypeHandler::Write(kValueFieldNumber, value, ptr, stream); + } + + static size_t ByteSizeLong(const Key& key, const Value& value) { + // Tags for key and value will both be one byte (field numbers 1 and 2). + size_t inner_length = + 2 + KeyTypeHandler::ByteSize(key) + ValueTypeHandler::ByteSize(value); + return inner_length + io::CodedOutputStream::VarintSize32( + static_cast<arc_ui32>(inner_length)); + } + + static int GetCachedSize(const Key& key, const Value& value) { + // Tags for key and value will both be one byte (field numbers 1 and 2). + return 2 + KeyTypeHandler::GetCachedSize(key) + + ValueTypeHandler::GetCachedSize(value); + } +}; + +// MapEntryImpl is used to implement parsing and serialization of map entries. +// It uses Curious Recursive Template Pattern (CRTP) to provide the type of +// the eventual code to the template code. +template <typename Derived, typename Base, typename Key, typename Value, + WireFormatLite::FieldType kKeyFieldType, + WireFormatLite::FieldType kValueFieldType> +class MapEntryImpl : public Base { + public: + typedef MapEntryFuncs<Key, Value, kKeyFieldType, kValueFieldType> Funcs; + + protected: + // Provide utilities to parse/serialize key/value. Provide utilities to + // manipulate internal stored type. + typedef MapTypeHandler<kKeyFieldType, Key> KeyTypeHandler; + typedef MapTypeHandler<kValueFieldType, Value> ValueTypeHandler; + + // Define internal memory layout. Strings and messages are stored as + // pointers, while other types are stored as values. + typedef typename KeyTypeHandler::TypeOnMemory KeyOnMemory; + typedef typename ValueTypeHandler::TypeOnMemory ValueOnMemory; + + // Enum type cannot be used for MapTypeHandler::Read. Define a type + // which will replace Enum with int. + typedef typename KeyTypeHandler::MapEntryAccessorType KeyMapEntryAccessorType; + typedef + typename ValueTypeHandler::MapEntryAccessorType ValueMapEntryAccessorType; + + // Constants for field number. + static const int kKeyFieldNumber = 1; + static const int kValueFieldNumber = 2; + + // Constants for field tag. + static const uint8_t kKeyTag = + GOOGLE_PROTOBUF_WIRE_FORMAT_MAKE_TAG(kKeyFieldNumber, KeyTypeHandler::kWireType); + static const uint8_t kValueTag = GOOGLE_PROTOBUF_WIRE_FORMAT_MAKE_TAG( + kValueFieldNumber, ValueTypeHandler::kWireType); + static const size_t kTagSize = 1; + + public: + // Work-around for a compiler bug (see repeated_field.h). + typedef void MapEntryHasMergeTypeTrait; + typedef Derived EntryType; + typedef Key EntryKeyType; + typedef Value EntryValueType; + static const WireFormatLite::FieldType kEntryKeyFieldType = kKeyFieldType; + static const WireFormatLite::FieldType kEntryValueFieldType = kValueFieldType; + + constexpr MapEntryImpl() + : key_(KeyTypeHandler::Constinit()), + value_(ValueTypeHandler::Constinit()), + _has_bits_{} {} + + explicit MapEntryImpl(Arena* arena) + : Base(arena), + key_(KeyTypeHandler::Constinit()), + value_(ValueTypeHandler::Constinit()), + _has_bits_{} {} + + ~MapEntryImpl() { + if (Base::GetArenaForAllocation() != nullptr) return; + KeyTypeHandler::DeleteNoArena(key_); + ValueTypeHandler::DeleteNoArena(value_); + } + + // accessors ====================================================== + + virtual inline const KeyMapEntryAccessorType& key() const { + return KeyTypeHandler::GetExternalReference(key_); + } + virtual inline const ValueMapEntryAccessorType& value() const { + return ValueTypeHandler::DefaultIfNotInitialized(value_); + } + inline KeyMapEntryAccessorType* mutable_key() { + set_has_key(); + return KeyTypeHandler::EnsureMutable(&key_, Base::GetArenaForAllocation()); + } + inline ValueMapEntryAccessorType* mutable_value() { + set_has_value(); + return ValueTypeHandler::EnsureMutable(&value_, + Base::GetArenaForAllocation()); + } + + // implements MessageLite ========================================= + + // MapEntryImpl is for implementation only and this function isn't called + // anywhere. Just provide a fake implementation here for MessageLite. + TProtoStringType GetTypeName() const override { return ""; } + + void CheckTypeAndMergeFrom(const MessageLite& other) override { + MergeFromInternal(*::google::protobuf::internal::DownCast<const Derived*>(&other)); + } + + const char* _InternalParse(const char* ptr, ParseContext* ctx) final { + while (!ctx->Done(&ptr)) { + arc_ui32 tag; + ptr = ReadTag(ptr, &tag); + GOOGLE_PROTOBUF_PARSER_ASSERT(ptr); + if (tag == kKeyTag) { + set_has_key(); + KeyMapEntryAccessorType* key = mutable_key(); + ptr = KeyTypeHandler::Read(ptr, ctx, key); + if (!Derived::ValidateKey(key)) return nullptr; + } else if (tag == kValueTag) { + set_has_value(); + ValueMapEntryAccessorType* value = mutable_value(); + ptr = ValueTypeHandler::Read(ptr, ctx, value); + if (!Derived::ValidateValue(value)) return nullptr; + } else { + if (tag == 0 || WireFormatLite::GetTagWireType(tag) == + WireFormatLite::WIRETYPE_END_GROUP) { + ctx->SetLastTag(tag); + return ptr; + } + ptr = UnknownFieldParse(tag, static_cast<TProtoStringType*>(nullptr), ptr, + ctx); + } + GOOGLE_PROTOBUF_PARSER_ASSERT(ptr); + } + return ptr; + } + + size_t ByteSizeLong() const override { + size_t size = 0; + size += kTagSize + static_cast<size_t>(KeyTypeHandler::ByteSize(key())); + size += kTagSize + static_cast<size_t>(ValueTypeHandler::ByteSize(value())); + return size; + } + + ::uint8_t* _InternalSerialize( + ::uint8_t* ptr, io::EpsCopyOutputStream* stream) const override { + ptr = KeyTypeHandler::Write(kKeyFieldNumber, key(), ptr, stream); + return ValueTypeHandler::Write(kValueFieldNumber, value(), ptr, stream); + } + + // Don't override SerializeWithCachedSizesToArray. Use MessageLite's. + + int GetCachedSize() const override { + int size = 0; + size += has_key() ? static_cast<int>(kTagSize) + + KeyTypeHandler::GetCachedSize(key()) + : 0; + size += has_value() ? static_cast<int>(kTagSize) + + ValueTypeHandler::GetCachedSize(value()) + : 0; + return size; + } + + bool IsInitialized() const override { + return ValueTypeHandler::IsInitialized(value_); + } + + Base* New(Arena* arena) const override { + Derived* entry = Arena::CreateMessage<Derived>(arena); + return entry; + } + + protected: + // We can't declare this function directly here as it would hide the other + // overload (const Message&). + void MergeFromInternal(const MapEntryImpl& from) { + if (from._has_bits_[0]) { + if (from.has_key()) { + KeyTypeHandler::EnsureMutable(&key_, Base::GetArenaForAllocation()); + KeyTypeHandler::Merge(from.key(), &key_, Base::GetArenaForAllocation()); + set_has_key(); + } + if (from.has_value()) { + ValueTypeHandler::EnsureMutable(&value_, Base::GetArenaForAllocation()); + ValueTypeHandler::Merge(from.value(), &value_, + Base::GetArenaForAllocation()); + set_has_value(); + } + } + } + + public: + void Clear() override { + KeyTypeHandler::Clear(&key_, Base::GetArenaForAllocation()); + ValueTypeHandler::Clear(&value_, Base::GetArenaForAllocation()); + clear_has_key(); + clear_has_value(); + } + + // Parsing using MergePartialFromCodedStream, above, is not as + // efficient as it could be. This helper class provides a speedier way. + template <typename MapField, typename Map> + class Parser { + public: + explicit Parser(MapField* mf) : mf_(mf), map_(mf->MutableMap()) {} + ~Parser() { + if (entry_ != nullptr && entry_->GetArenaForAllocation() == nullptr) + delete entry_; + } + + // This does what the typical MergePartialFromCodedStream() is expected to + // do, with the additional side-effect that if successful (i.e., if true is + // going to be its return value) it inserts the key-value pair into map_. + bool MergePartialFromCodedStream(io::CodedInputStream* input) { + // Look for the expected thing: a key and then a value. If it fails, + // invoke the enclosing class's MergePartialFromCodedStream, or return + // false if that would be pointless. + if (input->ExpectTag(kKeyTag)) { + if (!KeyTypeHandler::Read(input, &key_)) { + return false; + } + // Peek at the next byte to see if it is kValueTag. If not, bail out. + const void* data; + int size; + input->GetDirectBufferPointerInline(&data, &size); + // We could use memcmp here, but we don't bother. The tag is one byte. + static_assert(kTagSize == 1, "tag size must be 1"); + if (size > 0 && *reinterpret_cast<const char*>(data) == kValueTag) { + typename Map::size_type map_size = map_->size(); + value_ptr_ = &(*map_)[key_]; + if (PROTOBUF_PREDICT_TRUE(map_size != map_->size())) { + // We created a new key-value pair. Fill in the value. + typedef + typename MapIf<ValueTypeHandler::kIsEnum, int*, Value*>::type T; + input->Skip(kTagSize); // Skip kValueTag. + if (!ValueTypeHandler::Read(input, + reinterpret_cast<T>(value_ptr_))) { + map_->erase(key_); // Failure! Undo insertion. + return false; + } + if (input->ExpectAtEnd()) return true; + return ReadBeyondKeyValuePair(input); + } + } + } else { + key_ = Key(); + } + + NewEntry(); + *entry_->mutable_key() = key_; + const bool result = entry_->MergePartialFromCodedStream(input); + if (result) UseKeyAndValueFromEntry(); + return result; + } + + const char* _InternalParse(const char* ptr, ParseContext* ctx) { + if (PROTOBUF_PREDICT_TRUE(!ctx->Done(&ptr) && *ptr == kKeyTag)) { + ptr = KeyTypeHandler::Read(ptr + 1, ctx, &key_); + if (PROTOBUF_PREDICT_FALSE(!ptr || !Derived::ValidateKey(&key_))) { + return nullptr; + } + if (PROTOBUF_PREDICT_TRUE(!ctx->Done(&ptr) && *ptr == kValueTag)) { + typename Map::size_type map_size = map_->size(); + value_ptr_ = &(*map_)[key_]; + if (PROTOBUF_PREDICT_TRUE(map_size != map_->size())) { + using T = + typename MapIf<ValueTypeHandler::kIsEnum, int*, Value*>::type; + ptr = ValueTypeHandler::Read(ptr + 1, ctx, + reinterpret_cast<T>(value_ptr_)); + if (PROTOBUF_PREDICT_FALSE(!ptr || + !Derived::ValidateValue(value_ptr_))) { + map_->erase(key_); // Failure! Undo insertion. + return nullptr; + } + if (PROTOBUF_PREDICT_TRUE(ctx->Done(&ptr))) return ptr; + if (!ptr) return nullptr; + NewEntry(); + ValueMover::Move(value_ptr_, entry_->mutable_value()); + map_->erase(key_); + goto move_key; + } + } else { + if (!ptr) return nullptr; + } + NewEntry(); + move_key: + KeyMover::Move(&key_, entry_->mutable_key()); + } else { + if (!ptr) return nullptr; + NewEntry(); + } + ptr = entry_->_InternalParse(ptr, ctx); + if (ptr) UseKeyAndValueFromEntry(); + return ptr; + } + + template <typename UnknownType> + const char* ParseWithEnumValidation(const char* ptr, ParseContext* ctx, + bool (*is_valid)(int), + arc_ui32 field_num, + InternalMetadata* metadata) { + auto entry = NewEntry(); + ptr = entry->_InternalParse(ptr, ctx); + if (!ptr) return nullptr; + if (is_valid(entry->value())) { + UseKeyAndValueFromEntry(); + } else { + WriteLengthDelimited(field_num, entry->SerializeAsString(), + metadata->mutable_unknown_fields<UnknownType>()); + } + return ptr; + } + + MapEntryImpl* NewEntry() { return entry_ = mf_->NewEntry(); } + + const Key& key() const { return key_; } + const Value& value() const { return *value_ptr_; } + + const Key& entry_key() const { return entry_->key(); } + const Value& entry_value() const { return entry_->value(); } + + private: + void UseKeyAndValueFromEntry() { + // Update key_ in case we need it later (because key() is called). + // This is potentially inefficient, especially if the key is + // expensive to copy (e.g., a long string), but this is a cold + // path, so it's not a big deal. + key_ = entry_->key(); + value_ptr_ = &(*map_)[key_]; + ValueMover::Move(entry_->mutable_value(), value_ptr_); + } + + // After reading a key and value successfully, and inserting that data + // into map_, we are not at the end of the input. This is unusual, but + // allowed by the spec. + bool ReadBeyondKeyValuePair(io::CodedInputStream* input) PROTOBUF_COLD { + NewEntry(); + ValueMover::Move(value_ptr_, entry_->mutable_value()); + map_->erase(key_); + KeyMover::Move(&key_, entry_->mutable_key()); + const bool result = entry_->MergePartialFromCodedStream(input); + if (result) UseKeyAndValueFromEntry(); + return result; + } + + typedef MoveHelper<KeyTypeHandler::kIsEnum, KeyTypeHandler::kIsMessage, + KeyTypeHandler::kWireType == + WireFormatLite::WIRETYPE_LENGTH_DELIMITED, + Key> + KeyMover; + typedef MoveHelper<ValueTypeHandler::kIsEnum, ValueTypeHandler::kIsMessage, + ValueTypeHandler::kWireType == + WireFormatLite::WIRETYPE_LENGTH_DELIMITED, + Value> + ValueMover; + + MapField* const mf_; + Map* const map_; + Key key_; + Value* value_ptr_; + MapEntryImpl* entry_ = nullptr; + }; + + protected: + void set_has_key() { _has_bits_[0] |= 0x00000001u; } + bool has_key() const { return (_has_bits_[0] & 0x00000001u) != 0; } + void clear_has_key() { _has_bits_[0] &= ~0x00000001u; } + void set_has_value() { _has_bits_[0] |= 0x00000002u; } + bool has_value() const { return (_has_bits_[0] & 0x00000002u) != 0; } + void clear_has_value() { _has_bits_[0] &= ~0x00000002u; } + + public: + inline Arena* GetArena() const { return Base::GetArena(); } + + public: // Needed for constructing tables + KeyOnMemory key_; + ValueOnMemory value_; + arc_ui32 _has_bits_[1]; + + private: + friend class ::PROTOBUF_NAMESPACE_ID::Arena; + typedef void InternalArenaConstructable_; + typedef void DestructorSkippable_; + template <typename C, typename K, typename V, WireFormatLite::FieldType, + WireFormatLite::FieldType> + friend class internal::MapEntry; + template <typename C, typename K, typename V, WireFormatLite::FieldType, + WireFormatLite::FieldType> + friend class internal::MapFieldLite; + + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(MapEntryImpl); +}; + +template <typename T, typename Key, typename Value, + WireFormatLite::FieldType kKeyFieldType, + WireFormatLite::FieldType kValueFieldType> +class MapEntryLite : public MapEntryImpl<T, MessageLite, Key, Value, + kKeyFieldType, kValueFieldType> { + public: + typedef MapEntryImpl<T, MessageLite, Key, Value, kKeyFieldType, + kValueFieldType> + SuperType; + constexpr MapEntryLite() {} + explicit MapEntryLite(Arena* arena) : SuperType(arena) {} + ~MapEntryLite() { + MessageLite::_internal_metadata_.template Delete<TProtoStringType>(); + } + void MergeFrom(const MapEntryLite& other) { MergeFromInternal(other); } + + private: + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(MapEntryLite); +}; +// The completely unprincipled and unwieldy use of template parameters in +// the map code necessitates wrappers to make the code a little bit more +// manageable. +template <typename Derived> +struct DeconstructMapEntry; + +template <typename T, typename K, typename V, WireFormatLite::FieldType key, + WireFormatLite::FieldType value> +struct DeconstructMapEntry<MapEntryLite<T, K, V, key, value> > { + typedef K Key; + typedef V Value; + static const WireFormatLite::FieldType kKeyFieldType = key; + static const WireFormatLite::FieldType kValueFieldType = value; +}; + +// Helpers for deterministic serialization ============================= + +// This struct can be used with any generic sorting algorithm. If the Key +// type is relatively small and easy to copy then copying Keys into an +// array of SortItems can be beneficial. Then all the data the sorting +// algorithm needs to touch is in that one array. +template <typename Key, typename PtrToKeyValuePair> +struct SortItem { + SortItem() {} + explicit SortItem(PtrToKeyValuePair p) : first(p->first), second(p) {} + + Key first; + PtrToKeyValuePair second; +}; + +template <typename T> +struct CompareByFirstField { + bool operator()(const T& a, const T& b) const { return a.first < b.first; } +}; + +template <typename T> +struct CompareByDerefFirst { + bool operator()(const T& a, const T& b) const { return a->first < b->first; } +}; + +// Helper for table driven serialization + +template <WireFormatLite::FieldType FieldType> +struct FromHelper { + template <typename T> + static const T& From(const T& x) { + return x; + } +}; + +template <> +struct FromHelper<WireFormatLite::TYPE_STRING> { + static ArenaStringPtr From(const TProtoStringType& x) { + ArenaStringPtr res; + TaggedPtr<TProtoStringType> ptr; + ptr.Set(const_cast<TProtoStringType*>(&x)); + res.UnsafeSetTaggedPointer(ptr); + return res; + } +}; +template <> +struct FromHelper<WireFormatLite::TYPE_BYTES> { + static ArenaStringPtr From(const TProtoStringType& x) { + ArenaStringPtr res; + TaggedPtr<TProtoStringType> ptr; + ptr.Set(const_cast<TProtoStringType*>(&x)); + res.UnsafeSetTaggedPointer(ptr); + return res; + } +}; +template <> +struct FromHelper<WireFormatLite::TYPE_MESSAGE> { + template <typename T> + static T* From(const T& x) { + return const_cast<T*>(&x); + } +}; + +template <typename MapEntryType> +struct MapEntryHelper; + +template <typename T, typename Key, typename Value, + WireFormatLite::FieldType kKeyFieldType, + WireFormatLite::FieldType kValueFieldType> +struct MapEntryHelper< + MapEntryLite<T, Key, Value, kKeyFieldType, kValueFieldType> > { + // Provide utilities to parse/serialize key/value. Provide utilities to + // manipulate internal stored type. + typedef MapTypeHandler<kKeyFieldType, Key> KeyTypeHandler; + typedef MapTypeHandler<kValueFieldType, Value> ValueTypeHandler; + + // Define internal memory layout. Strings and messages are stored as + // pointers, while other types are stored as values. + typedef typename KeyTypeHandler::TypeOnMemory KeyOnMemory; + typedef typename ValueTypeHandler::TypeOnMemory ValueOnMemory; + + explicit MapEntryHelper(const MapPair<Key, Value>& map_pair) + : _has_bits_(3), + _cached_size_(2 + KeyTypeHandler::GetCachedSize(map_pair.first) + + ValueTypeHandler::GetCachedSize(map_pair.second)), + key_(FromHelper<kKeyFieldType>::From(map_pair.first)), + value_(FromHelper<kValueFieldType>::From(map_pair.second)) {} + + // Purposely not following the style guide naming. These are the names + // the proto compiler would generate given the map entry descriptor. + // The proto compiler generates the offsets in this struct as if this was + // a regular message. This way the table driven code barely notices it's + // dealing with a map field. + arc_ui32 _has_bits_; // NOLINT + arc_ui32 _cached_size_; // NOLINT + KeyOnMemory key_; // NOLINT + ValueOnMemory value_; // NOLINT +}; + +} // namespace internal +} // namespace protobuf +} // namespace google + +#include <google/protobuf/port_undef.inc> + +#endif // GOOGLE_PROTOBUF_MAP_ENTRY_LITE_H__ diff --git a/contrib/libs/protobuf_old/src/google/protobuf/map_field.cc b/contrib/libs/protobuf_old/src/google/protobuf/map_field.cc new file mode 100644 index 0000000000..d6534806fe --- /dev/null +++ b/contrib/libs/protobuf_old/src/google/protobuf/map_field.cc @@ -0,0 +1,647 @@ +// 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 <google/protobuf/map_field.h> +#include <google/protobuf/map_field_inl.h> + +#include <vector> + +#include <google/protobuf/port_def.inc> + +namespace google { +namespace protobuf { +namespace internal { + +MapFieldBase::~MapFieldBase() { + if (repeated_field_ != nullptr && arena_ == nullptr) delete repeated_field_; +} + +const RepeatedPtrFieldBase& MapFieldBase::GetRepeatedField() const { + ConstAccess(); + SyncRepeatedFieldWithMap(); + return *reinterpret_cast<RepeatedPtrFieldBase*>(repeated_field_); +} + +RepeatedPtrFieldBase* MapFieldBase::MutableRepeatedField() { + MutableAccess(); + SyncRepeatedFieldWithMap(); + SetRepeatedDirty(); + return reinterpret_cast<RepeatedPtrFieldBase*>(repeated_field_); +} + +void MapFieldBase::SwapState(MapFieldBase* other) { + // a relaxed swap of the atomic + auto other_state = other->state_.load(std::memory_order_relaxed); + auto this_state = state_.load(std::memory_order_relaxed); + other->state_.store(this_state, std::memory_order_relaxed); + state_.store(other_state, std::memory_order_relaxed); +} + +void SwapRepeatedPtrToNull(RepeatedPtrField<Message>** from, + RepeatedPtrField<Message>** to, Arena* from_arena, + Arena* to_arena) { + GOOGLE_DCHECK(*from != nullptr); + GOOGLE_DCHECK(*to == nullptr); + *to = Arena::CreateMessage<RepeatedPtrField<Message> >(to_arena); + **to = std::move(**from); + if (from_arena == nullptr) { + delete *from; + } + *from = nullptr; +} + +void MapFieldBase::Swap(MapFieldBase* other) { + if (arena_ == other->arena_) { + InternalSwap(other); + return; + } + if (repeated_field_ != nullptr || other->repeated_field_ != nullptr) { + if (repeated_field_ == nullptr) { + SwapRepeatedPtrToNull(&other->repeated_field_, &repeated_field_, + other->arena_, arena_); + } else if (other->repeated_field_ == nullptr) { + SwapRepeatedPtrToNull(&repeated_field_, &other->repeated_field_, arena_, + other->arena_); + } else { + repeated_field_->Swap(other->repeated_field_); + } + } + SwapState(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_); + SwapState(other); +} + +size_t MapFieldBase::SpaceUsedExcludingSelfLong() const { + ConstAccess(); + mutex_.Lock(); + size_t size = SpaceUsedExcludingSelfNoLock(); + mutex_.Unlock(); + ConstAccess(); + return size; +} + +size_t MapFieldBase::SpaceUsedExcludingSelfNoLock() const { + if (repeated_field_ != nullptr) { + return repeated_field_->SpaceUsedExcludingSelfLong(); + } else { + return 0; + } +} + +bool MapFieldBase::IsMapValid() const { + ConstAccess(); + // "Acquire" insures the operation after SyncRepeatedFieldWithMap won't get + // executed before state_ is checked. + int state = state_.load(std::memory_order_acquire); + return state != STATE_MODIFIED_REPEATED; +} + +bool MapFieldBase::IsRepeatedFieldValid() const { + ConstAccess(); + int state = state_.load(std::memory_order_acquire); + return state != STATE_MODIFIED_MAP; +} + +void MapFieldBase::SetMapDirty() { + MutableAccess(); + // These are called by (non-const) mutator functions. So by our API it's the + // callers responsibility to have these calls properly ordered. + state_.store(STATE_MODIFIED_MAP, std::memory_order_relaxed); +} + +void MapFieldBase::SetRepeatedDirty() { + MutableAccess(); + // These are called by (non-const) mutator functions. So by our API it's the + // callers responsibility to have these calls properly ordered. + state_.store(STATE_MODIFIED_REPEATED, std::memory_order_relaxed); +} + +void MapFieldBase::SyncRepeatedFieldWithMap() const { + ConstAccess(); + // acquire here matches with release below to ensure that we can only see a + // value of CLEAN after all previous changes have been synced. + switch (state_.load(std::memory_order_acquire)) { + case STATE_MODIFIED_MAP: + mutex_.Lock(); + // Double check state, because another thread may have seen the same + // state and done the synchronization before the current thread. + if (state_.load(std::memory_order_relaxed) == STATE_MODIFIED_MAP) { + SyncRepeatedFieldWithMapNoLock(); + state_.store(CLEAN, std::memory_order_release); + } + mutex_.Unlock(); + ConstAccess(); + break; + case CLEAN: + mutex_.Lock(); + // Double check state + if (state_.load(std::memory_order_relaxed) == CLEAN) { + if (repeated_field_ == nullptr) { + repeated_field_ = + Arena::CreateMessage<RepeatedPtrField<Message> >(arena_); + } + state_.store(CLEAN, std::memory_order_release); + } + mutex_.Unlock(); + ConstAccess(); + break; + default: + break; + } +} + +void MapFieldBase::SyncRepeatedFieldWithMapNoLock() const { + if (repeated_field_ == nullptr) { + repeated_field_ = Arena::CreateMessage<RepeatedPtrField<Message> >(arena_); + } +} + +void MapFieldBase::SyncMapWithRepeatedField() const { + ConstAccess(); + // acquire here matches with release below to ensure that we can only see a + // value of CLEAN after all previous changes have been synced. + if (state_.load(std::memory_order_acquire) == STATE_MODIFIED_REPEATED) { + mutex_.Lock(); + // Double check state, because another thread may have seen the same state + // and done the synchronization before the current thread. + if (state_.load(std::memory_order_relaxed) == STATE_MODIFIED_REPEATED) { + SyncMapWithRepeatedFieldNoLock(); + state_.store(CLEAN, std::memory_order_release); + } + mutex_.Unlock(); + ConstAccess(); + } +} + +// ------------------DynamicMapField------------------ +DynamicMapField::DynamicMapField(const Message* default_entry) + : default_entry_(default_entry) {} + +DynamicMapField::DynamicMapField(const Message* default_entry, Arena* arena) + : TypeDefinedMapFieldBase<MapKey, MapValueRef>(arena), + map_(arena), + default_entry_(default_entry) {} + +DynamicMapField::~DynamicMapField() { + if (arena_ != nullptr) return; + // DynamicMapField owns map values. Need to delete them before clearing the + // map. + for (auto& kv : map_) { + kv.second.DeleteData(); + } + map_.clear(); +} + +int DynamicMapField::size() const { return GetMap().size(); } + +void DynamicMapField::Clear() { + Map<MapKey, MapValueRef>* map = &const_cast<DynamicMapField*>(this)->map_; + if (MapFieldBase::arena_ == nullptr) { + for (Map<MapKey, MapValueRef>::iterator iter = map->begin(); + iter != map->end(); ++iter) { + iter->second.DeleteData(); + } + } + + map->clear(); + + if (MapFieldBase::repeated_field_ != nullptr) { + MapFieldBase::repeated_field_->Clear(); + } + // Data in map and repeated field are both empty, but we can't set status + // CLEAN which will invalidate previous reference to map. + MapFieldBase::SetMapDirty(); +} + +bool DynamicMapField::ContainsMapKey(const MapKey& map_key) const { + const Map<MapKey, MapValueRef>& map = GetMap(); + Map<MapKey, MapValueRef>::const_iterator iter = map.find(map_key); + return iter != map.end(); +} + +void DynamicMapField::AllocateMapValue(MapValueRef* map_val) { + const FieldDescriptor* val_des = default_entry_->GetDescriptor()->map_value(); + map_val->SetType(val_des->cpp_type()); + // Allocate memory for the MapValueRef, and initialize to + // default value. + switch (val_des->cpp_type()) { +#define HANDLE_TYPE(CPPTYPE, TYPE) \ + case FieldDescriptor::CPPTYPE_##CPPTYPE: { \ + TYPE* value = Arena::Create<TYPE>(MapFieldBase::arena_); \ + map_val->SetValue(value); \ + break; \ + } + HANDLE_TYPE(INT32, arc_i32); + HANDLE_TYPE(INT64, arc_i64); + HANDLE_TYPE(UINT32, arc_ui32); + HANDLE_TYPE(UINT64, arc_ui64); + HANDLE_TYPE(DOUBLE, double); + HANDLE_TYPE(FLOAT, float); + HANDLE_TYPE(BOOL, bool); + HANDLE_TYPE(STRING, TProtoStringType); + HANDLE_TYPE(ENUM, arc_i32); +#undef HANDLE_TYPE + case FieldDescriptor::CPPTYPE_MESSAGE: { + const Message& message = + default_entry_->GetReflection()->GetMessage(*default_entry_, val_des); + Message* value = message.New(MapFieldBase::arena_); + map_val->SetValue(value); + break; + } + } +} + +bool DynamicMapField::InsertOrLookupMapValue(const MapKey& map_key, + MapValueRef* val) { + // Always use mutable map because users may change the map value by + // MapValueRef. + Map<MapKey, MapValueRef>* map = MutableMap(); + Map<MapKey, MapValueRef>::iterator iter = map->find(map_key); + if (iter == map->end()) { + MapValueRef& map_val = map_[map_key]; + AllocateMapValue(&map_val); + val->CopyFrom(map_val); + return true; + } + // map_key is already in the map. Make sure (*map)[map_key] is not called. + // [] may reorder the map and iterators. + val->CopyFrom(iter->second); + return false; +} + +bool DynamicMapField::LookupMapValue(const MapKey& map_key, + MapValueConstRef* val) const { + const Map<MapKey, MapValueRef>& map = GetMap(); + Map<MapKey, MapValueRef>::const_iterator iter = map.find(map_key); + if (iter == map.end()) { + return false; + } + // map_key is already in the map. Make sure (*map)[map_key] is not called. + // [] may reorder the map and iterators. + val->CopyFrom(iter->second); + return true; +} + +bool DynamicMapField::DeleteMapValue(const MapKey& map_key) { + MapFieldBase::SyncMapWithRepeatedField(); + Map<MapKey, MapValueRef>::iterator iter = map_.find(map_key); + if (iter == map_.end()) { + return false; + } + // Set map dirty only if the delete is successful. + MapFieldBase::SetMapDirty(); + if (MapFieldBase::arena_ == nullptr) { + iter->second.DeleteData(); + } + map_.erase(iter); + return true; +} + +const Map<MapKey, MapValueRef>& DynamicMapField::GetMap() const { + MapFieldBase::SyncMapWithRepeatedField(); + return map_; +} + +Map<MapKey, MapValueRef>* DynamicMapField::MutableMap() { + MapFieldBase::SyncMapWithRepeatedField(); + MapFieldBase::SetMapDirty(); + return &map_; +} + +void DynamicMapField::SetMapIteratorValue(MapIterator* map_iter) const { + Map<MapKey, MapValueRef>::const_iterator iter = + TypeDefinedMapFieldBase<MapKey, MapValueRef>::InternalGetIterator( + map_iter); + if (iter == map_.end()) return; + map_iter->key_.CopyFrom(iter->first); + map_iter->value_.CopyFrom(iter->second); +} + +void DynamicMapField::MergeFrom(const MapFieldBase& other) { + GOOGLE_DCHECK(IsMapValid() && other.IsMapValid()); + Map<MapKey, MapValueRef>* map = MutableMap(); + const DynamicMapField& other_field = + reinterpret_cast<const DynamicMapField&>(other); + for (Map<MapKey, MapValueRef>::const_iterator other_it = + other_field.map_.begin(); + other_it != other_field.map_.end(); ++other_it) { + Map<MapKey, MapValueRef>::iterator iter = map->find(other_it->first); + MapValueRef* map_val; + if (iter == map->end()) { + map_val = &map_[other_it->first]; + AllocateMapValue(map_val); + } else { + map_val = &iter->second; + } + + // Copy map value + const FieldDescriptor* field_descriptor = + default_entry_->GetDescriptor()->map_value(); + switch (field_descriptor->cpp_type()) { + case FieldDescriptor::CPPTYPE_INT32: { + map_val->SetInt32Value(other_it->second.GetInt32Value()); + break; + } + case FieldDescriptor::CPPTYPE_INT64: { + map_val->SetInt64Value(other_it->second.GetInt64Value()); + break; + } + case FieldDescriptor::CPPTYPE_UINT32: { + map_val->SetUInt32Value(other_it->second.GetUInt32Value()); + break; + } + case FieldDescriptor::CPPTYPE_UINT64: { + map_val->SetUInt64Value(other_it->second.GetUInt64Value()); + break; + } + case FieldDescriptor::CPPTYPE_FLOAT: { + map_val->SetFloatValue(other_it->second.GetFloatValue()); + break; + } + case FieldDescriptor::CPPTYPE_DOUBLE: { + map_val->SetDoubleValue(other_it->second.GetDoubleValue()); + break; + } + case FieldDescriptor::CPPTYPE_BOOL: { + map_val->SetBoolValue(other_it->second.GetBoolValue()); + break; + } + case FieldDescriptor::CPPTYPE_STRING: { + map_val->SetStringValue(other_it->second.GetStringValue()); + break; + } + case FieldDescriptor::CPPTYPE_ENUM: { + map_val->SetEnumValue(other_it->second.GetEnumValue()); + break; + } + case FieldDescriptor::CPPTYPE_MESSAGE: { + map_val->MutableMessageValue()->CopyFrom( + other_it->second.GetMessageValue()); + break; + } + } + } +} + +void DynamicMapField::Swap(MapFieldBase* other) { + DynamicMapField* other_field = down_cast<DynamicMapField*>(other); + std::swap(this->MapFieldBase::repeated_field_, other_field->repeated_field_); + map_.swap(other_field->map_); + // a relaxed swap of the atomic + auto other_state = other_field->state_.load(std::memory_order_relaxed); + auto this_state = this->MapFieldBase::state_.load(std::memory_order_relaxed); + other_field->state_.store(this_state, std::memory_order_relaxed); + this->MapFieldBase::state_.store(other_state, std::memory_order_relaxed); +} + +void DynamicMapField::SyncRepeatedFieldWithMapNoLock() const { + const Reflection* reflection = default_entry_->GetReflection(); + const FieldDescriptor* key_des = default_entry_->GetDescriptor()->map_key(); + const FieldDescriptor* val_des = default_entry_->GetDescriptor()->map_value(); + if (MapFieldBase::repeated_field_ == nullptr) { + MapFieldBase::repeated_field_ = + Arena::CreateMessage<RepeatedPtrField<Message> >(MapFieldBase::arena_); + } + + MapFieldBase::repeated_field_->Clear(); + + for (Map<MapKey, MapValueRef>::const_iterator it = map_.begin(); + it != map_.end(); ++it) { + Message* new_entry = default_entry_->New(MapFieldBase::arena_); + MapFieldBase::repeated_field_->AddAllocated(new_entry); + const MapKey& map_key = it->first; + switch (key_des->cpp_type()) { + case FieldDescriptor::CPPTYPE_STRING: + reflection->SetString(new_entry, key_des, map_key.GetStringValue()); + break; + case FieldDescriptor::CPPTYPE_INT64: + reflection->SetInt64(new_entry, key_des, map_key.GetInt64Value()); + break; + case FieldDescriptor::CPPTYPE_INT32: + reflection->SetInt32(new_entry, key_des, map_key.GetInt32Value()); + break; + case FieldDescriptor::CPPTYPE_UINT64: + reflection->SetUInt64(new_entry, key_des, map_key.GetUInt64Value()); + break; + case FieldDescriptor::CPPTYPE_UINT32: + reflection->SetUInt32(new_entry, key_des, map_key.GetUInt32Value()); + break; + case FieldDescriptor::CPPTYPE_BOOL: + reflection->SetBool(new_entry, key_des, map_key.GetBoolValue()); + break; + case FieldDescriptor::CPPTYPE_DOUBLE: + case FieldDescriptor::CPPTYPE_FLOAT: + case FieldDescriptor::CPPTYPE_ENUM: + case FieldDescriptor::CPPTYPE_MESSAGE: + GOOGLE_LOG(FATAL) << "Can't get here."; + break; + } + const MapValueRef& map_val = it->second; + switch (val_des->cpp_type()) { + case FieldDescriptor::CPPTYPE_STRING: + reflection->SetString(new_entry, val_des, map_val.GetStringValue()); + break; + case FieldDescriptor::CPPTYPE_INT64: + reflection->SetInt64(new_entry, val_des, map_val.GetInt64Value()); + break; + case FieldDescriptor::CPPTYPE_INT32: + reflection->SetInt32(new_entry, val_des, map_val.GetInt32Value()); + break; + case FieldDescriptor::CPPTYPE_UINT64: + reflection->SetUInt64(new_entry, val_des, map_val.GetUInt64Value()); + break; + case FieldDescriptor::CPPTYPE_UINT32: + reflection->SetUInt32(new_entry, val_des, map_val.GetUInt32Value()); + break; + case FieldDescriptor::CPPTYPE_BOOL: + reflection->SetBool(new_entry, val_des, map_val.GetBoolValue()); + break; + case FieldDescriptor::CPPTYPE_DOUBLE: + reflection->SetDouble(new_entry, val_des, map_val.GetDoubleValue()); + break; + case FieldDescriptor::CPPTYPE_FLOAT: + reflection->SetFloat(new_entry, val_des, map_val.GetFloatValue()); + break; + case FieldDescriptor::CPPTYPE_ENUM: + reflection->SetEnumValue(new_entry, val_des, map_val.GetEnumValue()); + break; + case FieldDescriptor::CPPTYPE_MESSAGE: { + const Message& message = map_val.GetMessageValue(); + reflection->MutableMessage(new_entry, val_des)->CopyFrom(message); + break; + } + } + } +} + +void DynamicMapField::SyncMapWithRepeatedFieldNoLock() const { + Map<MapKey, MapValueRef>* map = &const_cast<DynamicMapField*>(this)->map_; + const Reflection* reflection = default_entry_->GetReflection(); + const FieldDescriptor* key_des = default_entry_->GetDescriptor()->map_key(); + const FieldDescriptor* val_des = default_entry_->GetDescriptor()->map_value(); + // DynamicMapField owns map values. Need to delete them before clearing + // the map. + if (MapFieldBase::arena_ == nullptr) { + for (Map<MapKey, MapValueRef>::iterator iter = map->begin(); + iter != map->end(); ++iter) { + iter->second.DeleteData(); + } + } + map->clear(); + for (RepeatedPtrField<Message>::iterator it = + MapFieldBase::repeated_field_->begin(); + it != MapFieldBase::repeated_field_->end(); ++it) { + // MapKey type will be set later. + MapKey map_key; + switch (key_des->cpp_type()) { + case FieldDescriptor::CPPTYPE_STRING: + map_key.SetStringValue(reflection->GetString(*it, key_des)); + break; + case FieldDescriptor::CPPTYPE_INT64: + map_key.SetInt64Value(reflection->GetInt64(*it, key_des)); + break; + case FieldDescriptor::CPPTYPE_INT32: + map_key.SetInt32Value(reflection->GetInt32(*it, key_des)); + break; + case FieldDescriptor::CPPTYPE_UINT64: + map_key.SetUInt64Value(reflection->GetUInt64(*it, key_des)); + break; + case FieldDescriptor::CPPTYPE_UINT32: + map_key.SetUInt32Value(reflection->GetUInt32(*it, key_des)); + break; + case FieldDescriptor::CPPTYPE_BOOL: + map_key.SetBoolValue(reflection->GetBool(*it, key_des)); + break; + case FieldDescriptor::CPPTYPE_DOUBLE: + case FieldDescriptor::CPPTYPE_FLOAT: + case FieldDescriptor::CPPTYPE_ENUM: + case FieldDescriptor::CPPTYPE_MESSAGE: + GOOGLE_LOG(FATAL) << "Can't get here."; + break; + } + + if (MapFieldBase::arena_ == nullptr) { + // Remove existing map value with same key. + Map<MapKey, MapValueRef>::iterator iter = map->find(map_key); + if (iter != map->end()) { + iter->second.DeleteData(); + } + } + + MapValueRef& map_val = (*map)[map_key]; + map_val.SetType(val_des->cpp_type()); + switch (val_des->cpp_type()) { +#define HANDLE_TYPE(CPPTYPE, TYPE, METHOD) \ + case FieldDescriptor::CPPTYPE_##CPPTYPE: { \ + TYPE* value = Arena::Create<TYPE>(MapFieldBase::arena_); \ + *value = reflection->Get##METHOD(*it, val_des); \ + map_val.SetValue(value); \ + break; \ + } + HANDLE_TYPE(INT32, arc_i32, Int32); + HANDLE_TYPE(INT64, arc_i64, Int64); + HANDLE_TYPE(UINT32, arc_ui32, UInt32); + HANDLE_TYPE(UINT64, arc_ui64, UInt64); + HANDLE_TYPE(DOUBLE, double, Double); + HANDLE_TYPE(FLOAT, float, Float); + HANDLE_TYPE(BOOL, bool, Bool); + HANDLE_TYPE(STRING, TProtoStringType, String); + HANDLE_TYPE(ENUM, arc_i32, EnumValue); +#undef HANDLE_TYPE + case FieldDescriptor::CPPTYPE_MESSAGE: { + const Message& message = reflection->GetMessage(*it, val_des); + Message* value = message.New(MapFieldBase::arena_); + value->CopyFrom(message); + map_val.SetValue(value); + break; + } + } + } +} + +size_t DynamicMapField::SpaceUsedExcludingSelfNoLock() const { + size_t size = 0; + if (MapFieldBase::repeated_field_ != nullptr) { + size += MapFieldBase::repeated_field_->SpaceUsedExcludingSelfLong(); + } + size += sizeof(map_); + size_t map_size = map_.size(); + if (map_size) { + Map<MapKey, MapValueRef>::const_iterator it = map_.begin(); + size += sizeof(it->first) * map_size; + size += sizeof(it->second) * map_size; + // If key is string, add the allocated space. + if (it->first.type() == FieldDescriptor::CPPTYPE_STRING) { + size += sizeof(TProtoStringType) * map_size; + } + // Add the allocated space in MapValueRef. + switch (it->second.type()) { +#define HANDLE_TYPE(CPPTYPE, TYPE) \ + case FieldDescriptor::CPPTYPE_##CPPTYPE: { \ + size += sizeof(TYPE) * map_size; \ + break; \ + } + HANDLE_TYPE(INT32, arc_i32); + HANDLE_TYPE(INT64, arc_i64); + HANDLE_TYPE(UINT32, arc_ui32); + HANDLE_TYPE(UINT64, arc_ui64); + HANDLE_TYPE(DOUBLE, double); + HANDLE_TYPE(FLOAT, float); + HANDLE_TYPE(BOOL, bool); + HANDLE_TYPE(STRING, TProtoStringType); + HANDLE_TYPE(ENUM, arc_i32); +#undef HANDLE_TYPE + case FieldDescriptor::CPPTYPE_MESSAGE: { + while (it != map_.end()) { + const Message& message = it->second.GetMessageValue(); + size += message.GetReflection()->SpaceUsedLong(message); + ++it; + } + break; + } + } + } + return size; +} + +} // namespace internal +} // namespace protobuf +} // namespace google + +#include <google/protobuf/port_undef.inc> diff --git a/contrib/libs/protobuf_old/src/google/protobuf/map_field.h b/contrib/libs/protobuf_old/src/google/protobuf/map_field.h new file mode 100644 index 0000000000..f5b7c6177a --- /dev/null +++ b/contrib/libs/protobuf_old/src/google/protobuf/map_field.h @@ -0,0 +1,924 @@ +// 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_MAP_FIELD_H__ +#define GOOGLE_PROTOBUF_MAP_FIELD_H__ + +#include <atomic> +#include <functional> + +#include <google/protobuf/arena.h> +#include <google/protobuf/descriptor.h> +#include <google/protobuf/generated_message_reflection.h> +#include <google/protobuf/generated_message_util.h> +#include <google/protobuf/map_entry.h> +#include <google/protobuf/map_field_lite.h> +#include <google/protobuf/map_type_handler.h> +#include <google/protobuf/message.h> +#include <google/protobuf/stubs/mutex.h> +#include <google/protobuf/stubs/port.h> +#include <google/protobuf/port.h> +#include <google/protobuf/repeated_field.h> +#include <google/protobuf/unknown_field_set.h> + + +#include <google/protobuf/port_def.inc> + +#ifdef SWIG +#error "You cannot SWIG proto headers" +#endif + +namespace google { +namespace protobuf { +class DynamicMessage; +class MapIterator; + +#define TYPE_CHECK(EXPECTEDTYPE, METHOD) \ + if (type() != EXPECTEDTYPE) { \ + GOOGLE_LOG(FATAL) << "Protocol Buffer map usage error:\n" \ + << METHOD << " type does not match\n" \ + << " Expected : " \ + << FieldDescriptor::CppTypeName(EXPECTEDTYPE) << "\n" \ + << " Actual : " << FieldDescriptor::CppTypeName(type()); \ + } + +// MapKey is an union type for representing any possible +// map key. +class PROTOBUF_EXPORT MapKey { + public: + MapKey() : type_() {} + MapKey(const MapKey& other) : type_() { CopyFrom(other); } + + MapKey& operator=(const MapKey& other) { + CopyFrom(other); + return *this; + } + + ~MapKey() { + if (type_ == FieldDescriptor::CPPTYPE_STRING) { + val_.string_value_.Destruct(); + } + } + + FieldDescriptor::CppType type() const { + if (type_ == FieldDescriptor::CppType()) { + GOOGLE_LOG(FATAL) << "Protocol Buffer map usage error:\n" + << "MapKey::type MapKey is not initialized. " + << "Call set methods to initialize MapKey."; + } + return type_; + } + + void SetInt64Value(arc_i64 value) { + SetType(FieldDescriptor::CPPTYPE_INT64); + val_.int64_value_ = value; + } + void SetUInt64Value(arc_ui64 value) { + SetType(FieldDescriptor::CPPTYPE_UINT64); + val_.uint64_value_ = value; + } + void SetInt32Value(arc_i32 value) { + SetType(FieldDescriptor::CPPTYPE_INT32); + val_.int32_value_ = value; + } + void SetUInt32Value(arc_ui32 value) { + SetType(FieldDescriptor::CPPTYPE_UINT32); + val_.uint32_value_ = value; + } + void SetBoolValue(bool value) { + SetType(FieldDescriptor::CPPTYPE_BOOL); + val_.bool_value_ = value; + } + void SetStringValue(TProtoStringType val) { + SetType(FieldDescriptor::CPPTYPE_STRING); + *val_.string_value_.get_mutable() = std::move(val); + } + + arc_i64 GetInt64Value() const { + TYPE_CHECK(FieldDescriptor::CPPTYPE_INT64, "MapKey::GetInt64Value"); + return val_.int64_value_; + } + arc_ui64 GetUInt64Value() const { + TYPE_CHECK(FieldDescriptor::CPPTYPE_UINT64, "MapKey::GetUInt64Value"); + return val_.uint64_value_; + } + arc_i32 GetInt32Value() const { + TYPE_CHECK(FieldDescriptor::CPPTYPE_INT32, "MapKey::GetInt32Value"); + return val_.int32_value_; + } + arc_ui32 GetUInt32Value() const { + TYPE_CHECK(FieldDescriptor::CPPTYPE_UINT32, "MapKey::GetUInt32Value"); + return val_.uint32_value_; + } + bool GetBoolValue() const { + TYPE_CHECK(FieldDescriptor::CPPTYPE_BOOL, "MapKey::GetBoolValue"); + return val_.bool_value_; + } + const TProtoStringType& GetStringValue() const { + TYPE_CHECK(FieldDescriptor::CPPTYPE_STRING, "MapKey::GetStringValue"); + return val_.string_value_.get(); + } + + bool operator<(const MapKey& other) const { + if (type_ != other.type_) { + // We could define a total order that handles this case, but + // there currently no need. So, for now, fail. + GOOGLE_LOG(FATAL) << "Unsupported: type mismatch"; + } + switch (type()) { + case FieldDescriptor::CPPTYPE_DOUBLE: + case FieldDescriptor::CPPTYPE_FLOAT: + case FieldDescriptor::CPPTYPE_ENUM: + case FieldDescriptor::CPPTYPE_MESSAGE: + GOOGLE_LOG(FATAL) << "Unsupported"; + return false; + case FieldDescriptor::CPPTYPE_STRING: + return val_.string_value_.get() < other.val_.string_value_.get(); + case FieldDescriptor::CPPTYPE_INT64: + return val_.int64_value_ < other.val_.int64_value_; + case FieldDescriptor::CPPTYPE_INT32: + return val_.int32_value_ < other.val_.int32_value_; + case FieldDescriptor::CPPTYPE_UINT64: + return val_.uint64_value_ < other.val_.uint64_value_; + case FieldDescriptor::CPPTYPE_UINT32: + return val_.uint32_value_ < other.val_.uint32_value_; + case FieldDescriptor::CPPTYPE_BOOL: + return val_.bool_value_ < other.val_.bool_value_; + } + return false; + } + + bool operator==(const MapKey& other) const { + if (type_ != other.type_) { + // To be consistent with operator<, we don't allow this either. + GOOGLE_LOG(FATAL) << "Unsupported: type mismatch"; + } + switch (type()) { + case FieldDescriptor::CPPTYPE_DOUBLE: + case FieldDescriptor::CPPTYPE_FLOAT: + case FieldDescriptor::CPPTYPE_ENUM: + case FieldDescriptor::CPPTYPE_MESSAGE: + GOOGLE_LOG(FATAL) << "Unsupported"; + break; + case FieldDescriptor::CPPTYPE_STRING: + return val_.string_value_.get() == other.val_.string_value_.get(); + case FieldDescriptor::CPPTYPE_INT64: + return val_.int64_value_ == other.val_.int64_value_; + case FieldDescriptor::CPPTYPE_INT32: + return val_.int32_value_ == other.val_.int32_value_; + case FieldDescriptor::CPPTYPE_UINT64: + return val_.uint64_value_ == other.val_.uint64_value_; + case FieldDescriptor::CPPTYPE_UINT32: + return val_.uint32_value_ == other.val_.uint32_value_; + case FieldDescriptor::CPPTYPE_BOOL: + return val_.bool_value_ == other.val_.bool_value_; + } + GOOGLE_LOG(FATAL) << "Can't get here."; + return false; + } + + void CopyFrom(const MapKey& other) { + SetType(other.type()); + switch (type_) { + case FieldDescriptor::CPPTYPE_DOUBLE: + case FieldDescriptor::CPPTYPE_FLOAT: + case FieldDescriptor::CPPTYPE_ENUM: + case FieldDescriptor::CPPTYPE_MESSAGE: + GOOGLE_LOG(FATAL) << "Unsupported"; + break; + case FieldDescriptor::CPPTYPE_STRING: + *val_.string_value_.get_mutable() = other.val_.string_value_.get(); + break; + case FieldDescriptor::CPPTYPE_INT64: + val_.int64_value_ = other.val_.int64_value_; + break; + case FieldDescriptor::CPPTYPE_INT32: + val_.int32_value_ = other.val_.int32_value_; + break; + case FieldDescriptor::CPPTYPE_UINT64: + val_.uint64_value_ = other.val_.uint64_value_; + break; + case FieldDescriptor::CPPTYPE_UINT32: + val_.uint32_value_ = other.val_.uint32_value_; + break; + case FieldDescriptor::CPPTYPE_BOOL: + val_.bool_value_ = other.val_.bool_value_; + break; + } + } + + private: + template <typename K, typename V> + friend class internal::TypeDefinedMapFieldBase; + friend class ::PROTOBUF_NAMESPACE_ID::MapIterator; + friend class internal::DynamicMapField; + + union KeyValue { + KeyValue() {} + internal::ExplicitlyConstructed<TProtoStringType> string_value_; + arc_i64 int64_value_; + arc_i32 int32_value_; + arc_ui64 uint64_value_; + arc_ui32 uint32_value_; + bool bool_value_; + } val_; + + void SetType(FieldDescriptor::CppType type) { + if (type_ == type) return; + if (type_ == FieldDescriptor::CPPTYPE_STRING) { + val_.string_value_.Destruct(); + } + type_ = type; + if (type_ == FieldDescriptor::CPPTYPE_STRING) { + val_.string_value_.DefaultConstruct(); + } + } + + // type_ is 0 or a valid FieldDescriptor::CppType. + // Use "CppType()" to indicate zero. + FieldDescriptor::CppType type_; +}; + +} // namespace protobuf +} // namespace google +namespace std { +template <> +struct hash<::PROTOBUF_NAMESPACE_ID::MapKey> { + size_t operator()(const ::PROTOBUF_NAMESPACE_ID::MapKey& map_key) const { + switch (map_key.type()) { + case ::PROTOBUF_NAMESPACE_ID::FieldDescriptor::CPPTYPE_DOUBLE: + case ::PROTOBUF_NAMESPACE_ID::FieldDescriptor::CPPTYPE_FLOAT: + case ::PROTOBUF_NAMESPACE_ID::FieldDescriptor::CPPTYPE_ENUM: + case ::PROTOBUF_NAMESPACE_ID::FieldDescriptor::CPPTYPE_MESSAGE: + GOOGLE_LOG(FATAL) << "Unsupported"; + break; + case ::PROTOBUF_NAMESPACE_ID::FieldDescriptor::CPPTYPE_STRING: + return hash<TProtoStringType>()(map_key.GetStringValue()); + case ::PROTOBUF_NAMESPACE_ID::FieldDescriptor::CPPTYPE_INT64: { + auto value = map_key.GetInt64Value(); + return hash<decltype(value)>()(value); + } + case ::PROTOBUF_NAMESPACE_ID::FieldDescriptor::CPPTYPE_INT32: { + auto value = map_key.GetInt32Value(); + return hash<decltype(value)>()(map_key.GetInt32Value()); + } + case ::PROTOBUF_NAMESPACE_ID::FieldDescriptor::CPPTYPE_UINT64: { + auto value = map_key.GetUInt64Value(); + return hash<decltype(value)>()(map_key.GetUInt64Value()); + } + case ::PROTOBUF_NAMESPACE_ID::FieldDescriptor::CPPTYPE_UINT32: { + auto value = map_key.GetUInt32Value(); + return hash<decltype(value)>()(map_key.GetUInt32Value()); + } + case ::PROTOBUF_NAMESPACE_ID::FieldDescriptor::CPPTYPE_BOOL: { + return hash<bool>()(map_key.GetBoolValue()); + } + } + GOOGLE_LOG(FATAL) << "Can't get here."; + return 0; + } + bool operator()(const ::PROTOBUF_NAMESPACE_ID::MapKey& map_key1, + const ::PROTOBUF_NAMESPACE_ID::MapKey& map_key2) const { + return map_key1 < map_key2; + } +}; +} // namespace std + +namespace google { +namespace protobuf { +namespace internal { + +class ContendedMapCleanTest; +class GeneratedMessageReflection; +class MapFieldAccessor; + +// This class provides access to map field using reflection, which is the same +// as those provided for RepeatedPtrField<Message>. It is used for internal +// reflection implementation only. Users should never use this directly. +class PROTOBUF_EXPORT MapFieldBase { + public: + MapFieldBase() + : arena_(nullptr), repeated_field_(nullptr), state_(STATE_MODIFIED_MAP) {} + + // This constructor is for constant initialized global instances. + // It uses a linker initialized mutex, so it is not compatible with regular + // runtime instances. + // Except in MSVC, where we can't have a constinit mutex. + explicit constexpr MapFieldBase(ConstantInitialized) + : arena_(nullptr), + repeated_field_(nullptr), + mutex_(GOOGLE_PROTOBUF_LINKER_INITIALIZED), + state_(STATE_MODIFIED_MAP) {} + explicit MapFieldBase(Arena* arena) + : arena_(arena), repeated_field_(nullptr), state_(STATE_MODIFIED_MAP) {} + virtual ~MapFieldBase(); + + // Returns reference to internal repeated field. Data written using + // Map's api prior to calling this function is guarantted to be + // included in repeated field. + const RepeatedPtrFieldBase& GetRepeatedField() const; + + // Like above. Returns mutable pointer to the internal repeated field. + RepeatedPtrFieldBase* MutableRepeatedField(); + + // Pure virtual map APIs for Map Reflection. + virtual bool ContainsMapKey(const MapKey& map_key) const = 0; + virtual bool InsertOrLookupMapValue(const MapKey& map_key, + MapValueRef* val) = 0; + virtual bool LookupMapValue(const MapKey& map_key, + MapValueConstRef* val) const = 0; + bool LookupMapValue(const MapKey&, MapValueRef*) const = delete; + + // Returns whether changes to the map are reflected in the repeated field. + bool IsRepeatedFieldValid() const; + // Insures operations after won't get executed before calling this. + bool IsMapValid() const; + virtual bool DeleteMapValue(const MapKey& map_key) = 0; + virtual bool EqualIterator(const MapIterator& a, + const MapIterator& b) const = 0; + virtual void MapBegin(MapIterator* map_iter) const = 0; + 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; + + // Returns the number of bytes used by the repeated field, excluding + // sizeof(*this) + size_t SpaceUsedExcludingSelfLong() const; + + int SpaceUsedExcludingSelf() const { + return internal::ToIntSize(SpaceUsedExcludingSelfLong()); + } + + protected: + // Gets the size of space used by map field. + virtual size_t SpaceUsedExcludingSelfNoLock() const; + + // Synchronizes the content in Map to RepeatedPtrField if there is any change + // to Map after last synchronization. + void SyncRepeatedFieldWithMap() const; + virtual void SyncRepeatedFieldWithMapNoLock() const; + + // Synchronizes the content in RepeatedPtrField to Map if there is any change + // to RepeatedPtrField after last synchronization. + void SyncMapWithRepeatedField() const; + virtual void SyncMapWithRepeatedFieldNoLock() const {} + + // Tells MapFieldBase that there is new change to Map. + void SetMapDirty(); + + // Tells MapFieldBase that there is new change to RepeatedPtrField. + void SetRepeatedDirty(); + + // Provides derived class the access to repeated field. + void* MutableRepeatedPtrField() const; + + void InternalSwap(MapFieldBase* other); + + // Support thread sanitizer (tsan) by making const / mutable races + // more apparent. If one thread calls MutableAccess() while another + // thread calls either ConstAccess() or MutableAccess(), on the same + // MapFieldBase-derived object, and there is no synchronization going + // on between them, tsan will alert. +#if defined(__SANITIZE_THREAD__) || defined(THREAD_SANITIZER) + void ConstAccess() const { GOOGLE_CHECK_EQ(seq1_, seq2_); } + void MutableAccess() { + if (seq1_ & 1) { + seq2_ = ++seq1_; + } else { + seq1_ = ++seq2_; + } + } + unsigned int seq1_ = 0, seq2_ = 0; +#else + void ConstAccess() const {} + void MutableAccess() {} +#endif + enum State { + STATE_MODIFIED_MAP = 0, // map has newly added data that has not been + // synchronized to repeated field + STATE_MODIFIED_REPEATED = 1, // repeated field has newly added data that + // has not been synchronized to map + CLEAN = 2, // data in map and repeated field are same + }; + + Arena* arena_; + mutable RepeatedPtrField<Message>* repeated_field_; + + mutable internal::WrappedMutex + mutex_; // The thread to synchronize map and repeated field + // needs to get lock first; + mutable std::atomic<State> state_; + + private: + 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 + // type helper for key and value. Call these help methods to deal with + // different types. Real helper methods are implemented in + // TypeDefinedMapFieldBase. + friend class ::PROTOBUF_NAMESPACE_ID::MapIterator; + // Allocate map<...>::iterator for MapIterator. + virtual void InitializeIterator(MapIterator* map_iter) const = 0; + + // DeleteIterator() is called by the destructor of MapIterator only. + // It deletes map<...>::iterator for MapIterator. + virtual void DeleteIterator(MapIterator* map_iter) const = 0; + + // Copy the map<...>::iterator from other_iterator to + // this_iterator. + virtual void CopyIterator(MapIterator* this_iterator, + const MapIterator& other_iterator) const = 0; + + // IncreaseIterator() is called by operator++() of MapIterator only. + // It implements the ++ operator of MapIterator. + virtual void IncreaseIterator(MapIterator* map_iter) const = 0; + + // Swaps state_ with another MapFieldBase + void SwapState(MapFieldBase* other); + + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(MapFieldBase); +}; + +// This class provides common Map Reflection implementations for generated +// message and dynamic message. +template <typename Key, typename T> +class TypeDefinedMapFieldBase : public MapFieldBase { + public: + TypeDefinedMapFieldBase() {} + + // This constructor is for constant initialized global instances. + // It uses a linker initialized mutex, so it is not compatible with regular + // runtime instances. + explicit constexpr TypeDefinedMapFieldBase(ConstantInitialized tag) + : MapFieldBase(tag) {} + explicit TypeDefinedMapFieldBase(Arena* arena) : MapFieldBase(arena) {} + ~TypeDefinedMapFieldBase() override {} + void MapBegin(MapIterator* map_iter) const override; + void MapEnd(MapIterator* map_iter) const override; + bool EqualIterator(const MapIterator& a, const MapIterator& b) const override; + + virtual const Map<Key, T>& GetMap() const = 0; + virtual Map<Key, T>* MutableMap() = 0; + + protected: + typename Map<Key, T>::const_iterator& InternalGetIterator( + const MapIterator* map_iter) const; + + private: + void InitializeIterator(MapIterator* map_iter) const override; + void DeleteIterator(MapIterator* map_iter) const override; + void CopyIterator(MapIterator* this_iteratorm, + const MapIterator& that_iterator) const override; + void IncreaseIterator(MapIterator* map_iter) const override; + + virtual void SetMapIteratorValue(MapIterator* map_iter) const = 0; + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(TypeDefinedMapFieldBase); +}; + +// This class provides access to map field using generated api. It is used for +// internal generated message implementation only. Users should never use this +// directly. +template <typename Derived, typename Key, typename T, + WireFormatLite::FieldType kKeyFieldType, + WireFormatLite::FieldType kValueFieldType> +class MapField : public TypeDefinedMapFieldBase<Key, T> { + // Provide utilities to parse/serialize key/value. Provide utilities to + // manipulate internal stored type. + typedef MapTypeHandler<kKeyFieldType, Key> KeyTypeHandler; + typedef MapTypeHandler<kValueFieldType, T> ValueTypeHandler; + + // Define message type for internal repeated field. + typedef Derived EntryType; + + // Define abbreviation for parent MapFieldLite + typedef MapFieldLite<Derived, Key, T, kKeyFieldType, kValueFieldType> + MapFieldLiteType; + + // Enum needs to be handled differently from other types because it has + // different exposed type in Map's api and repeated field's api. For + // details see the comment in the implementation of + // SyncMapWithRepeatedFieldNoLock. + static constexpr bool kIsValueEnum = ValueTypeHandler::kIsEnum; + typedef typename MapIf<kIsValueEnum, T, const T&>::type CastValueType; + + public: + typedef typename Derived::SuperType EntryTypeTrait; + typedef Map<Key, T> MapType; + + MapField() {} + + // This constructor is for constant initialized global instances. + // It uses a linker initialized mutex, so it is not compatible with regular + // runtime instances. + explicit constexpr MapField(ConstantInitialized tag) + : TypeDefinedMapFieldBase<Key, T>(tag), impl_() {} + explicit MapField(Arena* arena) + : TypeDefinedMapFieldBase<Key, T>(arena), impl_(arena) {} + + // Implement MapFieldBase + bool ContainsMapKey(const MapKey& map_key) const override; + bool InsertOrLookupMapValue(const MapKey& map_key, MapValueRef* val) override; + bool LookupMapValue(const MapKey& map_key, + MapValueConstRef* val) const override; + bool LookupMapValue(const MapKey&, MapValueRef*) const = delete; + bool DeleteMapValue(const MapKey& map_key) override; + + const Map<Key, T>& GetMap() const override { + MapFieldBase::SyncMapWithRepeatedField(); + return impl_.GetMap(); + } + + Map<Key, T>* MutableMap() override { + MapFieldBase::SyncMapWithRepeatedField(); + Map<Key, T>* result = impl_.MutableMap(); + MapFieldBase::SetMapDirty(); + return result; + } + + int size() const override; + 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 + // arena_ is nullptr. + EntryType* NewEntry() const { return impl_.NewEntry(); } + // Used in the implementation of serializing enum value type. Caller should + // take the ownership iff arena_ is nullptr. + EntryType* NewEnumEntryWrapper(const Key& key, const T t) const { + return impl_.NewEnumEntryWrapper(key, t); + } + // Used in the implementation of serializing other value types. Caller should + // take the ownership iff arena_ is nullptr. + EntryType* NewEntryWrapper(const Key& key, const T& t) const { + return impl_.NewEntryWrapper(key, t); + } + + const char* _InternalParse(const char* ptr, ParseContext* ctx) { + return impl_._InternalParse(ptr, ctx); + } + template <typename UnknownType> + const char* ParseWithEnumValidation(const char* ptr, ParseContext* ctx, + bool (*is_valid)(int), arc_ui32 field_num, + InternalMetadata* metadata) { + return impl_.template ParseWithEnumValidation<UnknownType>( + ptr, ctx, is_valid, field_num, metadata); + } + + private: + MapFieldLiteType impl_; + + typedef void InternalArenaConstructable_; + typedef void DestructorSkippable_; + + // Implements MapFieldBase + void SyncRepeatedFieldWithMapNoLock() const override; + void SyncMapWithRepeatedFieldNoLock() const override; + size_t SpaceUsedExcludingSelfNoLock() const override; + + void SetMapIteratorValue(MapIterator* map_iter) const override; + + friend class ::PROTOBUF_NAMESPACE_ID::Arena; + friend class MapFieldStateTest; // For testing, it needs raw access to impl_ + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(MapField); +}; + +template <typename Derived, typename Key, typename T, + WireFormatLite::FieldType key_wire_type, + WireFormatLite::FieldType value_wire_type> +bool AllAreInitialized( + const MapField<Derived, Key, T, key_wire_type, value_wire_type>& field) { + const auto& t = field.GetMap(); + for (typename Map<Key, T>::const_iterator it = t.begin(); it != t.end(); + ++it) { + if (!it->second.IsInitialized()) return false; + } + return true; +} + +template <typename T, typename Key, typename Value, + WireFormatLite::FieldType kKeyFieldType, + WireFormatLite::FieldType kValueFieldType> +struct MapEntryToMapField< + MapEntry<T, Key, Value, kKeyFieldType, kValueFieldType>> { + typedef MapField<T, Key, Value, kKeyFieldType, kValueFieldType> MapFieldType; +}; + +class PROTOBUF_EXPORT DynamicMapField + : public TypeDefinedMapFieldBase<MapKey, MapValueRef> { + public: + explicit DynamicMapField(const Message* default_entry); + DynamicMapField(const Message* default_entry, Arena* arena); + ~DynamicMapField() override; + + // Implement MapFieldBase + bool ContainsMapKey(const MapKey& map_key) const override; + bool InsertOrLookupMapValue(const MapKey& map_key, MapValueRef* val) override; + bool LookupMapValue(const MapKey& map_key, + MapValueConstRef* val) const override; + bool LookupMapValue(const MapKey&, MapValueRef*) const = delete; + 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; + + int size() const override; + void Clear() override; + + private: + Map<MapKey, MapValueRef> map_; + const Message* default_entry_; + + void AllocateMapValue(MapValueRef* map_val); + + // Implements MapFieldBase + void SyncRepeatedFieldWithMapNoLock() const override; + void SyncMapWithRepeatedFieldNoLock() const override; + size_t SpaceUsedExcludingSelfNoLock() const override; + void SetMapIteratorValue(MapIterator* map_iter) const override; + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(DynamicMapField); +}; + +} // namespace internal + +// MapValueConstRef points to a map value. Users can NOT modify +// the map value. +class PROTOBUF_EXPORT MapValueConstRef { + public: + MapValueConstRef() : data_(nullptr), type_() {} + + arc_i64 GetInt64Value() const { + TYPE_CHECK(FieldDescriptor::CPPTYPE_INT64, + "MapValueConstRef::GetInt64Value"); + return *reinterpret_cast<arc_i64*>(data_); + } + arc_ui64 GetUInt64Value() const { + TYPE_CHECK(FieldDescriptor::CPPTYPE_UINT64, + "MapValueConstRef::GetUInt64Value"); + return *reinterpret_cast<arc_ui64*>(data_); + } + arc_i32 GetInt32Value() const { + TYPE_CHECK(FieldDescriptor::CPPTYPE_INT32, + "MapValueConstRef::GetInt32Value"); + return *reinterpret_cast<arc_i32*>(data_); + } + arc_ui32 GetUInt32Value() const { + TYPE_CHECK(FieldDescriptor::CPPTYPE_UINT32, + "MapValueConstRef::GetUInt32Value"); + return *reinterpret_cast<arc_ui32*>(data_); + } + bool GetBoolValue() const { + TYPE_CHECK(FieldDescriptor::CPPTYPE_BOOL, "MapValueConstRef::GetBoolValue"); + return *reinterpret_cast<bool*>(data_); + } + int GetEnumValue() const { + TYPE_CHECK(FieldDescriptor::CPPTYPE_ENUM, "MapValueConstRef::GetEnumValue"); + return *reinterpret_cast<int*>(data_); + } + const TProtoStringType& GetStringValue() const { + TYPE_CHECK(FieldDescriptor::CPPTYPE_STRING, + "MapValueConstRef::GetStringValue"); + return *reinterpret_cast<TProtoStringType*>(data_); + } + float GetFloatValue() const { + TYPE_CHECK(FieldDescriptor::CPPTYPE_FLOAT, + "MapValueConstRef::GetFloatValue"); + return *reinterpret_cast<float*>(data_); + } + double GetDoubleValue() const { + TYPE_CHECK(FieldDescriptor::CPPTYPE_DOUBLE, + "MapValueConstRef::GetDoubleValue"); + return *reinterpret_cast<double*>(data_); + } + + const Message& GetMessageValue() const { + TYPE_CHECK(FieldDescriptor::CPPTYPE_MESSAGE, + "MapValueConstRef::GetMessageValue"); + return *reinterpret_cast<Message*>(data_); + } + + protected: + // data_ point to a map value. MapValueConstRef does not + // own this value. + void* data_; + // type_ is 0 or a valid FieldDescriptor::CppType. + // Use "CppType()" to indicate zero. + FieldDescriptor::CppType type_; + + FieldDescriptor::CppType type() const { + if (type_ == FieldDescriptor::CppType() || data_ == nullptr) { + GOOGLE_LOG(FATAL) + << "Protocol Buffer map usage error:\n" + << "MapValueConstRef::type MapValueConstRef is not initialized."; + } + return type_; + } + + private: + template <typename Derived, typename K, typename V, + internal::WireFormatLite::FieldType key_wire_type, + internal::WireFormatLite::FieldType value_wire_type> + friend class internal::MapField; + template <typename K, typename V> + friend class internal::TypeDefinedMapFieldBase; + friend class ::PROTOBUF_NAMESPACE_ID::MapIterator; + friend class Reflection; + friend class internal::DynamicMapField; + + void SetType(FieldDescriptor::CppType type) { type_ = type; } + void SetValue(const void* val) { data_ = const_cast<void*>(val); } + void CopyFrom(const MapValueConstRef& other) { + type_ = other.type_; + data_ = other.data_; + } +}; + +// MapValueRef points to a map value. Users are able to modify +// the map value. +class PROTOBUF_EXPORT MapValueRef final : public MapValueConstRef { + public: + MapValueRef() {} + + void SetInt64Value(arc_i64 value) { + TYPE_CHECK(FieldDescriptor::CPPTYPE_INT64, "MapValueRef::SetInt64Value"); + *reinterpret_cast<arc_i64*>(data_) = value; + } + void SetUInt64Value(arc_ui64 value) { + TYPE_CHECK(FieldDescriptor::CPPTYPE_UINT64, "MapValueRef::SetUInt64Value"); + *reinterpret_cast<arc_ui64*>(data_) = value; + } + void SetInt32Value(arc_i32 value) { + TYPE_CHECK(FieldDescriptor::CPPTYPE_INT32, "MapValueRef::SetInt32Value"); + *reinterpret_cast<arc_i32*>(data_) = value; + } + void SetUInt32Value(arc_ui32 value) { + TYPE_CHECK(FieldDescriptor::CPPTYPE_UINT32, "MapValueRef::SetUInt32Value"); + *reinterpret_cast<arc_ui32*>(data_) = value; + } + void SetBoolValue(bool value) { + TYPE_CHECK(FieldDescriptor::CPPTYPE_BOOL, "MapValueRef::SetBoolValue"); + *reinterpret_cast<bool*>(data_) = value; + } + // TODO(jieluo) - Checks that enum is member. + void SetEnumValue(int value) { + TYPE_CHECK(FieldDescriptor::CPPTYPE_ENUM, "MapValueRef::SetEnumValue"); + *reinterpret_cast<int*>(data_) = value; + } + void SetStringValue(const TProtoStringType& value) { + TYPE_CHECK(FieldDescriptor::CPPTYPE_STRING, "MapValueRef::SetStringValue"); + *reinterpret_cast<TProtoStringType*>(data_) = value; + } + void SetFloatValue(float value) { + TYPE_CHECK(FieldDescriptor::CPPTYPE_FLOAT, "MapValueRef::SetFloatValue"); + *reinterpret_cast<float*>(data_) = value; + } + void SetDoubleValue(double value) { + TYPE_CHECK(FieldDescriptor::CPPTYPE_DOUBLE, "MapValueRef::SetDoubleValue"); + *reinterpret_cast<double*>(data_) = value; + } + + Message* MutableMessageValue() { + TYPE_CHECK(FieldDescriptor::CPPTYPE_MESSAGE, + "MapValueRef::MutableMessageValue"); + return reinterpret_cast<Message*>(data_); + } + + private: + friend class internal::DynamicMapField; + + // Only used in DynamicMapField + void DeleteData() { + switch (type_) { +#define HANDLE_TYPE(CPPTYPE, TYPE) \ + case FieldDescriptor::CPPTYPE_##CPPTYPE: { \ + delete reinterpret_cast<TYPE*>(data_); \ + break; \ + } + HANDLE_TYPE(INT32, arc_i32); + HANDLE_TYPE(INT64, arc_i64); + HANDLE_TYPE(UINT32, arc_ui32); + HANDLE_TYPE(UINT64, arc_ui64); + HANDLE_TYPE(DOUBLE, double); + HANDLE_TYPE(FLOAT, float); + HANDLE_TYPE(BOOL, bool); + HANDLE_TYPE(STRING, TProtoStringType); + HANDLE_TYPE(ENUM, arc_i32); + HANDLE_TYPE(MESSAGE, Message); +#undef HANDLE_TYPE + } + } +}; + +#undef TYPE_CHECK + +class PROTOBUF_EXPORT MapIterator { + public: + MapIterator(Message* message, const FieldDescriptor* field) { + const Reflection* reflection = message->GetReflection(); + map_ = reflection->MutableMapData(message, field); + key_.SetType(field->message_type()->FindFieldByName("key")->cpp_type()); + value_.SetType(field->message_type()->FindFieldByName("value")->cpp_type()); + map_->InitializeIterator(this); + } + MapIterator(const MapIterator& other) { + map_ = other.map_; + map_->InitializeIterator(this); + map_->CopyIterator(this, other); + } + ~MapIterator() { map_->DeleteIterator(this); } + MapIterator& operator=(const MapIterator& other) { + map_ = other.map_; + map_->CopyIterator(this, other); + return *this; + } + friend bool operator==(const MapIterator& a, const MapIterator& b) { + return a.map_->EqualIterator(a, b); + } + friend bool operator!=(const MapIterator& a, const MapIterator& b) { + return !a.map_->EqualIterator(a, b); + } + MapIterator& operator++() { + map_->IncreaseIterator(this); + return *this; + } + MapIterator operator++(int) { + // iter_ is copied from Map<...>::iterator, no need to + // copy from its self again. Use the same implementation + // with operator++() + map_->IncreaseIterator(this); + return *this; + } + const MapKey& GetKey() { return key_; } + const MapValueRef& GetValueRef() { return value_; } + MapValueRef* MutableValueRef() { + map_->SetMapDirty(); + return &value_; + } + + private: + template <typename Key, typename T> + friend class internal::TypeDefinedMapFieldBase; + friend class internal::DynamicMapField; + template <typename Derived, typename Key, typename T, + internal::WireFormatLite::FieldType kKeyFieldType, + internal::WireFormatLite::FieldType kValueFieldType> + friend class internal::MapField; + + // reinterpret_cast from heap-allocated Map<...>::iterator*. MapIterator owns + // the iterator. It is allocated by MapField<...>::InitializeIterator() called + // in constructor and deleted by MapField<...>::DeleteIterator() called in + // destructor. + void* iter_; + // Point to a MapField to call helper methods implemented in MapField. + // MapIterator does not own this object. + internal::MapFieldBase* map_; + MapKey key_; + MapValueRef value_; +}; + +} // namespace protobuf +} // namespace google + +#include <google/protobuf/port_undef.inc> + +#endif // GOOGLE_PROTOBUF_MAP_FIELD_H__ diff --git a/contrib/libs/protobuf_old/src/google/protobuf/map_field_inl.h b/contrib/libs/protobuf_old/src/google/protobuf/map_field_inl.h new file mode 100644 index 0000000000..4d4abd2224 --- /dev/null +++ b/contrib/libs/protobuf_old/src/google/protobuf/map_field_inl.h @@ -0,0 +1,375 @@ +// 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_MAP_FIELD_INL_H__ +#define GOOGLE_PROTOBUF_MAP_FIELD_INL_H__ + +#include <memory> + +#include <google/protobuf/stubs/casts.h> +#include <google/protobuf/map.h> +#include <google/protobuf/map_field.h> +#include <google/protobuf/map_type_handler.h> + +#ifdef SWIG +#error "You cannot SWIG proto headers" +#endif + +namespace google { +namespace protobuf { +namespace internal { +// UnwrapMapKey template +template <typename T> +T UnwrapMapKey(const MapKey& map_key); +template <> +inline arc_i32 UnwrapMapKey<arc_i32>(const MapKey& map_key) { + return map_key.GetInt32Value(); +} +template <> +inline arc_ui32 UnwrapMapKey<arc_ui32>(const MapKey& map_key) { + return map_key.GetUInt32Value(); +} +template <> +inline arc_i64 UnwrapMapKey<arc_i64>(const MapKey& map_key) { + return map_key.GetInt64Value(); +} +template <> +inline arc_ui64 UnwrapMapKey<arc_ui64>(const MapKey& map_key) { + return map_key.GetUInt64Value(); +} +template <> +inline bool UnwrapMapKey<bool>(const MapKey& map_key) { + return map_key.GetBoolValue(); +} +template <> +inline TProtoStringType UnwrapMapKey<TProtoStringType>(const MapKey& map_key) { + return map_key.GetStringValue(); +} + +// SetMapKey template +template <typename T> +inline void SetMapKey(MapKey* map_key, const T& value); +template <> +inline void SetMapKey<arc_i32>(MapKey* map_key, const arc_i32& value) { + map_key->SetInt32Value(value); +} +template <> +inline void SetMapKey<arc_ui32>(MapKey* map_key, const arc_ui32& value) { + map_key->SetUInt32Value(value); +} +template <> +inline void SetMapKey<arc_i64>(MapKey* map_key, const arc_i64& value) { + map_key->SetInt64Value(value); +} +template <> +inline void SetMapKey<arc_ui64>(MapKey* map_key, const arc_ui64& value) { + map_key->SetUInt64Value(value); +} +template <> +inline void SetMapKey<bool>(MapKey* map_key, const bool& value) { + map_key->SetBoolValue(value); +} +template <> +inline void SetMapKey<TProtoStringType>(MapKey* map_key, const TProtoStringType& value) { + map_key->SetStringValue(value); +} + +// ------------------------TypeDefinedMapFieldBase--------------- +template <typename Key, typename T> +typename Map<Key, T>::const_iterator& +TypeDefinedMapFieldBase<Key, T>::InternalGetIterator( + const MapIterator* map_iter) const { + return *reinterpret_cast<typename Map<Key, T>::const_iterator*>( + map_iter->iter_); +} + +template <typename Key, typename T> +void TypeDefinedMapFieldBase<Key, T>::MapBegin(MapIterator* map_iter) const { + InternalGetIterator(map_iter) = GetMap().begin(); + SetMapIteratorValue(map_iter); +} + +template <typename Key, typename T> +void TypeDefinedMapFieldBase<Key, T>::MapEnd(MapIterator* map_iter) const { + InternalGetIterator(map_iter) = GetMap().end(); +} + +template <typename Key, typename T> +bool TypeDefinedMapFieldBase<Key, T>::EqualIterator( + const MapIterator& a, const MapIterator& b) const { + return InternalGetIterator(&a) == InternalGetIterator(&b); +} + +template <typename Key, typename T> +void TypeDefinedMapFieldBase<Key, T>::IncreaseIterator( + MapIterator* map_iter) const { + ++InternalGetIterator(map_iter); + SetMapIteratorValue(map_iter); +} + +template <typename Key, typename T> +void TypeDefinedMapFieldBase<Key, T>::InitializeIterator( + MapIterator* map_iter) const { + map_iter->iter_ = new typename Map<Key, T>::const_iterator; + GOOGLE_CHECK(map_iter->iter_ != nullptr); +} + +template <typename Key, typename T> +void TypeDefinedMapFieldBase<Key, T>::DeleteIterator( + MapIterator* map_iter) const { + delete reinterpret_cast<typename Map<Key, T>::const_iterator*>( + map_iter->iter_); +} + +template <typename Key, typename T> +void TypeDefinedMapFieldBase<Key, T>::CopyIterator( + MapIterator* this_iter, const MapIterator& that_iter) const { + InternalGetIterator(this_iter) = InternalGetIterator(&that_iter); + this_iter->key_.SetType(that_iter.key_.type()); + // MapValueRef::type() fails when containing data is null. However, if + // this_iter points to MapEnd, data can be null. + this_iter->value_.SetType( + static_cast<FieldDescriptor::CppType>(that_iter.value_.type_)); + SetMapIteratorValue(this_iter); +} + +// ---------------------------------------------------------------------- + +template <typename Derived, typename Key, typename T, + WireFormatLite::FieldType kKeyFieldType, + WireFormatLite::FieldType kValueFieldType> +int MapField<Derived, Key, T, kKeyFieldType, kValueFieldType>::size() const { + MapFieldBase::SyncMapWithRepeatedField(); + return static_cast<int>(impl_.GetMap().size()); +} + +template <typename Derived, typename Key, typename T, + WireFormatLite::FieldType kKeyFieldType, + WireFormatLite::FieldType kValueFieldType> +void MapField<Derived, Key, T, kKeyFieldType, kValueFieldType>::Clear() { + if (this->MapFieldBase::repeated_field_ != nullptr) { + RepeatedPtrField<EntryType>* repeated_field = + reinterpret_cast<RepeatedPtrField<EntryType>*>( + this->MapFieldBase::repeated_field_); + repeated_field->Clear(); + } + + impl_.MutableMap()->clear(); + // Data in map and repeated field are both empty, but we can't set status + // CLEAN. Because clear is a generated API, we cannot invalidate previous + // reference to map. + MapFieldBase::SetMapDirty(); +} + +template <typename Derived, typename Key, typename T, + WireFormatLite::FieldType kKeyFieldType, + WireFormatLite::FieldType kValueFieldType> +void MapField<Derived, Key, T, kKeyFieldType, + kValueFieldType>::SetMapIteratorValue(MapIterator* map_iter) + const { + const Map<Key, T>& map = impl_.GetMap(); + typename Map<Key, T>::const_iterator iter = + TypeDefinedMapFieldBase<Key, T>::InternalGetIterator(map_iter); + if (iter == map.end()) return; + SetMapKey(&map_iter->key_, iter->first); + map_iter->value_.SetValue(&iter->second); +} + +template <typename Derived, typename Key, typename T, + WireFormatLite::FieldType kKeyFieldType, + WireFormatLite::FieldType kValueFieldType> +bool MapField<Derived, Key, T, kKeyFieldType, kValueFieldType>::ContainsMapKey( + const MapKey& map_key) const { + const Map<Key, T>& map = impl_.GetMap(); + const Key& key = UnwrapMapKey<Key>(map_key); + typename Map<Key, T>::const_iterator iter = map.find(key); + return iter != map.end(); +} + +template <typename Derived, typename Key, typename T, + WireFormatLite::FieldType kKeyFieldType, + WireFormatLite::FieldType kValueFieldType> +bool MapField<Derived, Key, T, kKeyFieldType, + kValueFieldType>::InsertOrLookupMapValue(const MapKey& map_key, + MapValueRef* val) { + // Always use mutable map because users may change the map value by + // MapValueRef. + Map<Key, T>* map = MutableMap(); + const Key& key = UnwrapMapKey<Key>(map_key); + typename Map<Key, T>::iterator iter = map->find(key); + if (map->end() == iter) { + val->SetValue(&((*map)[key])); + return true; + } + // Key is already in the map. Make sure (*map)[key] is not called. + // [] may reorder the map and iterators. + val->SetValue(&(iter->second)); + return false; +} + +template <typename Derived, typename Key, typename T, + WireFormatLite::FieldType kKeyFieldType, + WireFormatLite::FieldType kValueFieldType> +bool MapField<Derived, Key, T, kKeyFieldType, kValueFieldType>::LookupMapValue( + const MapKey& map_key, MapValueConstRef* val) const { + const Map<Key, T>& map = GetMap(); + const Key& key = UnwrapMapKey<Key>(map_key); + typename Map<Key, T>::const_iterator iter = map.find(key); + if (map.end() == iter) { + return false; + } + // Key is already in the map. Make sure (*map)[key] is not called. + // [] may reorder the map and iterators. + val->SetValue(&(iter->second)); + return true; +} + +template <typename Derived, typename Key, typename T, + WireFormatLite::FieldType kKeyFieldType, + WireFormatLite::FieldType kValueFieldType> +bool MapField<Derived, Key, T, kKeyFieldType, kValueFieldType>::DeleteMapValue( + const MapKey& map_key) { + const Key& key = UnwrapMapKey<Key>(map_key); + return MutableMap()->erase(key); +} + +template <typename Derived, typename Key, typename T, + WireFormatLite::FieldType kKeyFieldType, + WireFormatLite::FieldType kValueFieldType> +void MapField<Derived, Key, T, kKeyFieldType, kValueFieldType>::MergeFrom( + const MapFieldBase& other) { + MapFieldBase::SyncMapWithRepeatedField(); + const MapField& other_field = static_cast<const MapField&>(other); + other_field.SyncMapWithRepeatedField(); + impl_.MergeFrom(other_field.impl_); + MapFieldBase::SetMapDirty(); +} + +template <typename Derived, typename Key, typename T, + WireFormatLite::FieldType kKeyFieldType, + WireFormatLite::FieldType kValueFieldType> +void MapField<Derived, Key, T, kKeyFieldType, kValueFieldType>::Swap( + MapFieldBase* other) { + MapFieldBase::Swap(other); + MapField* other_field = down_cast<MapField*>(other); + 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> +void MapField<Derived, Key, T, kKeyFieldType, kValueFieldType>::InternalSwap( + MapField* other) { + MapFieldBase::InternalSwap(other); + impl_.InternalSwap(&other->impl_); +} + +template <typename Derived, typename Key, typename T, + WireFormatLite::FieldType kKeyFieldType, + WireFormatLite::FieldType kValueFieldType> +void MapField<Derived, Key, T, kKeyFieldType, + kValueFieldType>::SyncRepeatedFieldWithMapNoLock() const { + if (this->MapFieldBase::repeated_field_ == nullptr) { + this->MapFieldBase::repeated_field_ = + Arena::CreateMessage<RepeatedPtrField<Message> >( + this->MapFieldBase::arena_); + } + const Map<Key, T>& map = impl_.GetMap(); + RepeatedPtrField<EntryType>* repeated_field = + reinterpret_cast<RepeatedPtrField<EntryType>*>( + this->MapFieldBase::repeated_field_); + + repeated_field->Clear(); + + // The only way we can get at this point is through reflection and the + // only way we can get the reflection object is by having called GetReflection + // on the encompassing field. So that type must have existed and hence we + // know that this MapEntry default_type has also already been constructed. + // So it's safe to just call internal_default_instance(). + const Message* default_entry = Derived::internal_default_instance(); + for (typename Map<Key, T>::const_iterator it = map.begin(); it != map.end(); + ++it) { + EntryType* new_entry = + down_cast<EntryType*>(default_entry->New(this->MapFieldBase::arena_)); + repeated_field->AddAllocated(new_entry); + (*new_entry->mutable_key()) = it->first; + (*new_entry->mutable_value()) = it->second; + } +} + +template <typename Derived, typename Key, typename T, + WireFormatLite::FieldType kKeyFieldType, + WireFormatLite::FieldType kValueFieldType> +void MapField<Derived, Key, T, kKeyFieldType, + kValueFieldType>::SyncMapWithRepeatedFieldNoLock() const { + Map<Key, T>* map = const_cast<MapField*>(this)->impl_.MutableMap(); + RepeatedPtrField<EntryType>* repeated_field = + reinterpret_cast<RepeatedPtrField<EntryType>*>( + this->MapFieldBase::repeated_field_); + GOOGLE_CHECK(this->MapFieldBase::repeated_field_ != nullptr); + map->clear(); + for (typename RepeatedPtrField<EntryType>::iterator it = + repeated_field->begin(); + it != repeated_field->end(); ++it) { + // Cast is needed because Map's api and internal storage is different when + // value is enum. For enum, we cannot cast an int to enum. Thus, we have to + // copy value. For other types, they have same exposed api type and internal + // stored type. We should not introduce value copy for them. We achieve this + // by casting to value for enum while casting to reference for other types. + (*map)[it->key()] = static_cast<CastValueType>(it->value()); + } +} + +template <typename Derived, typename Key, typename T, + WireFormatLite::FieldType kKeyFieldType, + WireFormatLite::FieldType kValueFieldType> +size_t MapField<Derived, Key, T, kKeyFieldType, + kValueFieldType>::SpaceUsedExcludingSelfNoLock() const { + size_t size = 0; + if (this->MapFieldBase::repeated_field_ != nullptr) { + size += this->MapFieldBase::repeated_field_->SpaceUsedExcludingSelfLong(); + } + size += impl_.GetMap().SpaceUsedExcludingSelfLong(); + + return size; +} +} // namespace internal +} // namespace protobuf +} // namespace google + +#endif // GOOGLE_PROTOBUF_MAP_FIELD_INL_H__ diff --git a/contrib/libs/protobuf_old/src/google/protobuf/map_field_lite.h b/contrib/libs/protobuf_old/src/google/protobuf/map_field_lite.h new file mode 100644 index 0000000000..c86e4af824 --- /dev/null +++ b/contrib/libs/protobuf_old/src/google/protobuf/map_field_lite.h @@ -0,0 +1,184 @@ +// 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_MAP_FIELD_LITE_H__ +#define GOOGLE_PROTOBUF_MAP_FIELD_LITE_H__ + +#include <type_traits> +#include <google/protobuf/parse_context.h> +#include <google/protobuf/io/coded_stream.h> +#include <google/protobuf/map.h> +#include <google/protobuf/map_entry_lite.h> +#include <google/protobuf/port.h> +#include <google/protobuf/wire_format_lite.h> + +#include <google/protobuf/port_def.inc> + +#ifdef SWIG +#error "You cannot SWIG proto headers" +#endif + +namespace google { +namespace protobuf { +namespace internal { + +// This class provides access to map field using generated api. It is used for +// internal generated message implementation only. Users should never use this +// directly. +template <typename Derived, typename Key, typename T, + WireFormatLite::FieldType key_wire_type, + WireFormatLite::FieldType value_wire_type> +class MapFieldLite { + // Define message type for internal repeated field. + typedef Derived EntryType; + + public: + typedef Map<Key, T> MapType; + typedef EntryType EntryTypeTrait; + + constexpr MapFieldLite() {} + + explicit MapFieldLite(Arena* arena) : map_(arena) {} + + // Accessors + const Map<Key, T>& GetMap() const { return map_; } + Map<Key, T>* MutableMap() { return &map_; } + + // Convenient methods for generated message implementation. + int size() const { return static_cast<int>(map_.size()); } + void Clear() { return map_.clear(); } + void MergeFrom(const MapFieldLite& other) { + for (typename Map<Key, T>::const_iterator it = other.map_.begin(); + it != other.map_.end(); ++it) { + map_[it->first] = it->second; + } + } + void Swap(MapFieldLite* other) { map_.swap(other->map_); } + void InternalSwap(MapFieldLite* other) { map_.InternalSwap(other->map_); } + + // Used in the implementation of parsing. Caller should take the ownership iff + // arena_ is nullptr. + EntryType* NewEntry() const { + return Arena::CreateMessage<EntryType>(map_.arena()); + } + // Used in the implementation of serializing enum value type. Caller should + // take the ownership iff arena_ is nullptr. + EntryType* NewEnumEntryWrapper(const Key& key, const T t) const { + return EntryType::EnumWrap(key, t, map_.arena_); + } + // Used in the implementation of serializing other value types. Caller should + // take the ownership iff arena_ is nullptr. + EntryType* NewEntryWrapper(const Key& key, const T& t) const { + return EntryType::Wrap(key, t, map_.arena_); + } + + const char* _InternalParse(const char* ptr, ParseContext* ctx) { + typename Derived::template Parser<MapFieldLite, Map<Key, T>> parser(this); + return parser._InternalParse(ptr, ctx); + } + + template <typename UnknownType> + const char* ParseWithEnumValidation(const char* ptr, ParseContext* ctx, + bool (*is_valid)(int), arc_ui32 field_num, + InternalMetadata* metadata) { + typename Derived::template Parser<MapFieldLite, Map<Key, T>> parser(this); + return parser.template ParseWithEnumValidation<UnknownType>( + ptr, ctx, is_valid, field_num, metadata); + } + + private: + typedef void DestructorSkippable_; + + Map<Key, T> map_; + + friend class ::PROTOBUF_NAMESPACE_ID::Arena; +}; + +template <typename UnknownType, typename T> +struct EnumParseWrapper { + const char* _InternalParse(const char* ptr, ParseContext* ctx) { + return map_field->template ParseWithEnumValidation<UnknownType>( + ptr, ctx, is_valid, field_num, metadata); + } + T* map_field; + bool (*is_valid)(int); + arc_ui32 field_num; + InternalMetadata* metadata; +}; + +// Helper function because the typenames of maps are horrendous to print. This +// leverages compiler type deduction, to keep all type data out of the +// generated code +template <typename UnknownType, typename T> +EnumParseWrapper<UnknownType, T> InitEnumParseWrapper( + T* map_field, bool (*is_valid)(int), arc_ui32 field_num, + InternalMetadata* metadata) { + return EnumParseWrapper<UnknownType, T>{map_field, is_valid, field_num, + metadata}; +} + +// True if IsInitialized() is true for value field in all elements of t. T is +// expected to be message. It's useful to have this helper here to keep the +// protobuf compiler from ever having to emit loops in IsInitialized() methods. +// We want the C++ compiler to inline this or not as it sees fit. +template <typename Derived, typename Key, typename T, + WireFormatLite::FieldType key_wire_type, + WireFormatLite::FieldType value_wire_type> +bool AllAreInitialized(const MapFieldLite<Derived, Key, T, key_wire_type, + value_wire_type>& field) { + const auto& t = field.GetMap(); + for (typename Map<Key, T>::const_iterator it = t.begin(); it != t.end(); + ++it) { + if (!it->second.IsInitialized()) return false; + } + return true; +} + +template <typename MEntry> +struct MapEntryToMapField : MapEntryToMapField<typename MEntry::SuperType> {}; + +template <typename T, typename Key, typename Value, + WireFormatLite::FieldType kKeyFieldType, + WireFormatLite::FieldType kValueFieldType> +struct MapEntryToMapField< + MapEntryLite<T, Key, Value, kKeyFieldType, kValueFieldType>> { + typedef MapFieldLite< + MapEntryLite<T, Key, Value, kKeyFieldType, kValueFieldType>, Key, Value, + kKeyFieldType, kValueFieldType> + MapFieldType; +}; + +} // namespace internal +} // namespace protobuf +} // namespace google + +#include <google/protobuf/port_undef.inc> + +#endif // GOOGLE_PROTOBUF_MAP_FIELD_LITE_H__ diff --git a/contrib/libs/protobuf_old/src/google/protobuf/map_type_handler.h b/contrib/libs/protobuf_old/src/google/protobuf/map_type_handler.h new file mode 100644 index 0000000000..db7f6fdbb3 --- /dev/null +++ b/contrib/libs/protobuf_old/src/google/protobuf/map_type_handler.h @@ -0,0 +1,691 @@ +// 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_MAP_TYPE_HANDLER_H__ +#define GOOGLE_PROTOBUF_MAP_TYPE_HANDLER_H__ + +#include <google/protobuf/parse_context.h> +#include <google/protobuf/io/coded_stream.h> +#include <google/protobuf/arena.h> +#include <google/protobuf/wire_format_lite.h> + +#ifdef SWIG +#error "You cannot SWIG proto headers" +#endif + +namespace google { +namespace protobuf { +namespace internal { + +// Used for compile time type selection. MapIf::type will be TrueType if Flag is +// true and FalseType otherwise. +template <bool Flag, typename TrueType, typename FalseType> +struct MapIf; + +template <typename TrueType, typename FalseType> +struct MapIf<true, TrueType, FalseType> { + typedef TrueType type; +}; + +template <typename TrueType, typename FalseType> +struct MapIf<false, TrueType, FalseType> { + typedef FalseType type; +}; + +template <typename Type, bool is_arena_constructable> +class MapArenaMessageCreator { + public: + // Use arena to create message if Type is arena constructable. Otherwise, + // create the message on heap. + static inline Type* CreateMessage(Arena* arena); +}; +template <typename Type> +class MapArenaMessageCreator<Type, true> { + public: + static inline Type* CreateMessage(Arena* arena) { + return Arena::CreateMessage<Type>(arena); + } +}; +template <typename Type> +class MapArenaMessageCreator<Type, false> { + public: + static inline Type* CreateMessage(Arena* arena) { + return Arena::Create<Type>(arena); + } +}; + +// Define constants for given wire field type +template <WireFormatLite::FieldType field_type, typename Type> +class MapWireFieldTypeTraits {}; + +#define TYPE_TRAITS(FieldType, CType, WireFormatType, IsMessage, IsEnum) \ + template <typename Type> \ + class MapWireFieldTypeTraits<WireFormatLite::TYPE_##FieldType, Type> { \ + public: \ + static const bool kIsMessage = IsMessage; \ + static const bool kIsEnum = IsEnum; \ + typedef typename MapIf<kIsMessage, Type*, CType>::type TypeOnMemory; \ + typedef typename MapIf<kIsEnum, int, Type>::type MapEntryAccessorType; \ + static const WireFormatLite::WireType kWireType = \ + WireFormatLite::WIRETYPE_##WireFormatType; \ + }; + +TYPE_TRAITS(MESSAGE, Type, LENGTH_DELIMITED, true, false) +TYPE_TRAITS(STRING, ArenaStringPtr, LENGTH_DELIMITED, false, false) +TYPE_TRAITS(BYTES, ArenaStringPtr, LENGTH_DELIMITED, false, false) +TYPE_TRAITS(INT64, arc_i64, VARINT, false, false) +TYPE_TRAITS(UINT64, arc_ui64, VARINT, false, false) +TYPE_TRAITS(INT32, arc_i32, VARINT, false, false) +TYPE_TRAITS(UINT32, arc_ui32, VARINT, false, false) +TYPE_TRAITS(SINT64, arc_i64, VARINT, false, false) +TYPE_TRAITS(SINT32, arc_i32, VARINT, false, false) +TYPE_TRAITS(ENUM, int, VARINT, false, true) +TYPE_TRAITS(DOUBLE, double, FIXED64, false, false) +TYPE_TRAITS(FLOAT, float, FIXED32, false, false) +TYPE_TRAITS(FIXED64, arc_ui64, FIXED64, false, false) +TYPE_TRAITS(FIXED32, arc_ui32, FIXED32, false, false) +TYPE_TRAITS(SFIXED64, arc_i64, FIXED64, false, false) +TYPE_TRAITS(SFIXED32, arc_i32, FIXED32, false, false) +TYPE_TRAITS(BOOL, bool, VARINT, false, false) + +#undef TYPE_TRAITS + +template <WireFormatLite::FieldType field_type, typename Type> +class MapTypeHandler {}; + +template <typename Type> +class MapTypeHandler<WireFormatLite::TYPE_MESSAGE, Type> { + public: + // Enum type cannot be used for MapTypeHandler::Read. Define a type which will + // replace Enum with int. + typedef typename MapWireFieldTypeTraits<WireFormatLite::TYPE_MESSAGE, + Type>::MapEntryAccessorType + MapEntryAccessorType; + // Internal stored type in MapEntryLite for given wire field type. + typedef typename MapWireFieldTypeTraits<WireFormatLite::TYPE_MESSAGE, + Type>::TypeOnMemory TypeOnMemory; + // Corresponding wire type for field type. + static constexpr WireFormatLite::WireType kWireType = + MapWireFieldTypeTraits<WireFormatLite::TYPE_MESSAGE, Type>::kWireType; + // Whether wire type is for message. + static constexpr bool kIsMessage = + MapWireFieldTypeTraits<WireFormatLite::TYPE_MESSAGE, Type>::kIsMessage; + // Whether wire type is for enum. + static constexpr bool kIsEnum = + MapWireFieldTypeTraits<WireFormatLite::TYPE_MESSAGE, Type>::kIsEnum; + + // Functions used in parsing and serialization. =================== + static inline size_t ByteSize(const MapEntryAccessorType& value); + static inline int GetCachedSize(const MapEntryAccessorType& value); + static inline bool Read(io::CodedInputStream* input, + MapEntryAccessorType* value); + static inline const char* Read(const char* ptr, ParseContext* ctx, + MapEntryAccessorType* value); + + static inline uint8_t* Write(int field, const MapEntryAccessorType& value, + uint8_t* ptr, io::EpsCopyOutputStream* stream); + + // Functions to manipulate data on memory. ======================== + static inline const Type& GetExternalReference(const Type* value); + static inline void DeleteNoArena(const Type* x); + static inline void Merge(const Type& from, Type** to, Arena* arena); + static inline void Clear(Type** value, Arena* arena); + static constexpr TypeOnMemory Constinit(); + + static inline Type* EnsureMutable(Type** value, Arena* arena); + // SpaceUsedInMapEntry: Return bytes used by value in MapEntry, excluding + // those already calculate in sizeof(MapField). + static inline size_t SpaceUsedInMapEntryLong(const Type* value); + // Return default instance if value is not initialized when calling const + // reference accessor. + static inline const Type& DefaultIfNotInitialized(const Type* value); + // Check if all required fields have values set. + static inline bool IsInitialized(Type* value); +}; + +#define MAP_HANDLER(FieldType) \ + template <typename Type> \ + class MapTypeHandler<WireFormatLite::TYPE_##FieldType, Type> { \ + public: \ + typedef typename MapWireFieldTypeTraits<WireFormatLite::TYPE_##FieldType, \ + Type>::MapEntryAccessorType \ + MapEntryAccessorType; \ + typedef typename MapWireFieldTypeTraits<WireFormatLite::TYPE_##FieldType, \ + Type>::TypeOnMemory TypeOnMemory; \ + static const WireFormatLite::WireType kWireType = \ + MapWireFieldTypeTraits<WireFormatLite::TYPE_##FieldType, \ + Type>::kWireType; \ + static const bool kIsMessage = \ + MapWireFieldTypeTraits<WireFormatLite::TYPE_##FieldType, \ + Type>::kIsMessage; \ + static const bool kIsEnum = \ + MapWireFieldTypeTraits<WireFormatLite::TYPE_##FieldType, \ + Type>::kIsEnum; \ + static inline int ByteSize(const MapEntryAccessorType& value); \ + static inline int GetCachedSize(const MapEntryAccessorType& value); \ + static inline bool Read(io::CodedInputStream* input, \ + MapEntryAccessorType* value); \ + static inline const char* Read(const char* begin, ParseContext* ctx, \ + MapEntryAccessorType* value); \ + static inline uint8_t* Write(int field, const MapEntryAccessorType& value, \ + uint8_t* ptr, \ + io::EpsCopyOutputStream* stream); \ + static inline const MapEntryAccessorType& GetExternalReference( \ + const TypeOnMemory& value); \ + static inline void DeleteNoArena(const TypeOnMemory& x); \ + static inline void Merge(const MapEntryAccessorType& from, \ + TypeOnMemory* to, Arena* arena); \ + static inline void Clear(TypeOnMemory* value, Arena* arena); \ + static inline size_t SpaceUsedInMapEntryLong(const TypeOnMemory& value); \ + static inline const MapEntryAccessorType& DefaultIfNotInitialized( \ + const TypeOnMemory& value); \ + static inline bool IsInitialized(const TypeOnMemory& value); \ + static void DeleteNoArena(TypeOnMemory& value); \ + static constexpr TypeOnMemory Constinit(); \ + static inline MapEntryAccessorType* EnsureMutable(TypeOnMemory* value, \ + Arena* arena); \ + }; +MAP_HANDLER(STRING) +MAP_HANDLER(BYTES) +MAP_HANDLER(INT64) +MAP_HANDLER(UINT64) +MAP_HANDLER(INT32) +MAP_HANDLER(UINT32) +MAP_HANDLER(SINT64) +MAP_HANDLER(SINT32) +MAP_HANDLER(ENUM) +MAP_HANDLER(DOUBLE) +MAP_HANDLER(FLOAT) +MAP_HANDLER(FIXED64) +MAP_HANDLER(FIXED32) +MAP_HANDLER(SFIXED64) +MAP_HANDLER(SFIXED32) +MAP_HANDLER(BOOL) +#undef MAP_HANDLER + +template <typename Type> +inline size_t MapTypeHandler<WireFormatLite::TYPE_MESSAGE, Type>::ByteSize( + const MapEntryAccessorType& value) { + return WireFormatLite::MessageSizeNoVirtual(value); +} + +#define GOOGLE_PROTOBUF_BYTE_SIZE(FieldType, DeclaredType) \ + template <typename Type> \ + inline int MapTypeHandler<WireFormatLite::TYPE_##FieldType, Type>::ByteSize( \ + const MapEntryAccessorType& value) { \ + return static_cast<int>(WireFormatLite::DeclaredType##Size(value)); \ + } + +GOOGLE_PROTOBUF_BYTE_SIZE(STRING, String) +GOOGLE_PROTOBUF_BYTE_SIZE(BYTES, Bytes) +GOOGLE_PROTOBUF_BYTE_SIZE(INT64, Int64) +GOOGLE_PROTOBUF_BYTE_SIZE(UINT64, UInt64) +GOOGLE_PROTOBUF_BYTE_SIZE(INT32, Int32) +GOOGLE_PROTOBUF_BYTE_SIZE(UINT32, UInt32) +GOOGLE_PROTOBUF_BYTE_SIZE(SINT64, SInt64) +GOOGLE_PROTOBUF_BYTE_SIZE(SINT32, SInt32) +GOOGLE_PROTOBUF_BYTE_SIZE(ENUM, Enum) + +#undef GOOGLE_PROTOBUF_BYTE_SIZE + +#define FIXED_BYTE_SIZE(FieldType, DeclaredType) \ + template <typename Type> \ + inline int MapTypeHandler<WireFormatLite::TYPE_##FieldType, Type>::ByteSize( \ + const MapEntryAccessorType& /* value */) { \ + return WireFormatLite::k##DeclaredType##Size; \ + } + +FIXED_BYTE_SIZE(DOUBLE, Double) +FIXED_BYTE_SIZE(FLOAT, Float) +FIXED_BYTE_SIZE(FIXED64, Fixed64) +FIXED_BYTE_SIZE(FIXED32, Fixed32) +FIXED_BYTE_SIZE(SFIXED64, SFixed64) +FIXED_BYTE_SIZE(SFIXED32, SFixed32) +FIXED_BYTE_SIZE(BOOL, Bool) + +#undef FIXED_BYTE_SIZE + +template <typename Type> +inline int MapTypeHandler<WireFormatLite::TYPE_MESSAGE, Type>::GetCachedSize( + const MapEntryAccessorType& value) { + return static_cast<int>(WireFormatLite::LengthDelimitedSize( + static_cast<size_t>(value.GetCachedSize()))); +} + +#define GET_CACHED_SIZE(FieldType, DeclaredType) \ + template <typename Type> \ + inline int \ + MapTypeHandler<WireFormatLite::TYPE_##FieldType, Type>::GetCachedSize( \ + const MapEntryAccessorType& value) { \ + return static_cast<int>(WireFormatLite::DeclaredType##Size(value)); \ + } + +GET_CACHED_SIZE(STRING, String) +GET_CACHED_SIZE(BYTES, Bytes) +GET_CACHED_SIZE(INT64, Int64) +GET_CACHED_SIZE(UINT64, UInt64) +GET_CACHED_SIZE(INT32, Int32) +GET_CACHED_SIZE(UINT32, UInt32) +GET_CACHED_SIZE(SINT64, SInt64) +GET_CACHED_SIZE(SINT32, SInt32) +GET_CACHED_SIZE(ENUM, Enum) + +#undef GET_CACHED_SIZE + +#define GET_FIXED_CACHED_SIZE(FieldType, DeclaredType) \ + template <typename Type> \ + inline int \ + MapTypeHandler<WireFormatLite::TYPE_##FieldType, Type>::GetCachedSize( \ + const MapEntryAccessorType& /* value */) { \ + return WireFormatLite::k##DeclaredType##Size; \ + } + +GET_FIXED_CACHED_SIZE(DOUBLE, Double) +GET_FIXED_CACHED_SIZE(FLOAT, Float) +GET_FIXED_CACHED_SIZE(FIXED64, Fixed64) +GET_FIXED_CACHED_SIZE(FIXED32, Fixed32) +GET_FIXED_CACHED_SIZE(SFIXED64, SFixed64) +GET_FIXED_CACHED_SIZE(SFIXED32, SFixed32) +GET_FIXED_CACHED_SIZE(BOOL, Bool) + +#undef GET_FIXED_CACHED_SIZE + +template <typename Type> +inline uint8_t* MapTypeHandler<WireFormatLite::TYPE_MESSAGE, Type>::Write( + int field, const MapEntryAccessorType& value, uint8_t* ptr, + io::EpsCopyOutputStream* stream) { + ptr = stream->EnsureSpace(ptr); + return WireFormatLite::InternalWriteMessage(field, value, ptr, stream); +} + +#define WRITE_METHOD(FieldType, DeclaredType) \ + template <typename Type> \ + inline uint8_t* \ + MapTypeHandler<WireFormatLite::TYPE_##FieldType, Type>::Write( \ + int field, const MapEntryAccessorType& value, uint8_t* ptr, \ + io::EpsCopyOutputStream* stream) { \ + ptr = stream->EnsureSpace(ptr); \ + return stream->Write##DeclaredType(field, value, ptr); \ + } + +WRITE_METHOD(STRING, String) +WRITE_METHOD(BYTES, Bytes) + +#undef WRITE_METHOD +#define WRITE_METHOD(FieldType, DeclaredType) \ + template <typename Type> \ + inline uint8_t* \ + MapTypeHandler<WireFormatLite::TYPE_##FieldType, Type>::Write( \ + int field, const MapEntryAccessorType& value, uint8_t* ptr, \ + io::EpsCopyOutputStream* stream) { \ + ptr = stream->EnsureSpace(ptr); \ + return WireFormatLite::Write##DeclaredType##ToArray(field, value, ptr); \ + } + +WRITE_METHOD(INT64, Int64) +WRITE_METHOD(UINT64, UInt64) +WRITE_METHOD(INT32, Int32) +WRITE_METHOD(UINT32, UInt32) +WRITE_METHOD(SINT64, SInt64) +WRITE_METHOD(SINT32, SInt32) +WRITE_METHOD(ENUM, Enum) +WRITE_METHOD(DOUBLE, Double) +WRITE_METHOD(FLOAT, Float) +WRITE_METHOD(FIXED64, Fixed64) +WRITE_METHOD(FIXED32, Fixed32) +WRITE_METHOD(SFIXED64, SFixed64) +WRITE_METHOD(SFIXED32, SFixed32) +WRITE_METHOD(BOOL, Bool) + +#undef WRITE_METHOD + +template <typename Type> +inline bool MapTypeHandler<WireFormatLite::TYPE_MESSAGE, Type>::Read( + io::CodedInputStream* input, MapEntryAccessorType* value) { + return WireFormatLite::ReadMessageNoVirtual(input, value); +} + +template <typename Type> +inline bool MapTypeHandler<WireFormatLite::TYPE_STRING, Type>::Read( + io::CodedInputStream* input, MapEntryAccessorType* value) { + return WireFormatLite::ReadString(input, value); +} + +template <typename Type> +inline bool MapTypeHandler<WireFormatLite::TYPE_BYTES, Type>::Read( + io::CodedInputStream* input, MapEntryAccessorType* value) { + return WireFormatLite::ReadBytes(input, value); +} + +template <typename Type> +const char* MapTypeHandler<WireFormatLite::TYPE_MESSAGE, Type>::Read( + const char* ptr, ParseContext* ctx, MapEntryAccessorType* value) { + return ctx->ParseMessage(value, ptr); +} + +template <typename Type> +const char* MapTypeHandler<WireFormatLite::TYPE_STRING, Type>::Read( + const char* ptr, ParseContext* ctx, MapEntryAccessorType* value) { + int size = ReadSize(&ptr); + GOOGLE_PROTOBUF_PARSER_ASSERT(ptr); + return ctx->ReadString(ptr, size, value); +} + +template <typename Type> +const char* MapTypeHandler<WireFormatLite::TYPE_BYTES, Type>::Read( + const char* ptr, ParseContext* ctx, MapEntryAccessorType* value) { + int size = ReadSize(&ptr); + GOOGLE_PROTOBUF_PARSER_ASSERT(ptr); + return ctx->ReadString(ptr, size, value); +} + +inline const char* ReadINT64(const char* ptr, arc_i64* value) { + return VarintParse(ptr, reinterpret_cast<arc_ui64*>(value)); +} +inline const char* ReadUINT64(const char* ptr, arc_ui64* value) { + return VarintParse(ptr, value); +} +inline const char* ReadINT32(const char* ptr, arc_i32* value) { + return VarintParse(ptr, reinterpret_cast<arc_ui32*>(value)); +} +inline const char* ReadUINT32(const char* ptr, arc_ui32* value) { + return VarintParse(ptr, value); +} +inline const char* ReadSINT64(const char* ptr, arc_i64* value) { + *value = ReadVarintZigZag64(&ptr); + return ptr; +} +inline const char* ReadSINT32(const char* ptr, arc_i32* value) { + *value = ReadVarintZigZag32(&ptr); + return ptr; +} +template <typename E> +inline const char* ReadENUM(const char* ptr, E* value) { + *value = static_cast<E>(ReadVarint32(&ptr)); + return ptr; +} +inline const char* ReadBOOL(const char* ptr, bool* value) { + *value = static_cast<bool>(ReadVarint32(&ptr)); + return ptr; +} + +template <typename F> +inline const char* ReadUnaligned(const char* ptr, F* value) { + *value = UnalignedLoad<F>(ptr); + return ptr + sizeof(F); +} +inline const char* ReadFLOAT(const char* ptr, float* value) { + return ReadUnaligned(ptr, value); +} +inline const char* ReadDOUBLE(const char* ptr, double* value) { + return ReadUnaligned(ptr, value); +} +inline const char* ReadFIXED64(const char* ptr, arc_ui64* value) { + return ReadUnaligned(ptr, value); +} +inline const char* ReadFIXED32(const char* ptr, arc_ui32* value) { + return ReadUnaligned(ptr, value); +} +inline const char* ReadSFIXED64(const char* ptr, arc_i64* value) { + return ReadUnaligned(ptr, value); +} +inline const char* ReadSFIXED32(const char* ptr, arc_i32* value) { + return ReadUnaligned(ptr, value); +} + +#define READ_METHOD(FieldType) \ + template <typename Type> \ + inline bool MapTypeHandler<WireFormatLite::TYPE_##FieldType, Type>::Read( \ + io::CodedInputStream* input, MapEntryAccessorType* value) { \ + return WireFormatLite::ReadPrimitive<TypeOnMemory, \ + WireFormatLite::TYPE_##FieldType>( \ + input, value); \ + } \ + template <typename Type> \ + const char* MapTypeHandler<WireFormatLite::TYPE_##FieldType, Type>::Read( \ + const char* begin, ParseContext* ctx, MapEntryAccessorType* value) { \ + (void)ctx; \ + return Read##FieldType(begin, value); \ + } + +READ_METHOD(INT64) +READ_METHOD(UINT64) +READ_METHOD(INT32) +READ_METHOD(UINT32) +READ_METHOD(SINT64) +READ_METHOD(SINT32) +READ_METHOD(ENUM) +READ_METHOD(DOUBLE) +READ_METHOD(FLOAT) +READ_METHOD(FIXED64) +READ_METHOD(FIXED32) +READ_METHOD(SFIXED64) +READ_METHOD(SFIXED32) +READ_METHOD(BOOL) + +#undef READ_METHOD + +// Definition for message handler + +template <typename Type> +inline const Type& +MapTypeHandler<WireFormatLite::TYPE_MESSAGE, Type>::GetExternalReference( + const Type* value) { + return *value; +} + +template <typename Type> +inline size_t MapTypeHandler<WireFormatLite::TYPE_MESSAGE, + Type>::SpaceUsedInMapEntryLong(const Type* value) { + return value->SpaceUsedLong(); +} + +template <typename Type> +inline void MapTypeHandler<WireFormatLite::TYPE_MESSAGE, Type>::Clear( + Type** value, Arena* /* arena */) { + if (*value != nullptr) (*value)->Clear(); +} +template <typename Type> +inline void MapTypeHandler<WireFormatLite::TYPE_MESSAGE, Type>::Merge( + const Type& from, Type** to, Arena* /* arena */) { + (*to)->MergeFrom(from); +} + +template <typename Type> +void MapTypeHandler<WireFormatLite::TYPE_MESSAGE, Type>::DeleteNoArena( + const Type* ptr) { + delete ptr; +} + +template <typename Type> +constexpr auto MapTypeHandler<WireFormatLite::TYPE_MESSAGE, Type>::Constinit() + -> TypeOnMemory { + return nullptr; +} + +template <typename Type> +inline Type* MapTypeHandler<WireFormatLite::TYPE_MESSAGE, Type>::EnsureMutable( + Type** value, Arena* arena) { + if (*value == nullptr) { + *value = MapArenaMessageCreator< + Type, + Arena::is_arena_constructable<Type>::type::value>::CreateMessage(arena); + } + return *value; +} + +template <typename Type> +inline const Type& +MapTypeHandler<WireFormatLite::TYPE_MESSAGE, Type>::DefaultIfNotInitialized( + const Type* value) { + return value != nullptr ? *value : *Type::internal_default_instance(); +} + +template <typename Type> +inline bool MapTypeHandler<WireFormatLite::TYPE_MESSAGE, Type>::IsInitialized( + Type* value) { + return value ? value->IsInitialized() : false; +} + +// Definition for string/bytes handler + +#define STRING_OR_BYTES_HANDLER_FUNCTIONS(FieldType) \ + template <typename Type> \ + inline const typename MapTypeHandler<WireFormatLite::TYPE_##FieldType, \ + Type>::MapEntryAccessorType& \ + MapTypeHandler<WireFormatLite::TYPE_##FieldType, \ + Type>::GetExternalReference(const TypeOnMemory& value) { \ + return value.Get(); \ + } \ + template <typename Type> \ + inline size_t \ + MapTypeHandler<WireFormatLite::TYPE_##FieldType, \ + Type>::SpaceUsedInMapEntryLong(const TypeOnMemory& value) { \ + return sizeof(value); \ + } \ + template <typename Type> \ + inline void MapTypeHandler<WireFormatLite::TYPE_##FieldType, Type>::Clear( \ + TypeOnMemory* value, Arena* /* arena */) { \ + value->ClearToEmpty(); \ + } \ + template <typename Type> \ + inline void MapTypeHandler<WireFormatLite::TYPE_##FieldType, Type>::Merge( \ + const MapEntryAccessorType& from, TypeOnMemory* to, Arena* arena) { \ + to->Set(&internal::GetEmptyStringAlreadyInited(), from, arena); \ + } \ + template <typename Type> \ + void MapTypeHandler<WireFormatLite::TYPE_##FieldType, Type>::DeleteNoArena( \ + TypeOnMemory& value) { \ + value.DestroyNoArena(&internal::GetEmptyStringAlreadyInited()); \ + } \ + template <typename Type> \ + constexpr auto \ + MapTypeHandler<WireFormatLite::TYPE_##FieldType, Type>::Constinit() \ + ->TypeOnMemory { \ + return TypeOnMemory(&internal::fixed_address_empty_string); \ + } \ + template <typename Type> \ + inline typename MapTypeHandler<WireFormatLite::TYPE_##FieldType, \ + Type>::MapEntryAccessorType* \ + MapTypeHandler<WireFormatLite::TYPE_##FieldType, Type>::EnsureMutable( \ + TypeOnMemory* value, Arena* arena) { \ + return value->Mutable(ArenaStringPtr::EmptyDefault{}, arena); \ + } \ + template <typename Type> \ + inline const typename MapTypeHandler<WireFormatLite::TYPE_##FieldType, \ + Type>::MapEntryAccessorType& \ + MapTypeHandler<WireFormatLite::TYPE_##FieldType, \ + Type>::DefaultIfNotInitialized(const TypeOnMemory& value) { \ + return value.Get(); \ + } \ + template <typename Type> \ + inline bool \ + MapTypeHandler<WireFormatLite::TYPE_##FieldType, Type>::IsInitialized( \ + const TypeOnMemory& /* value */) { \ + return true; \ + } +STRING_OR_BYTES_HANDLER_FUNCTIONS(STRING) +STRING_OR_BYTES_HANDLER_FUNCTIONS(BYTES) +#undef STRING_OR_BYTES_HANDLER_FUNCTIONS + +#define PRIMITIVE_HANDLER_FUNCTIONS(FieldType) \ + template <typename Type> \ + inline const typename MapTypeHandler<WireFormatLite::TYPE_##FieldType, \ + Type>::MapEntryAccessorType& \ + MapTypeHandler<WireFormatLite::TYPE_##FieldType, \ + Type>::GetExternalReference(const TypeOnMemory& value) { \ + return value; \ + } \ + template <typename Type> \ + inline size_t MapTypeHandler<WireFormatLite::TYPE_##FieldType, Type>:: \ + SpaceUsedInMapEntryLong(const TypeOnMemory& /* value */) { \ + return 0; \ + } \ + template <typename Type> \ + inline void MapTypeHandler<WireFormatLite::TYPE_##FieldType, Type>::Clear( \ + TypeOnMemory* value, Arena* /* arena */) { \ + *value = 0; \ + } \ + template <typename Type> \ + inline void MapTypeHandler<WireFormatLite::TYPE_##FieldType, Type>::Merge( \ + const MapEntryAccessorType& from, TypeOnMemory* to, \ + Arena* /* arena */) { \ + *to = from; \ + } \ + template <typename Type> \ + inline void MapTypeHandler<WireFormatLite::TYPE_##FieldType, \ + Type>::DeleteNoArena(TypeOnMemory& /* x */) {} \ + template <typename Type> \ + constexpr auto \ + MapTypeHandler<WireFormatLite::TYPE_##FieldType, Type>::Constinit() \ + ->TypeOnMemory { \ + return 0; \ + } \ + template <typename Type> \ + inline typename MapTypeHandler<WireFormatLite::TYPE_##FieldType, \ + Type>::MapEntryAccessorType* \ + MapTypeHandler<WireFormatLite::TYPE_##FieldType, Type>::EnsureMutable( \ + TypeOnMemory* value, Arena* /* arena */) { \ + return value; \ + } \ + template <typename Type> \ + inline const typename MapTypeHandler<WireFormatLite::TYPE_##FieldType, \ + Type>::MapEntryAccessorType& \ + MapTypeHandler<WireFormatLite::TYPE_##FieldType, \ + Type>::DefaultIfNotInitialized(const TypeOnMemory& value) { \ + return value; \ + } \ + template <typename Type> \ + inline bool \ + MapTypeHandler<WireFormatLite::TYPE_##FieldType, Type>::IsInitialized( \ + const TypeOnMemory& /* value */) { \ + return true; \ + } +PRIMITIVE_HANDLER_FUNCTIONS(INT64) +PRIMITIVE_HANDLER_FUNCTIONS(UINT64) +PRIMITIVE_HANDLER_FUNCTIONS(INT32) +PRIMITIVE_HANDLER_FUNCTIONS(UINT32) +PRIMITIVE_HANDLER_FUNCTIONS(SINT64) +PRIMITIVE_HANDLER_FUNCTIONS(SINT32) +PRIMITIVE_HANDLER_FUNCTIONS(ENUM) +PRIMITIVE_HANDLER_FUNCTIONS(DOUBLE) +PRIMITIVE_HANDLER_FUNCTIONS(FLOAT) +PRIMITIVE_HANDLER_FUNCTIONS(FIXED64) +PRIMITIVE_HANDLER_FUNCTIONS(FIXED32) +PRIMITIVE_HANDLER_FUNCTIONS(SFIXED64) +PRIMITIVE_HANDLER_FUNCTIONS(SFIXED32) +PRIMITIVE_HANDLER_FUNCTIONS(BOOL) +#undef PRIMITIVE_HANDLER_FUNCTIONS + +} // namespace internal +} // namespace protobuf +} // namespace google + +#endif // GOOGLE_PROTOBUF_MAP_TYPE_HANDLER_H__ diff --git a/contrib/libs/protobuf_old/src/google/protobuf/message.cc b/contrib/libs/protobuf_old/src/google/protobuf/message.cc new file mode 100644 index 0000000000..e049807c23 --- /dev/null +++ b/contrib/libs/protobuf_old/src/google/protobuf/message.cc @@ -0,0 +1,446 @@ +// 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: kenton@google.com (Kenton Varda) +// Based on original Protocol Buffers design by +// Sanjay Ghemawat, Jeff Dean, and others. + +#include <google/protobuf/message.h> + +#include <iostream> +#include <stack> +#include <unordered_map> + +#include <google/protobuf/stubs/casts.h> +#include <google/protobuf/stubs/logging.h> +#include <google/protobuf/stubs/common.h> +#include <google/protobuf/descriptor.pb.h> +#include <google/protobuf/parse_context.h> +#include <google/protobuf/reflection_internal.h> +#include <google/protobuf/io/coded_stream.h> +#include <google/protobuf/io/zero_copy_stream_impl.h> +#include <google/protobuf/descriptor.h> +#include <google/protobuf/generated_message_reflection.h> +#include <google/protobuf/generated_message_util.h> +#include <google/protobuf/map_field.h> +#include <google/protobuf/map_field_inl.h> +#include <google/protobuf/reflection_ops.h> +#include <google/protobuf/unknown_field_set.h> +#include <google/protobuf/wire_format.h> +#include <google/protobuf/wire_format_lite.h> +#include <google/protobuf/stubs/strutil.h> +#include <google/protobuf/stubs/map_util.h> +#include <google/protobuf/stubs/stl_util.h> +#include <google/protobuf/stubs/hash.h> + +#include <google/protobuf/port_def.inc> + +namespace google { +namespace protobuf { + +namespace internal { + +// TODO(gerbens) make this factorized better. This should not have to hop +// to reflection. Currently uses GeneratedMessageReflection and thus is +// defined in generated_message_reflection.cc +void RegisterFileLevelMetadata(const DescriptorTable* descriptor_table); + +} // namespace internal + +using internal::ReflectionOps; +using internal::WireFormat; +using internal::WireFormatLite; + +void Message::MergeFrom(const Message& from) { + 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) { + MergeFrom(*down_cast<const Message*>(&other)); +} + +void Message::CopyFrom(const Message& from) { + 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); +} + +TProtoStringType Message::GetTypeName() const { + return GetDescriptor()->full_name(); +} + +void Message::Clear() { ReflectionOps::Clear(this); } + +bool Message::IsInitialized() const { + return ReflectionOps::IsInitialized(*this); +} + +void Message::FindInitializationErrors(std::vector<TProtoStringType>* errors) const { + return ReflectionOps::FindInitializationErrors(*this, "", errors); +} + +TProtoStringType Message::InitializationErrorString() const { + std::vector<TProtoStringType> errors; + FindInitializationErrors(&errors); + return Join(errors, ", "); +} + +void Message::CheckInitialized() const { + GOOGLE_CHECK(IsInitialized()) << "Message of type \"" << GetDescriptor()->full_name() + << "\" is missing required fields: " + << InitializationErrorString(); +} + +void Message::DiscardUnknownFields() { + return ReflectionOps::DiscardUnknownFields(this); +} + +const char* Message::_InternalParse(const char* ptr, + internal::ParseContext* ctx) { + return WireFormat::_InternalParse(this, ptr, ctx); +} + +uint8_t* Message::_InternalSerialize(uint8_t* target, + io::EpsCopyOutputStream* stream) const { + return WireFormat::_InternalSerialize(*this, target, stream); +} + +// Yandex-specific +void Message::PrintJSON(IOutputStream& out) const { + out << "(Something went wrong: no PrintJSON() override provided - are you using a non-styleguided .pb.h?)"; +} + +bool Message::ParseFromArcadiaStream(IInputStream* input) { + bool res = false; + io::TInputStreamProxy proxy(input); + { + io::CopyingInputStreamAdaptor stream(&proxy); + res = ParseFromZeroCopyStream(&stream); + } + return res && !proxy.HasError(); +} + +bool Message::ParsePartialFromArcadiaStream(IInputStream* input) { + bool res = false; + io::TInputStreamProxy proxy(input); + { + io::CopyingInputStreamAdaptor stream(&proxy); + res = ParsePartialFromZeroCopyStream(&stream); + } + return res && !proxy.HasError(); +} + +bool Message::SerializeToArcadiaStream(IOutputStream* output) const { + bool res = false; + io::TOutputStreamProxy proxy(output); + { + io::CopyingOutputStreamAdaptor stream(&proxy); + res = SerializeToZeroCopyStream(&stream); + } + return res && !proxy.HasError(); +} + +bool Message::SerializePartialToArcadiaStream(IOutputStream* output) const { + bool res = false; + io::TOutputStreamProxy proxy(output); + { + io::CopyingOutputStreamAdaptor stream(&proxy); + res = SerializePartialToZeroCopyStream(&stream); + } + return res && !proxy.HasError(); +} +// End of Yandex-specific + +size_t Message::ByteSizeLong() const { + size_t size = WireFormat::ByteSize(*this); + SetCachedSize(internal::ToCachedSize(size)); + return size; +} + +void Message::SetCachedSize(int /* size */) const { + GOOGLE_LOG(FATAL) << "Message class \"" << GetDescriptor()->full_name() + << "\" implements neither SetCachedSize() nor ByteSize(). " + "Must implement one or the other."; +} + +size_t Message::ComputeUnknownFieldsSize( + size_t total_size, internal::CachedSize* cached_size) const { + total_size += WireFormat::ComputeUnknownFieldsSize( + _internal_metadata_.unknown_fields<UnknownFieldSet>( + UnknownFieldSet::default_instance)); + cached_size->Set(internal::ToCachedSize(total_size)); + return total_size; +} + +size_t Message::MaybeComputeUnknownFieldsSize( + size_t total_size, internal::CachedSize* cached_size) const { + if (PROTOBUF_PREDICT_FALSE(_internal_metadata_.have_unknown_fields())) { + return ComputeUnknownFieldsSize(total_size, cached_size); + } + cached_size->Set(internal::ToCachedSize(total_size)); + return total_size; +} + +size_t Message::SpaceUsedLong() const { + return GetReflection()->SpaceUsedLong(*this); +} + +arc_ui64 Message::GetInvariantPerBuild(arc_ui64 salt) { + return salt; +} + +// ============================================================================= +// MessageFactory + +MessageFactory::~MessageFactory() {} + +namespace { + + +#define HASH_MAP std::unordered_map +#define STR_HASH_FXN hash<::google::protobuf::StringPiece> + + +class GeneratedMessageFactory final : public MessageFactory { + public: + static GeneratedMessageFactory* singleton(); + + void RegisterFile(const google::protobuf::internal::DescriptorTable* table); + void RegisterType(const Descriptor* descriptor, const Message* prototype); + + // implements MessageFactory --------------------------------------- + const Message* GetPrototype(const Descriptor* type) override; + + private: + // Only written at static init time, so does not require locking. + HASH_MAP<StringPiece, const google::protobuf::internal::DescriptorTable*, + STR_HASH_FXN> + file_map_; + + internal::WrappedMutex mutex_; + // Initialized lazily, so requires locking. + std::unordered_map<const Descriptor*, const Message*> type_map_; +}; + +GeneratedMessageFactory* GeneratedMessageFactory::singleton() { + static auto instance = + internal::OnShutdownDelete(new GeneratedMessageFactory); + return instance; +} + +void GeneratedMessageFactory::RegisterFile( + const google::protobuf::internal::DescriptorTable* table) { + if (!InsertIfNotPresent(&file_map_, table->filename, table)) { + GOOGLE_LOG(FATAL) << "File is already registered: " << table->filename; + } +} + +void GeneratedMessageFactory::RegisterType(const Descriptor* descriptor, + const Message* prototype) { + GOOGLE_DCHECK_EQ(descriptor->file()->pool(), DescriptorPool::generated_pool()) + << "Tried to register a non-generated type with the generated " + "type registry."; + + // This should only be called as a result of calling a file registration + // function during GetPrototype(), in which case we already have locked + // the mutex. + mutex_.AssertHeld(); + if (!InsertIfNotPresent(&type_map_, descriptor, prototype)) { + GOOGLE_LOG(DFATAL) << "Type is already registered: " << descriptor->full_name(); + } +} + + +const Message* GeneratedMessageFactory::GetPrototype(const Descriptor* type) { + { + ReaderMutexLock lock(&mutex_); + const Message* result = FindPtrOrNull(type_map_, type); + if (result != nullptr) return result; + } + + // If the type is not in the generated pool, then we can't possibly handle + // it. + if (type->file()->pool() != DescriptorPool::generated_pool()) return nullptr; + + // Apparently the file hasn't been registered yet. Let's do that now. + const internal::DescriptorTable* registration_data = + FindPtrOrNull(file_map_, type->file()->name().c_str()); + if (registration_data == nullptr) { + GOOGLE_LOG(DFATAL) << "File appears to be in generated pool but wasn't " + "registered: " + << type->file()->name(); + return nullptr; + } + + WriterMutexLock lock(&mutex_); + + // Check if another thread preempted us. + const Message* result = FindPtrOrNull(type_map_, type); + if (result == nullptr) { + // Nope. OK, register everything. + internal::RegisterFileLevelMetadata(registration_data); + // Should be here now. + result = FindPtrOrNull(type_map_, type); + } + + if (result == nullptr) { + GOOGLE_LOG(DFATAL) << "Type appears to be in generated pool but wasn't " + << "registered: " << type->full_name(); + } + + return result; +} + +} // namespace + +MessageFactory* MessageFactory::generated_factory() { + return GeneratedMessageFactory::singleton(); +} + +void MessageFactory::InternalRegisterGeneratedFile( + const google::protobuf::internal::DescriptorTable* table) { + GeneratedMessageFactory::singleton()->RegisterFile(table); +} + +void MessageFactory::InternalRegisterGeneratedMessage( + const Descriptor* descriptor, const Message* prototype) { + GeneratedMessageFactory::singleton()->RegisterType(descriptor, prototype); +} + + +namespace { +template <typename T> +T* GetSingleton() { + static T singleton; + return &singleton; +} +} // namespace + +const internal::RepeatedFieldAccessor* Reflection::RepeatedFieldAccessor( + const FieldDescriptor* field) const { + GOOGLE_CHECK(field->is_repeated()); + switch (field->cpp_type()) { +#define HANDLE_PRIMITIVE_TYPE(TYPE, type) \ + case FieldDescriptor::CPPTYPE_##TYPE: \ + return GetSingleton<internal::RepeatedFieldPrimitiveAccessor<type> >(); + HANDLE_PRIMITIVE_TYPE(INT32, arc_i32) + HANDLE_PRIMITIVE_TYPE(UINT32, arc_ui32) + HANDLE_PRIMITIVE_TYPE(INT64, arc_i64) + HANDLE_PRIMITIVE_TYPE(UINT64, arc_ui64) + HANDLE_PRIMITIVE_TYPE(FLOAT, float) + HANDLE_PRIMITIVE_TYPE(DOUBLE, double) + HANDLE_PRIMITIVE_TYPE(BOOL, bool) + HANDLE_PRIMITIVE_TYPE(ENUM, arc_i32) +#undef HANDLE_PRIMITIVE_TYPE + case FieldDescriptor::CPPTYPE_STRING: + switch (field->options().ctype()) { + default: + case FieldOptions::STRING: + return GetSingleton<internal::RepeatedPtrFieldStringAccessor>(); + } + break; + case FieldDescriptor::CPPTYPE_MESSAGE: + if (field->is_map()) { + return GetSingleton<internal::MapFieldAccessor>(); + } else { + return GetSingleton<internal::RepeatedPtrFieldMessageAccessor>(); + } + } + GOOGLE_LOG(FATAL) << "Should not reach here."; + return nullptr; +} + +namespace internal { +template <> +#if defined(_MSC_VER) && (_MSC_VER >= 1800) +// Note: force noinline to workaround MSVC compiler bug with /Zc:inline, issue +// #240 +PROTOBUF_NOINLINE +#endif + Message* + GenericTypeHandler<Message>::NewFromPrototype(const Message* prototype, + Arena* arena) { + return prototype->New(arena); +} +template <> +#if defined(_MSC_VER) && (_MSC_VER >= 1800) +// Note: force noinline to workaround MSVC compiler bug with /Zc:inline, issue +// #240 +PROTOBUF_NOINLINE +#endif + Arena* + GenericTypeHandler<Message>::GetOwningArena(Message* value) { + return value->GetOwningArena(); +} +} // namespace internal + +} // namespace protobuf +} // namespace google + +#include <google/protobuf/port_undef.inc> diff --git a/contrib/libs/protobuf_old/src/google/protobuf/message.h b/contrib/libs/protobuf_old/src/google/protobuf/message.h new file mode 100644 index 0000000000..a94688c248 --- /dev/null +++ b/contrib/libs/protobuf_old/src/google/protobuf/message.h @@ -0,0 +1,1510 @@ +// 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: kenton@google.com (Kenton Varda) +// Based on original Protocol Buffers design by +// Sanjay Ghemawat, Jeff Dean, and others. +// +// Defines Message, the abstract interface implemented by non-lite +// protocol message objects. Although it's possible to implement this +// interface manually, most users will use the protocol compiler to +// generate implementations. +// +// Example usage: +// +// Say you have a message defined as: +// +// message Foo { +// optional string text = 1; +// repeated int32 numbers = 2; +// } +// +// Then, if you used the protocol compiler to generate a class from the above +// definition, you could use it like so: +// +// TProtoStringType data; // Will store a serialized version of the message. +// +// { +// // Create a message and serialize it. +// Foo foo; +// foo.set_text("Hello World!"); +// foo.add_numbers(1); +// foo.add_numbers(5); +// foo.add_numbers(42); +// +// foo.SerializeToString(&data); +// } +// +// { +// // Parse the serialized message and check that it contains the +// // correct data. +// Foo foo; +// foo.ParseFromString(data); +// +// assert(foo.text() == "Hello World!"); +// assert(foo.numbers_size() == 3); +// assert(foo.numbers(0) == 1); +// assert(foo.numbers(1) == 5); +// assert(foo.numbers(2) == 42); +// } +// +// { +// // Same as the last block, but do it dynamically via the Message +// // reflection interface. +// Message* foo = new Foo; +// const Descriptor* descriptor = foo->GetDescriptor(); +// +// // Get the descriptors for the fields we're interested in and verify +// // their types. +// const FieldDescriptor* text_field = descriptor->FindFieldByName("text"); +// assert(text_field != nullptr); +// assert(text_field->type() == FieldDescriptor::TYPE_STRING); +// assert(text_field->label() == FieldDescriptor::LABEL_OPTIONAL); +// const FieldDescriptor* numbers_field = descriptor-> +// FindFieldByName("numbers"); +// assert(numbers_field != nullptr); +// assert(numbers_field->type() == FieldDescriptor::TYPE_INT32); +// assert(numbers_field->label() == FieldDescriptor::LABEL_REPEATED); +// +// // Parse the message. +// foo->ParseFromString(data); +// +// // Use the reflection interface to examine the contents. +// const Reflection* reflection = foo->GetReflection(); +// assert(reflection->GetString(*foo, text_field) == "Hello World!"); +// assert(reflection->FieldSize(*foo, numbers_field) == 3); +// assert(reflection->GetRepeatedInt32(*foo, numbers_field, 0) == 1); +// assert(reflection->GetRepeatedInt32(*foo, numbers_field, 1) == 5); +// assert(reflection->GetRepeatedInt32(*foo, numbers_field, 2) == 42); +// +// delete foo; +// } + +#ifndef GOOGLE_PROTOBUF_MESSAGE_H__ +#define GOOGLE_PROTOBUF_MESSAGE_H__ + +#include <iosfwd> +#include <string> +#include <type_traits> +#include <vector> + +#include <google/protobuf/stubs/casts.h> +#include <google/protobuf/stubs/common.h> +#include <google/protobuf/arena.h> +#include <google/protobuf/descriptor.h> +#include <google/protobuf/generated_message_reflection.h> +#include <google/protobuf/generated_message_util.h> +#include <google/protobuf/message_lite.h> +#include <google/protobuf/port.h> + +#include <google/protobuf/json_util.h> +#include <google/protobuf/messagext.h> + +#define GOOGLE_PROTOBUF_HAS_ONEOF +#define GOOGLE_PROTOBUF_HAS_ARENAS + +#include <google/protobuf/port_def.inc> + +#ifdef SWIG +#error "You cannot SWIG proto headers" +#endif + +namespace google { +namespace protobuf { + +// Defined in this file. +class Message; +class Reflection; +class MessageFactory; + +// Defined in other files. +class AssignDescriptorsHelper; +class DynamicMessageFactory; +class DynamicMessageReflectionHelper; +class GeneratedMessageReflectionTestHelper; +class MapKey; +class MapValueConstRef; +class MapValueRef; +class MapIterator; +class MapReflectionTester; + +namespace internal { +struct DescriptorTable; +class MapFieldBase; +class SwapFieldHelper; +class CachedSize; +} // namespace internal +class UnknownFieldSet; // unknown_field_set.h +namespace io { +class ZeroCopyInputStream; // zero_copy_stream.h +class ZeroCopyOutputStream; // zero_copy_stream.h +class CodedInputStream; // coded_stream.h +class CodedOutputStream; // coded_stream.h +} // namespace io +namespace python { +class MapReflectionFriend; // scalar_map_container.h +class MessageReflectionFriend; +} // namespace python +namespace expr { +class CelMapReflectionFriend; // field_backed_map_impl.cc +} + +namespace internal { +class MapFieldPrinterHelper; // text_format.cc +} +namespace util { +class MessageDifferencer; +} + + +namespace internal { +class ReflectionAccessor; // message.cc +class ReflectionOps; // reflection_ops.h +class MapKeySorter; // wire_format.cc +class WireFormat; // wire_format.h +class MapFieldReflectionTest; // map_test.cc +} // namespace internal + +template <typename T> +class RepeatedField; // repeated_field.h + +template <typename T> +class RepeatedPtrField; // repeated_field.h + +// A container to hold message metadata. +struct Metadata { + const Descriptor* descriptor; + const Reflection* reflection; +}; + +namespace internal { +template <class To> +inline To* GetPointerAtOffset(Message* message, arc_ui32 offset) { + return reinterpret_cast<To*>(reinterpret_cast<char*>(message) + offset); +} + +template <class To> +const To* GetConstPointerAtOffset(const Message* message, arc_ui32 offset) { + return reinterpret_cast<const To*>(reinterpret_cast<const char*>(message) + + offset); +} + +template <class To> +const To& GetConstRefAtOffset(const Message& message, arc_ui32 offset) { + return *GetConstPointerAtOffset<To>(&message, offset); +} + +bool CreateUnknownEnumValues(const FieldDescriptor* field); +} // namespace internal + +// Abstract interface for protocol messages. +// +// See also MessageLite, which contains most every-day operations. Message +// adds descriptors and reflection on top of that. +// +// The methods of this class that are virtual but not pure-virtual have +// default implementations based on reflection. Message classes which are +// optimized for speed will want to override these with faster implementations, +// but classes optimized for code size may be happy with keeping them. See +// the optimize_for option in descriptor.proto. +// +// Users must not derive from this class. Only the protocol compiler and +// the internal library are allowed to create subclasses. +class PROTOBUF_EXPORT Message : public MessageLite { + public: + constexpr Message() {} + + // Basic Operations ------------------------------------------------ + + // Construct a new instance of the same type. Ownership is passed to the + // caller. (This is also defined in MessageLite, but is defined again here + // for return-type covariance.) + Message* New() const { return New(nullptr); } + + // Construct a new instance on the arena. Ownership is passed to the caller + // if arena is a nullptr. + Message* New(Arena* arena) const override = 0; + + // Make this message into a copy of the given message. The given message + // must have the same descriptor, but need not necessarily be the same class. + // By default this is just implemented as "Clear(); MergeFrom(from);". + virtual void CopyFrom(const Message& from); + + // Merge the fields from the given message into this message. Singular + // fields will be overwritten, if specified in from, except for embedded + // messages which will be merged. Repeated fields will be concatenated. + // The given message must be of the same type as this message (i.e. the + // exact same class). + virtual void MergeFrom(const Message& from); + + // Verifies that IsInitialized() returns true. GOOGLE_CHECK-fails otherwise, with + // a nice error message. + void CheckInitialized() const; + + // Slowly build a list of all required fields that are not set. + // This is much, much slower than IsInitialized() as it is implemented + // purely via reflection. Generally, you should not call this unless you + // have already determined that an error exists by calling IsInitialized(). + void FindInitializationErrors(std::vector<TProtoStringType>* errors) const; + + // Like FindInitializationErrors, but joins all the strings, delimited by + // commas, and returns them. + TProtoStringType InitializationErrorString() const override; + + // Clears all unknown fields from this message and all embedded messages. + // Normally, if unknown tag numbers are encountered when parsing a message, + // the tag and value are stored in the message's UnknownFieldSet and + // then written back out when the message is serialized. This allows servers + // which simply route messages to other servers to pass through messages + // that have new field definitions which they don't yet know about. However, + // this behavior can have security implications. To avoid it, call this + // method after parsing. + // + // See Reflection::GetUnknownFields() for more on unknown fields. + void DiscardUnknownFields(); + + // Computes (an estimate of) the total number of bytes currently used for + // storing the message in memory. The default implementation calls the + // Reflection object's SpaceUsed() method. + // + // SpaceUsed() is noticeably slower than ByteSize(), as it is implemented + // using reflection (rather than the generated code implementation for + // ByteSize()). Like ByteSize(), its CPU time is linear in the number of + // fields defined for the proto. + virtual size_t SpaceUsedLong() const; + + PROTOBUF_DEPRECATED_MSG("Please use SpaceUsedLong() instead") + int SpaceUsed() const { return internal::ToIntSize(SpaceUsedLong()); } + + // Debugging & Testing---------------------------------------------- + + // Generates a human readable form of this message, useful for debugging + // and other purposes. + TProtoStringType DebugString() const; + // Like DebugString(), but with less whitespace. + TProtoStringType ShortDebugString() const; + // Like DebugString(), but do not escape UTF-8 byte sequences. + TProtoStringType Utf8DebugString() const; + // Convenience function useful in GDB. Prints DebugString() to stdout. + void PrintDebugString() const; + + // Reflection-based methods ---------------------------------------- + // These methods are pure-virtual in MessageLite, but Message provides + // reflection-based default implementations. + + TProtoStringType GetTypeName() const override; + void Clear() override; + + // Returns whether all required fields have been set. Note that required + // fields no longer exist starting in proto3. + bool IsInitialized() const override; + + void CheckTypeAndMergeFrom(const MessageLite& other) override; + // Reflective parser + const char* _InternalParse(const char* ptr, + internal::ParseContext* ctx) override; + size_t ByteSizeLong() const override; + uint8_t* _InternalSerialize(uint8_t* target, + io::EpsCopyOutputStream* stream) const override; + + // Yandex-specific + bool ParseFromArcadiaStream(IInputStream* input); + bool ParsePartialFromArcadiaStream(IInputStream* input); + bool SerializeToArcadiaStream(IOutputStream* output) const; + bool SerializePartialToArcadiaStream(IOutputStream* output) const; + + virtual void PrintJSON(IOutputStream&) const; + + io::TAsJSON<Message> AsJSON() const { + return io::TAsJSON<Message>(*this); + } + + internal::TAsBinary AsBinary() const { + return internal::TAsBinary{*this}; + } + + internal::TAsStreamSeq AsStreamSeq() const { + return internal::TAsStreamSeq{*this}; + } + // End of Yandex-specific + + private: + // This is called only by the default implementation of ByteSize(), to + // update the cached size. If you override ByteSize(), you do not need + // to override this. If you do not override ByteSize(), you MUST override + // this; the default implementation will crash. + // + // The method is private because subclasses should never call it; only + // override it. Yes, C++ lets you do that. Crazy, huh? + virtual void SetCachedSize(int size) const; + + public: + // Introspection --------------------------------------------------- + + + // Get a non-owning pointer to a Descriptor for this message's type. This + // describes what fields the message contains, the types of those fields, etc. + // This object remains property of the Message. + const Descriptor* GetDescriptor() const { return GetMetadata().descriptor; } + + // Get a non-owning pointer to the Reflection interface for this Message, + // which can be used to read and modify the fields of the Message dynamically + // (in other words, without knowing the message type at compile time). This + // object remains property of the Message. + const Reflection* GetReflection() const { return GetMetadata().reflection; } + + protected: + // Get a struct containing the metadata for the Message, which is used in turn + // to implement GetDescriptor() and GetReflection() above. + virtual Metadata GetMetadata() const = 0; + + 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) {} + size_t ComputeUnknownFieldsSize(size_t total_size, + internal::CachedSize* cached_size) const; + size_t MaybeComputeUnknownFieldsSize(size_t total_size, + internal::CachedSize* cached_size) const; + + + protected: + static arc_ui64 GetInvariantPerBuild(arc_ui64 salt); + + private: + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(Message); +}; + +namespace internal { +// Forward-declare interfaces used to implement RepeatedFieldRef. +// These are protobuf internals that users shouldn't care about. +class RepeatedFieldAccessor; +} // namespace internal + +// Forward-declare RepeatedFieldRef templates. The second type parameter is +// used for SFINAE tricks. Users should ignore it. +template <typename T, typename Enable = void> +class RepeatedFieldRef; + +template <typename T, typename Enable = void> +class MutableRepeatedFieldRef; + +// This interface contains methods that can be used to dynamically access +// and modify the fields of a protocol message. Their semantics are +// similar to the accessors the protocol compiler generates. +// +// To get the Reflection for a given Message, call Message::GetReflection(). +// +// This interface is separate from Message only for efficiency reasons; +// the vast majority of implementations of Message will share the same +// implementation of Reflection (GeneratedMessageReflection, +// defined in generated_message.h), and all Messages of a particular class +// should share the same Reflection object (though you should not rely on +// the latter fact). +// +// There are several ways that these methods can be used incorrectly. For +// example, any of the following conditions will lead to undefined +// results (probably assertion failures): +// - The FieldDescriptor is not a field of this message type. +// - The method called is not appropriate for the field's type. For +// each field type in FieldDescriptor::TYPE_*, there is only one +// Get*() method, one Set*() method, and one Add*() method that is +// valid for that type. It should be obvious which (except maybe +// for TYPE_BYTES, which are represented using strings in C++). +// - A Get*() or Set*() method for singular fields is called on a repeated +// field. +// - GetRepeated*(), SetRepeated*(), or Add*() is called on a non-repeated +// field. +// - The Message object passed to any method is not of the right type for +// this Reflection object (i.e. message.GetReflection() != reflection). +// +// You might wonder why there is not any abstract representation for a field +// of arbitrary type. E.g., why isn't there just a "GetField()" method that +// returns "const Field&", where "Field" is some class with accessors like +// "GetInt32Value()". The problem is that someone would have to deal with +// allocating these Field objects. For generated message classes, having to +// allocate space for an additional object to wrap every field would at least +// double the message's memory footprint, probably worse. Allocating the +// objects on-demand, on the other hand, would be expensive and prone to +// memory leaks. So, instead we ended up with this flat interface. +class PROTOBUF_EXPORT Reflection final { + public: + // Get the UnknownFieldSet for the message. This contains fields which + // were seen when the Message was parsed but were not recognized according + // to the Message's definition. + const UnknownFieldSet& GetUnknownFields(const Message& message) const; + // Get a mutable pointer to the UnknownFieldSet for the message. This + // contains fields which were seen when the Message was parsed but were not + // recognized according to the Message's definition. + UnknownFieldSet* MutableUnknownFields(Message* message) const; + + // Estimate the amount of memory used by the message object. + size_t SpaceUsedLong(const Message& message) const; + + PROTOBUF_DEPRECATED_MSG("Please use SpaceUsedLong() instead") + int SpaceUsed(const Message& message) const { + return internal::ToIntSize(SpaceUsedLong(message)); + } + + // Check if the given non-repeated field is set. + bool HasField(const Message& message, const FieldDescriptor* field) const; + + // Get the number of elements of a repeated field. + int FieldSize(const Message& message, const FieldDescriptor* field) const; + + // Clear the value of a field, so that HasField() returns false or + // FieldSize() returns zero. + void ClearField(Message* message, const FieldDescriptor* field) const; + + // Check if the oneof is set. Returns true if any field in oneof + // is set, false otherwise. + bool HasOneof(const Message& message, + const OneofDescriptor* oneof_descriptor) const; + + void ClearOneof(Message* message, + const OneofDescriptor* oneof_descriptor) const; + + // Returns the field descriptor if the oneof is set. nullptr otherwise. + const FieldDescriptor* GetOneofFieldDescriptor( + const Message& message, const OneofDescriptor* oneof_descriptor) const; + + // Removes the last element of a repeated field. + // We don't provide a way to remove any element other than the last + // because it invites inefficient use, such as O(n^2) filtering loops + // that should have been O(n). If you want to remove an element other + // than the last, the best way to do it is to re-arrange the elements + // (using Swap()) so that the one you want removed is at the end, then + // call RemoveLast(). + 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_NODISCARD Message* ReleaseLast(Message* message, + const FieldDescriptor* field) const; + + // Similar to ReleaseLast() without internal safety and ownershp checks. This + // method should only be used when the objects are on the same arena or paired + // with a call to `UnsafeArenaAddAllocatedMessage`. + Message* UnsafeArenaReleaseLast(Message* message, + const FieldDescriptor* field) const; + + // Swap the complete contents of two messages. + void Swap(Message* message1, Message* message2) const; + + // Swap fields listed in fields vector of two messages. + void SwapFields(Message* message1, Message* message2, + const std::vector<const FieldDescriptor*>& fields) const; + + // Swap two elements of a repeated field. + void SwapElements(Message* message, const FieldDescriptor* field, int index1, + int index2) const; + + // Swap without internal safety and ownership checks. This method should only + // be used when the objects are on the same arena. + void UnsafeArenaSwap(Message* lhs, Message* rhs) const; + + // SwapFields without internal safety and ownership checks. This method should + // only be used when the objects are on the same arena. + void UnsafeArenaSwapFields( + Message* lhs, Message* rhs, + const std::vector<const FieldDescriptor*>& fields) const; + + // List all fields of the message which are currently set, except for unknown + // fields, but including extension known to the parser (i.e. compiled in). + // Singular fields will only be listed if HasField(field) would return true + // and repeated fields will only be listed if FieldSize(field) would return + // non-zero. Fields (both normal fields and extension fields) will be listed + // ordered by field number. + // Use Reflection::GetUnknownFields() or message.unknown_fields() to also get + // access to fields/extensions unknown to the parser. + void ListFields(const Message& message, + std::vector<const FieldDescriptor*>* output) const; + + // Singular field getters ------------------------------------------ + // These get the value of a non-repeated field. They return the default + // value for fields that aren't set. + + arc_i32 GetInt32(const Message& message, const FieldDescriptor* field) const; + arc_i64 GetInt64(const Message& message, const FieldDescriptor* field) const; + arc_ui32 GetUInt32(const Message& message, + const FieldDescriptor* field) const; + arc_ui64 GetUInt64(const Message& message, + const FieldDescriptor* field) const; + float GetFloat(const Message& message, const FieldDescriptor* field) const; + double GetDouble(const Message& message, const FieldDescriptor* field) const; + bool GetBool(const Message& message, const FieldDescriptor* field) const; + TProtoStringType GetString(const Message& message, + const FieldDescriptor* field) const; + const EnumValueDescriptor* GetEnum(const Message& message, + const FieldDescriptor* field) const; + + // GetEnumValue() returns an enum field's value as an integer rather than + // an EnumValueDescriptor*. If the integer value does not correspond to a + // known value descriptor, a new value descriptor is created. (Such a value + // will only be present when the new unknown-enum-value semantics are enabled + // for a message.) + int GetEnumValue(const Message& message, const FieldDescriptor* field) const; + + // See MutableMessage() for the meaning of the "factory" parameter. + const Message& GetMessage(const Message& message, + const FieldDescriptor* field, + MessageFactory* factory = nullptr) const; + + // Get a string value without copying, if possible. + // + // GetString() necessarily returns a copy of the string. This can be + // inefficient when the TProtoStringType is already stored in a TProtoStringType object + // in the underlying message. GetStringReference() will return a reference to + // the underlying TProtoStringType in this case. Otherwise, it will copy the + // string into *scratch and return that. + // + // Note: It is perfectly reasonable and useful to write code like: + // str = reflection->GetStringReference(message, field, &str); + // This line would ensure that only one copy of the string is made + // regardless of the field's underlying representation. When initializing + // a newly-constructed string, though, it's just as fast and more + // readable to use code like: + // TProtoStringType str = reflection->GetString(message, field); + const TProtoStringType& GetStringReference(const Message& message, + const FieldDescriptor* field, + TProtoStringType* scratch) const; + + + // Singular field mutators ----------------------------------------- + // These mutate the value of a non-repeated field. + + void SetInt32(Message* message, const FieldDescriptor* field, + arc_i32 value) const; + void SetInt64(Message* message, const FieldDescriptor* field, + arc_i64 value) const; + void SetUInt32(Message* message, const FieldDescriptor* field, + arc_ui32 value) const; + void SetUInt64(Message* message, const FieldDescriptor* field, + arc_ui64 value) const; + void SetFloat(Message* message, const FieldDescriptor* field, + float value) const; + void SetDouble(Message* message, const FieldDescriptor* field, + double value) const; + void SetBool(Message* message, const FieldDescriptor* field, + bool value) const; + void SetString(Message* message, const FieldDescriptor* field, + TProtoStringType value) const; + void SetEnum(Message* message, const FieldDescriptor* field, + const EnumValueDescriptor* value) const; + // Set an enum field's value with an integer rather than EnumValueDescriptor. + // For proto3 this is just setting the enum field to the value specified, for + // proto2 it's more complicated. If value is a known enum value the field is + // set as usual. If the value is unknown then it is added to the unknown field + // set. Note this matches the behavior of parsing unknown enum values. + // If multiple calls with unknown values happen than they are all added to the + // unknown field set in order of the calls. + void SetEnumValue(Message* message, const FieldDescriptor* field, + int value) const; + + // Get a mutable pointer to a field with a message type. If a MessageFactory + // is provided, it will be used to construct instances of the sub-message; + // otherwise, the default factory is used. If the field is an extension that + // does not live in the same pool as the containing message's descriptor (e.g. + // it lives in an overlay pool), then a MessageFactory must be provided. + // If you have no idea what that meant, then you probably don't need to worry + // about it (don't provide a MessageFactory). WARNING: If the + // FieldDescriptor is for a compiled-in extension, then + // factory->GetPrototype(field->message_type()) MUST return an instance of + // the compiled-in class for this type, NOT DynamicMessage. + Message* MutableMessage(Message* message, const FieldDescriptor* field, + MessageFactory* factory = nullptr) const; + + // Replaces the message specified by 'field' with the already-allocated object + // sub_message, passing ownership to the message. If the field contained a + // message, that message is deleted. If sub_message is nullptr, the field is + // cleared. + void SetAllocatedMessage(Message* message, Message* sub_message, + const FieldDescriptor* field) const; + + // Similar to `SetAllocatedMessage`, but omits all internal safety and + // ownership checks. This method should only be used when the objects are on + // the same arena or paired with a call to `UnsafeArenaReleaseMessage`. + void UnsafeArenaSetAllocatedMessage(Message* message, Message* sub_message, + const FieldDescriptor* field) const; + + // Releases the message specified by 'field' and returns the pointer, + // ReleaseMessage() will return the message the message object if it exists. + // Otherwise, it may or may not return nullptr. In any case, if the return + // value is non-null, the caller takes ownership of the pointer. + // 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_NODISCARD Message* ReleaseMessage( + Message* message, const FieldDescriptor* field, + MessageFactory* factory = nullptr) const; + + // Similar to `ReleaseMessage`, but omits all internal safety and ownership + // checks. This method should only be used when the objects are on the same + // arena or paired with a call to `UnsafeArenaSetAllocatedMessage`. + Message* UnsafeArenaReleaseMessage(Message* message, + const FieldDescriptor* field, + MessageFactory* factory = nullptr) const; + + + // Repeated field getters ------------------------------------------ + // These get the value of one element of a repeated field. + + arc_i32 GetRepeatedInt32(const Message& message, const FieldDescriptor* field, + int index) const; + arc_i64 GetRepeatedInt64(const Message& message, const FieldDescriptor* field, + int index) const; + arc_ui32 GetRepeatedUInt32(const Message& message, + const FieldDescriptor* field, int index) const; + arc_ui64 GetRepeatedUInt64(const Message& message, + const FieldDescriptor* field, int index) const; + float GetRepeatedFloat(const Message& message, const FieldDescriptor* field, + int index) const; + double GetRepeatedDouble(const Message& message, const FieldDescriptor* field, + int index) const; + bool GetRepeatedBool(const Message& message, const FieldDescriptor* field, + int index) const; + TProtoStringType GetRepeatedString(const Message& message, + const FieldDescriptor* field, int index) const; + const EnumValueDescriptor* GetRepeatedEnum(const Message& message, + const FieldDescriptor* field, + int index) const; + // GetRepeatedEnumValue() returns an enum field's value as an integer rather + // than an EnumValueDescriptor*. If the integer value does not correspond to a + // known value descriptor, a new value descriptor is created. (Such a value + // will only be present when the new unknown-enum-value semantics are enabled + // for a message.) + int GetRepeatedEnumValue(const Message& message, const FieldDescriptor* field, + int index) const; + const Message& GetRepeatedMessage(const Message& message, + const FieldDescriptor* field, + int index) const; + + // See GetStringReference(), above. + const TProtoStringType& GetRepeatedStringReference(const Message& message, + const FieldDescriptor* field, + int index, + TProtoStringType* scratch) const; + + + // Repeated field mutators ----------------------------------------- + // These mutate the value of one element of a repeated field. + + void SetRepeatedInt32(Message* message, const FieldDescriptor* field, + int index, arc_i32 value) const; + void SetRepeatedInt64(Message* message, const FieldDescriptor* field, + int index, arc_i64 value) const; + void SetRepeatedUInt32(Message* message, const FieldDescriptor* field, + int index, arc_ui32 value) const; + void SetRepeatedUInt64(Message* message, const FieldDescriptor* field, + int index, arc_ui64 value) const; + void SetRepeatedFloat(Message* message, const FieldDescriptor* field, + int index, float value) const; + void SetRepeatedDouble(Message* message, const FieldDescriptor* field, + int index, double value) const; + void SetRepeatedBool(Message* message, const FieldDescriptor* field, + int index, bool value) const; + void SetRepeatedString(Message* message, const FieldDescriptor* field, + int index, TProtoStringType value) const; + void SetRepeatedEnum(Message* message, const FieldDescriptor* field, + int index, const EnumValueDescriptor* value) const; + // Set an enum field's value with an integer rather than EnumValueDescriptor. + // For proto3 this is just setting the enum field to the value specified, for + // proto2 it's more complicated. If value is a known enum value the field is + // set as usual. If the value is unknown then it is added to the unknown field + // set. Note this matches the behavior of parsing unknown enum values. + // If multiple calls with unknown values happen than they are all added to the + // unknown field set in order of the calls. + void SetRepeatedEnumValue(Message* message, const FieldDescriptor* field, + int index, int value) const; + // Get a mutable pointer to an element of a repeated field with a message + // type. + Message* MutableRepeatedMessage(Message* message, + const FieldDescriptor* field, + int index) const; + + + // Repeated field adders ------------------------------------------- + // These add an element to a repeated field. + + void AddInt32(Message* message, const FieldDescriptor* field, + arc_i32 value) const; + void AddInt64(Message* message, const FieldDescriptor* field, + arc_i64 value) const; + void AddUInt32(Message* message, const FieldDescriptor* field, + arc_ui32 value) const; + void AddUInt64(Message* message, const FieldDescriptor* field, + arc_ui64 value) const; + void AddFloat(Message* message, const FieldDescriptor* field, + float value) const; + void AddDouble(Message* message, const FieldDescriptor* field, + double value) const; + void AddBool(Message* message, const FieldDescriptor* field, + bool value) const; + void AddString(Message* message, const FieldDescriptor* field, + TProtoStringType value) const; + void AddEnum(Message* message, const FieldDescriptor* field, + const EnumValueDescriptor* value) const; + // Add an integer value to a repeated enum field rather than + // EnumValueDescriptor. For proto3 this is just setting the enum field to the + // value specified, for proto2 it's more complicated. If value is a known enum + // value the field is set as usual. If the value is unknown then it is added + // to the unknown field set. Note this matches the behavior of parsing unknown + // enum values. If multiple calls with unknown values happen than they are all + // added to the unknown field set in order of the calls. + void AddEnumValue(Message* message, const FieldDescriptor* field, + int value) const; + // See MutableMessage() for comments on the "factory" parameter. + Message* AddMessage(Message* message, const FieldDescriptor* field, + MessageFactory* factory = nullptr) const; + + // Appends an already-allocated object 'new_entry' to the repeated field + // specified by 'field' passing ownership to the message. + void AddAllocatedMessage(Message* message, const FieldDescriptor* field, + Message* new_entry) const; + + // Similar to AddAllocatedMessage() without internal safety and ownership + // checks. This method should only be used when the objects are on the same + // arena or paired with a call to `UnsafeArenaReleaseLast`. + void UnsafeArenaAddAllocatedMessage(Message* message, + const FieldDescriptor* field, + Message* new_entry) const; + + + // Get a RepeatedFieldRef object that can be used to read the underlying + // repeated field. The type parameter T must be set according to the + // field's cpp type. The following table shows the mapping from cpp type + // to acceptable T. + // + // field->cpp_type() T + // CPPTYPE_INT32 arc_i32 + // CPPTYPE_UINT32 arc_ui32 + // CPPTYPE_INT64 arc_i64 + // CPPTYPE_UINT64 arc_ui64 + // CPPTYPE_DOUBLE double + // CPPTYPE_FLOAT float + // CPPTYPE_BOOL bool + // CPPTYPE_ENUM generated enum type or arc_i32 + // CPPTYPE_STRING TProtoStringType + // CPPTYPE_MESSAGE generated message type or google::protobuf::Message + // + // A RepeatedFieldRef object can be copied and the resulted object will point + // to the same repeated field in the same message. The object can be used as + // long as the message is not destroyed. + // + // Note that to use this method users need to include the header file + // "reflection.h" (which defines the RepeatedFieldRef class templates). + template <typename T> + RepeatedFieldRef<T> GetRepeatedFieldRef(const Message& message, + const FieldDescriptor* field) const; + + // Like GetRepeatedFieldRef() but return an object that can also be used + // manipulate the underlying repeated field. + template <typename T> + MutableRepeatedFieldRef<T> GetMutableRepeatedFieldRef( + Message* message, const FieldDescriptor* field) const; + + // DEPRECATED. Please use Get(Mutable)RepeatedFieldRef() for repeated field + // access. The following repeated field accessors will be removed in the + // future. + // + // Repeated field accessors ------------------------------------------------- + // The methods above, e.g. GetRepeatedInt32(msg, fd, index), provide singular + // access to the data in a RepeatedField. The methods below provide aggregate + // access by exposing the RepeatedField object itself with the Message. + // Applying these templates to inappropriate types will lead to an undefined + // reference at link time (e.g. GetRepeatedField<***double>), or possibly a + // template matching error at compile time (e.g. GetRepeatedPtrField<File>). + // + // Usage example: my_doubs = refl->GetRepeatedField<double>(msg, fd); + + // DEPRECATED. Please use GetRepeatedFieldRef(). + // + // for T = Cord and all protobuf scalar types except enums. + template <typename T> + PROTOBUF_DEPRECATED_MSG("Please use GetRepeatedFieldRef() instead") + const RepeatedField<T>& GetRepeatedField(const Message& msg, + const FieldDescriptor* d) const { + return GetRepeatedFieldInternal<T>(msg, d); + } + + // DEPRECATED. Please use GetMutableRepeatedFieldRef(). + // + // for T = Cord and all protobuf scalar types except enums. + template <typename T> + PROTOBUF_DEPRECATED_MSG("Please use GetMutableRepeatedFieldRef() instead") + RepeatedField<T>* MutableRepeatedField(Message* msg, + const FieldDescriptor* d) const { + return MutableRepeatedFieldInternal<T>(msg, d); + } + + // DEPRECATED. Please use GetRepeatedFieldRef(). + // + // for T = TProtoStringType, google::protobuf::internal::StringPieceField + // google::protobuf::Message & descendants. + template <typename T> + PROTOBUF_DEPRECATED_MSG("Please use GetRepeatedFieldRef() instead") + const RepeatedPtrField<T>& GetRepeatedPtrField( + const Message& msg, const FieldDescriptor* d) const { + return GetRepeatedPtrFieldInternal<T>(msg, d); + } + + // DEPRECATED. Please use GetMutableRepeatedFieldRef(). + // + // for T = TProtoStringType, google::protobuf::internal::StringPieceField + // google::protobuf::Message & descendants. + template <typename T> + PROTOBUF_DEPRECATED_MSG("Please use GetMutableRepeatedFieldRef() instead") + RepeatedPtrField<T>* MutableRepeatedPtrField(Message* msg, + const FieldDescriptor* d) const { + return MutableRepeatedPtrFieldInternal<T>(msg, d); + } + + // Extensions ---------------------------------------------------------------- + + // Try to find an extension of this message type by fully-qualified field + // name. Returns nullptr if no extension is known for this name or number. + const FieldDescriptor* FindKnownExtensionByName( + const TProtoStringType& name) const; + + // Try to find an extension of this message type by field number. + // Returns nullptr if no extension is known for this name or number. + const FieldDescriptor* FindKnownExtensionByNumber(int number) const; + + // Feature Flags ------------------------------------------------------------- + + // Does this message support storing arbitrary integer values in enum fields? + // If |true|, GetEnumValue/SetEnumValue and associated repeated-field versions + // take arbitrary integer values, and the legacy GetEnum() getter will + // dynamically create an EnumValueDescriptor for any integer value without + // one. If |false|, setting an unknown enum value via the integer-based + // setters results in undefined behavior (in practice, GOOGLE_DCHECK-fails). + // + // Generic code that uses reflection to handle messages with enum fields + // should check this flag before using the integer-based setter, and either + // downgrade to a compatible value or use the UnknownFieldSet if not. For + // example: + // + // int new_value = GetValueFromApplicationLogic(); + // if (reflection->SupportsUnknownEnumValues()) { + // reflection->SetEnumValue(message, field, new_value); + // } else { + // if (field_descriptor->enum_type()-> + // FindValueByNumber(new_value) != nullptr) { + // reflection->SetEnumValue(message, field, new_value); + // } else if (emit_unknown_enum_values) { + // reflection->MutableUnknownFields(message)->AddVarint( + // field->number(), new_value); + // } else { + // // convert value to a compatible/default value. + // new_value = CompatibleDowngrade(new_value); + // reflection->SetEnumValue(message, field, new_value); + // } + // } + bool SupportsUnknownEnumValues() const; + + // Returns the MessageFactory associated with this message. This can be + // useful for determining if a message is a generated message or not, for + // example: + // if (message->GetReflection()->GetMessageFactory() == + // google::protobuf::MessageFactory::generated_factory()) { + // // This is a generated message. + // } + // It can also be used to create more messages of this type, though + // Message::New() is an easier way to accomplish this. + MessageFactory* GetMessageFactory() const; + + private: + template <typename T> + const RepeatedField<T>& GetRepeatedFieldInternal( + const Message& message, const FieldDescriptor* field) const; + template <typename T> + RepeatedField<T>* MutableRepeatedFieldInternal( + Message* message, const FieldDescriptor* field) const; + template <typename T> + const RepeatedPtrField<T>& GetRepeatedPtrFieldInternal( + const Message& message, const FieldDescriptor* field) const; + template <typename T> + RepeatedPtrField<T>* MutableRepeatedPtrFieldInternal( + Message* message, const FieldDescriptor* field) const; + // Obtain a pointer to a Repeated Field Structure and do some type checking: + // on field->cpp_type(), + // on field->field_option().ctype() (if ctype >= 0) + // of field->message_type() (if message_type != nullptr). + // We use 2 routine rather than 4 (const vs mutable) x (scalar vs pointer). + void* MutableRawRepeatedField(Message* message, const FieldDescriptor* field, + FieldDescriptor::CppType, int ctype, + const Descriptor* message_type) const; + + const void* GetRawRepeatedField(const Message& message, + const FieldDescriptor* field, + FieldDescriptor::CppType cpptype, int ctype, + const Descriptor* message_type) const; + + // The following methods are used to implement (Mutable)RepeatedFieldRef. + // A Ref object will store a raw pointer to the repeated field data (obtained + // from RepeatedFieldData()) and a pointer to a Accessor (obtained from + // RepeatedFieldAccessor) which will be used to access the raw data. + + // Returns a raw pointer to the repeated field + // + // "cpp_type" and "message_type" are deduced from the type parameter T passed + // to Get(Mutable)RepeatedFieldRef. If T is a generated message type, + // "message_type" should be set to its descriptor. Otherwise "message_type" + // should be set to nullptr. Implementations of this method should check + // whether "cpp_type"/"message_type" is consistent with the actual type of the + // field. We use 1 routine rather than 2 (const vs mutable) because it is + // protected and it doesn't change the message. + void* RepeatedFieldData(Message* message, const FieldDescriptor* field, + FieldDescriptor::CppType cpp_type, + const Descriptor* message_type) const; + + // The returned pointer should point to a singleton instance which implements + // the RepeatedFieldAccessor interface. + const internal::RepeatedFieldAccessor* RepeatedFieldAccessor( + const FieldDescriptor* field) const; + + // Lists all fields of the message which are currently set, except for unknown + // fields and stripped fields. See ListFields for details. + void ListFieldsOmitStripped( + const Message& message, + std::vector<const FieldDescriptor*>* output) const; + + bool IsMessageStripped(const Descriptor* descriptor) const { + return schema_.IsMessageStripped(descriptor); + } + + friend class TextFormat; + + void ListFieldsMayFailOnStripped( + const Message& message, bool should_fail, + std::vector<const FieldDescriptor*>* output) const; + + // Returns true if the message field is backed by a LazyField. + // + // A message field may be backed by a LazyField without the user annotation + // ([lazy = true]). While the user-annotated LazyField is lazily verified on + // first touch (i.e. failure on access rather than parsing if the LazyField is + // not initialized), the inferred LazyField is eagerly verified to avoid lazy + // parsing error at the cost of lower efficiency. When reflecting a message + // field, use this API instead of checking field->options().lazy(). + bool IsLazyField(const FieldDescriptor* field) const { + return IsLazilyVerifiedLazyField(field) || + IsEagerlyVerifiedLazyField(field); + } + + // Returns true if the field is lazy extension. It is meant to allow python + // reparse lazy field until b/157559327 is fixed. + bool IsLazyExtension(const Message& message, + const FieldDescriptor* field) const; + + bool IsLazilyVerifiedLazyField(const FieldDescriptor* field) const; + bool IsEagerlyVerifiedLazyField(const FieldDescriptor* field) const; + + friend class FastReflectionMessageMutator; + + const Descriptor* const descriptor_; + const internal::ReflectionSchema schema_; + const DescriptorPool* const descriptor_pool_; + MessageFactory* const message_factory_; + + // Last non weak field index. This is an optimization when most weak fields + // are at the end of the containing message. If a message proto doesn't + // contain weak fields, then this field equals descriptor_->field_count(). + int last_non_weak_field_index_; + + template <typename T, typename Enable> + friend class RepeatedFieldRef; + template <typename T, typename Enable> + friend class MutableRepeatedFieldRef; + friend class ::PROTOBUF_NAMESPACE_ID::MessageLayoutInspector; + friend class ::PROTOBUF_NAMESPACE_ID::AssignDescriptorsHelper; + friend class DynamicMessageFactory; + friend class DynamicMessageReflectionHelper; + 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; + friend class internal::MapFieldReflectionTest; + 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; + + Reflection(const Descriptor* descriptor, + const internal::ReflectionSchema& schema, + const DescriptorPool* pool, MessageFactory* factory); + + // Special version for specialized implementations of string. We can't + // call MutableRawRepeatedField directly here because we don't have access to + // FieldOptions::* which are defined in descriptor.pb.h. Including that + // file here is not possible because it would cause a circular include cycle. + // We use 1 routine rather than 2 (const vs mutable) because it is private + // and mutable a repeated string field doesn't change the message. + void* MutableRawRepeatedString(Message* message, const FieldDescriptor* field, + bool is_string) const; + + friend class MapReflectionTester; + // Returns true if key is in map. Returns false if key is not in map field. + bool ContainsMapKey(const Message& message, const FieldDescriptor* field, + const MapKey& key) const; + + // If key is in map field: Saves the value pointer to val and returns + // false. If key in not in map field: Insert the key into map, saves + // value pointer to val and returns true. Users are able to modify the + // map value by MapValueRef. + bool InsertOrLookupMapValue(Message* message, const FieldDescriptor* field, + const MapKey& key, MapValueRef* val) const; + + // If key is in map field: Saves the value pointer to val and returns true. + // Returns false if key is not in map field. Users are NOT able to modify + // the value by MapValueConstRef. + bool LookupMapValue(const Message& message, const FieldDescriptor* field, + const MapKey& key, MapValueConstRef* val) const; + bool LookupMapValue(const Message&, const FieldDescriptor*, const MapKey&, + MapValueRef*) const = delete; + + // Delete and returns true if key is in the map field. Returns false + // otherwise. + bool DeleteMapValue(Message* message, const FieldDescriptor* field, + const MapKey& key) const; + + // Returns a MapIterator referring to the first element in the map field. + // If the map field is empty, this function returns the same as + // reflection::MapEnd. Mutation to the field may invalidate the iterator. + MapIterator MapBegin(Message* message, const FieldDescriptor* field) const; + + // Returns a MapIterator referring to the theoretical element that would + // follow the last element in the map field. It does not point to any + // real element. Mutation to the field may invalidate the iterator. + MapIterator MapEnd(Message* message, const FieldDescriptor* field) const; + + // Get the number of <key, value> pair of a map field. The result may be + // different from FieldSize which can have duplicate keys. + int MapSize(const Message& message, const FieldDescriptor* field) const; + + // Help method for MapIterator. + friend class MapIterator; + friend class WireFormatForMapFieldTest; + internal::MapFieldBase* MutableMapData(Message* message, + const FieldDescriptor* field) const; + + const internal::MapFieldBase* GetMapData(const Message& message, + const FieldDescriptor* field) const; + + template <class T> + const T& GetRawNonOneof(const Message& message, + const FieldDescriptor* field) const; + template <class T> + T* MutableRawNonOneof(Message* message, const FieldDescriptor* field) const; + + template <typename Type> + const Type& GetRaw(const Message& message, + const FieldDescriptor* field) const; + template <typename Type> + inline Type* MutableRaw(Message* message, const FieldDescriptor* field) const; + template <typename Type> + const Type& DefaultRaw(const FieldDescriptor* field) const; + + const Message* GetDefaultMessageInstance(const FieldDescriptor* field) const; + + inline const arc_ui32* GetHasBits(const Message& message) const; + inline arc_ui32* MutableHasBits(Message* message) const; + inline arc_ui32 GetOneofCase(const Message& message, + const OneofDescriptor* oneof_descriptor) const; + inline arc_ui32* MutableOneofCase( + Message* message, const OneofDescriptor* oneof_descriptor) const; + inline bool HasExtensionSet(const Message& /* message */) const { + return schema_.HasExtensionSet(); + } + const internal::ExtensionSet& GetExtensionSet(const Message& message) const; + internal::ExtensionSet* MutableExtensionSet(Message* message) const; + + inline const internal::InternalMetadata& GetInternalMetadata( + const Message& message) const; + + internal::InternalMetadata* MutableInternalMetadata(Message* message) const; + + inline bool IsInlined(const FieldDescriptor* field) const; + + inline bool HasBit(const Message& message, + const FieldDescriptor* field) const; + inline void SetBit(Message* message, const FieldDescriptor* field) const; + inline void ClearBit(Message* message, const FieldDescriptor* field) const; + inline void SwapBit(Message* message1, Message* message2, + const FieldDescriptor* field) const; + + inline const arc_ui32* GetInlinedStringDonatedArray( + const Message& message) const; + inline arc_ui32* MutableInlinedStringDonatedArray(Message* message) const; + inline bool IsInlinedStringDonated(const Message& message, + 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; + + template <bool unsafe_shallow_swap> + void SwapOneofField(Message* lhs, Message* rhs, + const OneofDescriptor* oneof_descriptor) const; + + inline bool HasOneofField(const Message& message, + const FieldDescriptor* field) const; + inline void SetOneofCase(Message* message, + const FieldDescriptor* field) const; + inline void ClearOneofField(Message* message, + const FieldDescriptor* field) const; + + template <typename Type> + inline const Type& GetField(const Message& message, + const FieldDescriptor* field) const; + template <typename Type> + inline void SetField(Message* message, const FieldDescriptor* field, + const Type& value) const; + template <typename Type> + inline Type* MutableField(Message* message, + const FieldDescriptor* field) const; + template <typename Type> + inline const Type& GetRepeatedField(const Message& message, + const FieldDescriptor* field, + int index) const; + template <typename Type> + inline const Type& GetRepeatedPtrField(const Message& message, + const FieldDescriptor* field, + int index) const; + template <typename Type> + inline void SetRepeatedField(Message* message, const FieldDescriptor* field, + int index, Type value) const; + template <typename Type> + inline Type* MutableRepeatedField(Message* message, + const FieldDescriptor* field, + int index) const; + template <typename Type> + inline void AddField(Message* message, const FieldDescriptor* field, + const Type& value) const; + template <typename Type> + inline Type* AddField(Message* message, const FieldDescriptor* field) const; + + int GetExtensionNumberOrDie(const Descriptor* type) const; + + // Internal versions of EnumValue API perform no checking. Called after checks + // by public methods. + void SetEnumValueInternal(Message* message, const FieldDescriptor* field, + int value) const; + void SetRepeatedEnumValueInternal(Message* message, + const FieldDescriptor* field, int index, + int value) const; + void AddEnumValueInternal(Message* message, const FieldDescriptor* field, + int value) const; + + friend inline // inline so nobody can call this function. + void + RegisterAllTypesInternal(const Metadata* file_level_metadata, int size); + friend inline const char* ParseLenDelim(int field_number, + const FieldDescriptor* field, + Message* msg, + const Reflection* reflection, + const char* ptr, + internal::ParseContext* ctx); + friend inline const char* ParsePackedField(const FieldDescriptor* field, + Message* msg, + const Reflection* reflection, + const char* ptr, + internal::ParseContext* ctx); + + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(Reflection); +}; + +// Abstract interface for a factory for message objects. +class PROTOBUF_EXPORT MessageFactory { + public: + inline MessageFactory() {} + virtual ~MessageFactory(); + + // Given a Descriptor, gets or constructs the default (prototype) Message + // of that type. You can then call that message's New() method to construct + // a mutable message of that type. + // + // Calling this method twice with the same Descriptor returns the same + // object. The returned object remains property of the factory. Also, any + // objects created by calling the prototype's New() method share some data + // with the prototype, so these must be destroyed before the MessageFactory + // is destroyed. + // + // The given descriptor must outlive the returned message, and hence must + // outlive the MessageFactory. + // + // Some implementations do not support all types. GetPrototype() will + // return nullptr if the descriptor passed in is not supported. + // + // This method may or may not be thread-safe depending on the implementation. + // Each implementation should document its own degree thread-safety. + virtual const Message* GetPrototype(const Descriptor* type) = 0; + + // Gets a MessageFactory which supports all generated, compiled-in messages. + // In other words, for any compiled-in type FooMessage, the following is true: + // MessageFactory::generated_factory()->GetPrototype( + // FooMessage::descriptor()) == FooMessage::default_instance() + // This factory supports all types which are found in + // DescriptorPool::generated_pool(). If given a descriptor from any other + // pool, GetPrototype() will return nullptr. (You can also check if a + // descriptor is for a generated message by checking if + // descriptor->file()->pool() == DescriptorPool::generated_pool().) + // + // This factory is 100% thread-safe; calling GetPrototype() does not modify + // any shared data. + // + // This factory is a singleton. The caller must not delete the object. + static MessageFactory* generated_factory(); + + // For internal use only: Registers a .proto file at static initialization + // time, to be placed in generated_factory. The first time GetPrototype() + // is called with a descriptor from this file, |register_messages| will be + // called, with the file name as the parameter. It must call + // InternalRegisterGeneratedMessage() (below) to register each message type + // in the file. This strange mechanism is necessary because descriptors are + // built lazily, so we can't register types by their descriptor until we + // know that the descriptor exists. |filename| must be a permanent string. + static void InternalRegisterGeneratedFile( + const google::protobuf::internal::DescriptorTable* table); + + // For internal use only: Registers a message type. Called only by the + // functions which are registered with InternalRegisterGeneratedFile(), + // above. + static void InternalRegisterGeneratedMessage(const Descriptor* descriptor, + const Message* prototype); + + + private: + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(MessageFactory); +}; + +#define DECLARE_GET_REPEATED_FIELD(TYPE) \ + template <> \ + PROTOBUF_EXPORT const RepeatedField<TYPE>& \ + Reflection::GetRepeatedFieldInternal<TYPE>( \ + const Message& message, const FieldDescriptor* field) const; \ + \ + template <> \ + PROTOBUF_EXPORT RepeatedField<TYPE>* \ + Reflection::MutableRepeatedFieldInternal<TYPE>( \ + Message * message, const FieldDescriptor* field) const; + +DECLARE_GET_REPEATED_FIELD(arc_i32) +DECLARE_GET_REPEATED_FIELD(arc_i64) +DECLARE_GET_REPEATED_FIELD(arc_ui32) +DECLARE_GET_REPEATED_FIELD(arc_ui64) +DECLARE_GET_REPEATED_FIELD(float) +DECLARE_GET_REPEATED_FIELD(double) +DECLARE_GET_REPEATED_FIELD(bool) + +#undef DECLARE_GET_REPEATED_FIELD + +// Tries to downcast this message to a generated message type. Returns nullptr +// if this class is not an instance of T. This works even if RTTI is disabled. +// +// This also has the effect of creating a strong reference to T that will +// prevent the linker from stripping it out at link time. This can be important +// if you are using a DynamicMessageFactory that delegates to the generated +// factory. +template <typename T> +const T* DynamicCastToGenerated(const Message* from) { + // Compile-time assert that T is a generated type that has a + // default_instance() accessor, but avoid actually calling it. + const T& (*get_default_instance)() = &T::default_instance; + (void)get_default_instance; + + // Compile-time assert that T is a subclass of google::protobuf::Message. + const Message* unused = static_cast<T*>(nullptr); + (void)unused; + +#if PROTOBUF_RTTI + return dynamic_cast<const T*>(from); +#else + bool ok = from != nullptr && + T::default_instance().GetReflection() == from->GetReflection(); + return ok ? down_cast<const T*>(from) : nullptr; +#endif +} + +template <typename T> +T* DynamicCastToGenerated(Message* from) { + const Message* message_const = from; + return const_cast<T*>(DynamicCastToGenerated<T>(message_const)); +} + +// Call this function to ensure that this message's reflection is linked into +// the binary: +// +// google::protobuf::LinkMessageReflection<FooMessage>(); +// +// This will ensure that the following lookup will succeed: +// +// DescriptorPool::generated_pool()->FindMessageTypeByName("FooMessage"); +// +// As a side-effect, it will also guarantee that anything else from the same +// .proto file will also be available for lookup in the generated pool. +// +// This function does not actually register the message, so it does not need +// to be called before the lookup. However it does need to occur in a function +// that cannot be stripped from the binary (ie. it must be reachable from main). +// +// Best practice is to call this function as close as possible to where the +// reflection is actually needed. This function is very cheap to call, so you +// should not need to worry about its runtime overhead except in the tightest +// of loops (on x86-64 it compiles into two "mov" instructions). +template <typename T> +void LinkMessageReflection() { + internal::StrongReference(T::default_instance); +} + +// ============================================================================= +// Implementation details for {Get,Mutable}RawRepeatedPtrField. We provide +// specializations for <TProtoStringType>, <StringPieceField> and <Message> and +// handle everything else with the default template which will match any type +// having a method with signature "static const google::protobuf::Descriptor* +// descriptor()". Such a type presumably is a descendant of google::protobuf::Message. + +template <> +inline const RepeatedPtrField<TProtoStringType>& +Reflection::GetRepeatedPtrFieldInternal<TProtoStringType>( + const Message& message, const FieldDescriptor* field) const { + return *static_cast<RepeatedPtrField<TProtoStringType>*>( + MutableRawRepeatedString(const_cast<Message*>(&message), field, true)); +} + +template <> +inline RepeatedPtrField<TProtoStringType>* +Reflection::MutableRepeatedPtrFieldInternal<TProtoStringType>( + Message* message, const FieldDescriptor* field) const { + return static_cast<RepeatedPtrField<TProtoStringType>*>( + MutableRawRepeatedString(message, field, true)); +} + + +// ----- + +template <> +inline const RepeatedPtrField<Message>& Reflection::GetRepeatedPtrFieldInternal( + const Message& message, const FieldDescriptor* field) const { + return *static_cast<const RepeatedPtrField<Message>*>(GetRawRepeatedField( + message, field, FieldDescriptor::CPPTYPE_MESSAGE, -1, nullptr)); +} + +template <> +inline RepeatedPtrField<Message>* Reflection::MutableRepeatedPtrFieldInternal( + Message* message, const FieldDescriptor* field) const { + return static_cast<RepeatedPtrField<Message>*>(MutableRawRepeatedField( + message, field, FieldDescriptor::CPPTYPE_MESSAGE, -1, nullptr)); +} + +template <typename PB> +inline const RepeatedPtrField<PB>& Reflection::GetRepeatedPtrFieldInternal( + const Message& message, const FieldDescriptor* field) const { + return *static_cast<const RepeatedPtrField<PB>*>( + GetRawRepeatedField(message, field, FieldDescriptor::CPPTYPE_MESSAGE, -1, + PB::default_instance().GetDescriptor())); +} + +template <typename PB> +inline RepeatedPtrField<PB>* Reflection::MutableRepeatedPtrFieldInternal( + Message* message, const FieldDescriptor* field) const { + return static_cast<RepeatedPtrField<PB>*>( + MutableRawRepeatedField(message, field, FieldDescriptor::CPPTYPE_MESSAGE, + -1, PB::default_instance().GetDescriptor())); +} + +template <typename Type> +const Type& Reflection::DefaultRaw(const FieldDescriptor* field) const { + return *reinterpret_cast<const Type*>(schema_.GetFieldDefault(field)); +} + +arc_ui32 Reflection::GetOneofCase( + const Message& message, const OneofDescriptor* oneof_descriptor) const { + GOOGLE_DCHECK(!oneof_descriptor->is_synthetic()); + return internal::GetConstRefAtOffset<arc_ui32>( + message, schema_.GetOneofCaseOffset(oneof_descriptor)); +} + +bool Reflection::HasOneofField(const Message& message, + const FieldDescriptor* field) const { + return (GetOneofCase(message, field->containing_oneof()) == + static_cast<arc_ui32>(field->number())); +} + +template <typename Type> +const Type& Reflection::GetRaw(const Message& message, + const FieldDescriptor* field) const { + GOOGLE_DCHECK(!schema_.InRealOneof(field) || HasOneofField(message, field)) + << "Field = " << field->full_name(); + return internal::GetConstRefAtOffset<Type>(message, + schema_.GetFieldOffset(field)); +} +} // namespace protobuf +} // namespace google + +#include <google/protobuf/port_undef.inc> + +#endif // GOOGLE_PROTOBUF_MESSAGE_H__ diff --git a/contrib/libs/protobuf_old/src/google/protobuf/message_lite.cc b/contrib/libs/protobuf_old/src/google/protobuf/message_lite.cc new file mode 100644 index 0000000000..f644dd834d --- /dev/null +++ b/contrib/libs/protobuf_old/src/google/protobuf/message_lite.cc @@ -0,0 +1,626 @@ +// 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. + +// Authors: wink@google.com (Wink Saville), +// kenton@google.com (Kenton Varda) +// Based on original Protocol Buffers design by +// Sanjay Ghemawat, Jeff Dean, and others. + +#include <google/protobuf/message_lite.h> + +#include <climits> +#include <cstdint> +#include <string> + +#include <google/protobuf/stubs/logging.h> +#include <google/protobuf/stubs/common.h> +#include <google/protobuf/stubs/stringprintf.h> +#include <google/protobuf/parse_context.h> +#include <google/protobuf/io/coded_stream.h> +#include <google/protobuf/io/zero_copy_stream.h> +#include <google/protobuf/io/zero_copy_stream_impl.h> +#include <google/protobuf/io/zero_copy_stream_impl_lite.h> +#include <google/protobuf/arena.h> +#include <google/protobuf/generated_message_table_driven.h> +#include <google/protobuf/generated_message_util.h> +#include <google/protobuf/repeated_field.h> +#include <google/protobuf/stubs/strutil.h> +#include <google/protobuf/stubs/stl_util.h> +#include <google/protobuf/stubs/mutex.h> + +#include <google/protobuf/port_def.inc> + +namespace google { +namespace protobuf { + +TProtoStringType MessageLite::InitializationErrorString() const { + return "(cannot determine missing fields for lite message)"; +} + +TProtoStringType MessageLite::DebugString() const { + std::uintptr_t address = reinterpret_cast<std::uintptr_t>(this); + return StrCat("MessageLite at 0x", strings::Hex(address)); +} + +namespace { + +// When serializing, we first compute the byte size, then serialize the message. +// If serialization produces a different number of bytes than expected, we +// call this function, which crashes. The problem could be due to a bug in the +// protobuf implementation but is more likely caused by concurrent modification +// of the message. This function attempts to distinguish between the two and +// provide a useful error message. +void ByteSizeConsistencyError(size_t byte_size_before_serialization, + size_t byte_size_after_serialization, + size_t bytes_produced_by_serialization, + const MessageLite& message) { + GOOGLE_CHECK_EQ(byte_size_before_serialization, byte_size_after_serialization) + << message.GetTypeName() + << " was modified concurrently during serialization."; + GOOGLE_CHECK_EQ(bytes_produced_by_serialization, byte_size_before_serialization) + << "Byte size calculation and serialization were inconsistent. This " + "may indicate a bug in protocol buffers or it may be caused by " + "concurrent modification of " + << message.GetTypeName() << "."; + GOOGLE_LOG(FATAL) << "This shouldn't be called if all the sizes are equal."; +} + +} // anonymous namespace + +TProtoStringType InitializationErrorMessage(const char* action, + const MessageLite& message) { + // Note: We want to avoid depending on strutil in the lite library, otherwise + // we'd use: + // + // return strings::Substitute( + // "Can't $0 message of type \"$1\" because it is missing required " + // "fields: $2", + // action, message.GetTypeName(), + // message.InitializationErrorString()); + + TProtoStringType result; + result += "Can't "; + result += action; + result += " message of type \""; + result += message.GetTypeName(); + result += "\" because it is missing required fields: "; + result += message.InitializationErrorString(); + return result; +} + +namespace { + +inline StringPiece as_string_view(const void* data, int size) { + return StringPiece(static_cast<const char*>(data), size); +} + +// Returns true of all required fields are present / have values. +inline bool CheckFieldPresence(const internal::ParseContext& ctx, + const MessageLite& msg, + MessageLite::ParseFlags parse_flags) { + (void)ctx; // Parameter is used by Google-internal code. + if (PROTOBUF_PREDICT_FALSE((parse_flags & MessageLite::kMergePartial) != 0)) { + return true; + } + return msg.IsInitializedWithErrors(); +} + +} // namespace + +void MessageLite::LogInitializationErrorMessage() const { + GOOGLE_LOG(ERROR) << InitializationErrorMessage("parse", *this); +} + +namespace internal { + +template <bool aliasing> +bool MergeFromImpl(StringPiece input, MessageLite* msg, + MessageLite::ParseFlags parse_flags) { + const char* ptr; + internal::ParseContext ctx(io::CodedInputStream::GetDefaultRecursionLimit(), + aliasing, &ptr, input); + ptr = msg->_InternalParse(ptr, &ctx); + // ctx has an explicit limit set (length of string_view). + if (PROTOBUF_PREDICT_TRUE(ptr && ctx.EndedAtLimit())) { + return CheckFieldPresence(ctx, *msg, parse_flags); + } + return false; +} + +template <bool aliasing> +bool MergeFromImpl(io::ZeroCopyInputStream* input, MessageLite* msg, + MessageLite::ParseFlags parse_flags) { + const char* ptr; + internal::ParseContext ctx(io::CodedInputStream::GetDefaultRecursionLimit(), + aliasing, &ptr, input); + ptr = msg->_InternalParse(ptr, &ctx); + // ctx has no explicit limit (hence we end on end of stream) + if (PROTOBUF_PREDICT_TRUE(ptr && ctx.EndedAtEndOfStream())) { + return CheckFieldPresence(ctx, *msg, parse_flags); + } + return false; +} + +template <bool aliasing> +bool MergeFromImpl(BoundedZCIS input, MessageLite* msg, + MessageLite::ParseFlags parse_flags) { + const char* ptr; + internal::ParseContext ctx(io::CodedInputStream::GetDefaultRecursionLimit(), + aliasing, &ptr, input.zcis, input.limit); + ptr = msg->_InternalParse(ptr, &ctx); + if (PROTOBUF_PREDICT_FALSE(!ptr)) return false; + ctx.BackUp(ptr); + if (PROTOBUF_PREDICT_TRUE(ctx.EndedAtLimit())) { + return CheckFieldPresence(ctx, *msg, parse_flags); + } + return false; +} + +template bool MergeFromImpl<false>(StringPiece input, MessageLite* msg, + MessageLite::ParseFlags parse_flags); +template bool MergeFromImpl<true>(StringPiece input, MessageLite* msg, + MessageLite::ParseFlags parse_flags); +template bool MergeFromImpl<false>(io::ZeroCopyInputStream* input, + MessageLite* msg, + MessageLite::ParseFlags parse_flags); +template bool MergeFromImpl<true>(io::ZeroCopyInputStream* input, + MessageLite* msg, + MessageLite::ParseFlags parse_flags); +template bool MergeFromImpl<false>(BoundedZCIS input, MessageLite* msg, + MessageLite::ParseFlags parse_flags); +template bool MergeFromImpl<true>(BoundedZCIS input, MessageLite* msg, + MessageLite::ParseFlags parse_flags); + +} // namespace internal + +class ZeroCopyCodedInputStream : public io::ZeroCopyInputStream { + public: + ZeroCopyCodedInputStream(io::CodedInputStream* cis) : cis_(cis) {} + bool Next(const void** data, int* size) final { + if (!cis_->GetDirectBufferPointer(data, size)) return false; + cis_->Skip(*size); + return true; + } + void BackUp(int count) final { cis_->Advance(-count); } + bool Skip(int count) final { return cis_->Skip(count); } + int64_t ByteCount() const final { return 0; } + + bool aliasing_enabled() { return cis_->aliasing_enabled_; } + + private: + io::CodedInputStream* cis_; +}; + +bool MessageLite::MergeFromImpl(io::CodedInputStream* input, + MessageLite::ParseFlags parse_flags) { + ZeroCopyCodedInputStream zcis(input); + const char* ptr; + internal::ParseContext ctx(input->RecursionBudget(), zcis.aliasing_enabled(), + &ptr, &zcis); + // MergePartialFromCodedStream allows terminating the wireformat by 0 or + // end-group tag. Leaving it up to the caller to verify correct ending by + // calling LastTagWas on input. We need to maintain this behavior. + ctx.TrackCorrectEnding(); + ctx.data().pool = input->GetExtensionPool(); + ctx.data().factory = input->GetExtensionFactory(); + ptr = _InternalParse(ptr, &ctx); + if (PROTOBUF_PREDICT_FALSE(!ptr)) return false; + ctx.BackUp(ptr); + if (!ctx.EndedAtEndOfStream()) { + GOOGLE_DCHECK(ctx.LastTag() != 1); // We can't end on a pushed limit. + if (ctx.IsExceedingLimit(ptr)) return false; + input->SetLastTag(ctx.LastTag()); + } else { + input->SetConsumed(); + } + return CheckFieldPresence(ctx, *this, parse_flags); +} + +bool MessageLite::MergePartialFromCodedStream(io::CodedInputStream* input) { + return MergeFromImpl(input, kMergePartial); +} + +bool MessageLite::MergeFromCodedStream(io::CodedInputStream* input) { + return MergeFromImpl(input, kMerge); +} + +bool MessageLite::ParseFromCodedStream(io::CodedInputStream* input) { + Clear(); + return MergeFromImpl(input, kParse); +} + +bool MessageLite::ParsePartialFromCodedStream(io::CodedInputStream* input) { + Clear(); + return MergeFromImpl(input, kParsePartial); +} + +bool MessageLite::ParseFromZeroCopyStream(io::ZeroCopyInputStream* input) { + return ParseFrom<kParse>(input); +} + +bool MessageLite::ParsePartialFromZeroCopyStream( + io::ZeroCopyInputStream* input) { + return ParseFrom<kParsePartial>(input); +} + +bool MessageLite::ParseFromFileDescriptor(int file_descriptor) { + io::FileInputStream input(file_descriptor); + return ParseFromZeroCopyStream(&input) && input.GetErrno() == 0; +} + +bool MessageLite::ParsePartialFromFileDescriptor(int file_descriptor) { + io::FileInputStream input(file_descriptor); + return ParsePartialFromZeroCopyStream(&input) && input.GetErrno() == 0; +} + +bool MessageLite::ParseFromIstream(std::istream* input) { + io::IstreamInputStream zero_copy_input(input); + return ParseFromZeroCopyStream(&zero_copy_input) && input->eof(); +} + +bool MessageLite::ParsePartialFromIstream(std::istream* input) { + io::IstreamInputStream zero_copy_input(input); + return ParsePartialFromZeroCopyStream(&zero_copy_input) && input->eof(); +} + +bool MessageLite::MergePartialFromBoundedZeroCopyStream( + io::ZeroCopyInputStream* input, int size) { + return ParseFrom<kMergePartial>(internal::BoundedZCIS{input, size}); +} + +bool MessageLite::MergeFromBoundedZeroCopyStream(io::ZeroCopyInputStream* input, + int size) { + return ParseFrom<kMerge>(internal::BoundedZCIS{input, size}); +} + +bool MessageLite::ParseFromBoundedZeroCopyStream(io::ZeroCopyInputStream* input, + int size) { + return ParseFrom<kParse>(internal::BoundedZCIS{input, size}); +} + +bool MessageLite::ParsePartialFromBoundedZeroCopyStream( + io::ZeroCopyInputStream* input, int size) { + return ParseFrom<kParsePartial>(internal::BoundedZCIS{input, size}); +} + +bool MessageLite::ParseFromString(ConstStringParam data) { + return ParseFrom<kParse>(data); +} + +bool MessageLite::ParsePartialFromString(ConstStringParam data) { + return ParseFrom<kParsePartial>(data); +} + +bool MessageLite::ParseFromArray(const void* data, int size) { + return ParseFrom<kParse>(as_string_view(data, size)); +} + +bool MessageLite::ParsePartialFromArray(const void* data, int size) { + return ParseFrom<kParsePartial>(as_string_view(data, size)); +} + +bool MessageLite::MergeFromString(ConstStringParam data) { + return ParseFrom<kMerge>(data); +} + + +// =================================================================== + +inline uint8_t* SerializeToArrayImpl(const MessageLite& msg, uint8_t* target, + int size) { + constexpr bool debug = false; + if (debug) { + // Force serialization to a stream with a block size of 1, which forces + // all writes to the stream to cross buffers triggering all fallback paths + // in the unittests when serializing to string / array. + io::ArrayOutputStream stream(target, size, 1); + uint8_t* ptr; + io::EpsCopyOutputStream out( + &stream, io::CodedOutputStream::IsDefaultSerializationDeterministic(), + &ptr); + ptr = msg._InternalSerialize(ptr, &out); + out.Trim(ptr); + GOOGLE_DCHECK(!out.HadError() && stream.ByteCount() == size); + return target + size; + } else { + io::EpsCopyOutputStream out( + target, size, + io::CodedOutputStream::IsDefaultSerializationDeterministic()); + auto res = msg._InternalSerialize(target, &out); + GOOGLE_DCHECK(target + size == res); + return res; + } +} + +uint8_t* MessageLite::SerializeWithCachedSizesToArray(uint8_t* target) const { + // We only optimize this when using optimize_for = SPEED. In other cases + // we just use the CodedOutputStream path. + return SerializeToArrayImpl(*this, target, GetCachedSize()); +} + +bool MessageLite::SerializeToCodedStream(io::CodedOutputStream* output) const { + GOOGLE_DCHECK(IsInitialized()) << InitializationErrorMessage("serialize", *this); + return SerializePartialToCodedStream(output); +} + +bool MessageLite::SerializePartialToCodedStream( + io::CodedOutputStream* output) const { + const size_t size = ByteSizeLong(); // Force size to be cached. + if (size > INT_MAX) { + GOOGLE_LOG(ERROR) << GetTypeName() + << " exceeded maximum protobuf size of 2GB: " << size; + return false; + } + + int original_byte_count = output->ByteCount(); + SerializeWithCachedSizes(output); + if (output->HadError()) { + return false; + } + int final_byte_count = output->ByteCount(); + + if (final_byte_count - original_byte_count != static_cast<arc_i64>(size)) { + ByteSizeConsistencyError(size, ByteSizeLong(), + final_byte_count - original_byte_count, *this); + } + + return true; +} + +bool MessageLite::SerializeToZeroCopyStream( + io::ZeroCopyOutputStream* output) const { + GOOGLE_DCHECK(IsInitialized()) << InitializationErrorMessage("serialize", *this); + return SerializePartialToZeroCopyStream(output); +} + +bool MessageLite::SerializePartialToZeroCopyStream( + io::ZeroCopyOutputStream* output) const { + const size_t size = ByteSizeLong(); // Force size to be cached. + if (size > INT_MAX) { + GOOGLE_LOG(ERROR) << GetTypeName() + << " exceeded maximum protobuf size of 2GB: " << size; + return false; + } + + uint8_t* target; + io::EpsCopyOutputStream stream( + output, io::CodedOutputStream::IsDefaultSerializationDeterministic(), + &target); + target = _InternalSerialize(target, &stream); + stream.Trim(target); + if (stream.HadError()) return false; + return true; +} + +bool MessageLite::SerializeToFileDescriptor(int file_descriptor) const { + io::FileOutputStream output(file_descriptor); + return SerializeToZeroCopyStream(&output) && output.Flush(); +} + +bool MessageLite::SerializePartialToFileDescriptor(int file_descriptor) const { + io::FileOutputStream output(file_descriptor); + return SerializePartialToZeroCopyStream(&output) && output.Flush(); +} + +bool MessageLite::SerializeToOstream(std::ostream* output) const { + { + io::OstreamOutputStream zero_copy_output(output); + if (!SerializeToZeroCopyStream(&zero_copy_output)) return false; + } + return output->good(); +} + +bool MessageLite::SerializePartialToOstream(std::ostream* output) const { + io::OstreamOutputStream zero_copy_output(output); + return SerializePartialToZeroCopyStream(&zero_copy_output); +} + +bool MessageLite::AppendToString(TProtoStringType* output) const { + GOOGLE_DCHECK(IsInitialized()) << InitializationErrorMessage("serialize", *this); + return AppendPartialToString(output); +} + +bool MessageLite::AppendPartialToString(TProtoStringType* output) const { + size_t old_size = output->size(); + size_t byte_size = ByteSizeLong(); + if (byte_size > INT_MAX) { + GOOGLE_LOG(ERROR) << GetTypeName() + << " exceeded maximum protobuf size of 2GB: " << byte_size; + return false; + } + + STLStringResizeUninitializedAmortized(output, old_size + byte_size); + uint8_t* start = + reinterpret_cast<uint8_t*>(io::mutable_string_data(output) + old_size); + SerializeToArrayImpl(*this, start, byte_size); + return true; +} + +bool MessageLite::SerializeToString(TProtoStringType* output) const { + output->clear(); + return AppendToString(output); +} + +bool MessageLite::SerializePartialToString(TProtoStringType* output) const { + output->clear(); + return AppendPartialToString(output); +} + +bool MessageLite::SerializeToArray(void* data, int size) const { + GOOGLE_DCHECK(IsInitialized()) << InitializationErrorMessage("serialize", *this); + return SerializePartialToArray(data, size); +} + +bool MessageLite::SerializePartialToArray(void* data, int size) const { + const size_t byte_size = ByteSizeLong(); + if (byte_size > INT_MAX) { + GOOGLE_LOG(ERROR) << GetTypeName() + << " exceeded maximum protobuf size of 2GB: " << byte_size; + return false; + } + if (size < static_cast<arc_i64>(byte_size)) return false; + uint8_t* start = reinterpret_cast<uint8_t*>(data); + SerializeToArrayImpl(*this, start, byte_size); + return true; +} + +TProtoStringType MessageLite::SerializeAsString() const { + // If the compiler implements the (Named) Return Value Optimization, + // the local variable 'output' will not actually reside on the stack + // of this function, but will be overlaid with the object that the + // caller supplied for the return value to be constructed in. + TProtoStringType output; + if (!AppendToString(&output)) output.clear(); + return output; +} + +TProtoStringType MessageLite::SerializePartialAsString() const { + TProtoStringType output; + if (!AppendPartialToString(&output)) output.clear(); + return output; +} + +#if PROTOBUF_USE_EXCEPTIONS && defined(__cpp_lib_string_view) +void MessageLite::ParseFromStringOrThrow(std::string_view s) { + const bool isOk = ParseFromArray(s.data(), s.size()); + if (!isOk) { + throw FatalException("message_lite.cc", __LINE__, "Failed to parse protobuf message " + GetTypeName()); + } +} +#endif + +#if PROTOBUF_USE_EXCEPTIONS +TProtoStringType NProtoBuf::MessageLite::SerializeAsStringOrThrow() const { + TProtoStringType s; + if (!IsInitialized()) { + //NOTE: SerializeToString (called inside SerializeAsString too) does not perform this check in release build + // so SerializeToString in release build return false only if result size is greater than 2gb + // but in debug build not properly inited message (without required filds) will lead to an exception + // different control flow in debug and build release look like a bug + throw FatalException("message_lite.cc", __LINE__, "Some required fileds are not set in message " + GetTypeName()); + } + const bool isOk = SerializeToString(&s); + if (!isOk) { + throw FatalException("message_lite.cc", __LINE__, "Failed to serialize protobuf message " + GetTypeName()); + } + return s; +} +#endif + + +namespace internal { + +template <> +MessageLite* GenericTypeHandler<MessageLite>::NewFromPrototype( + const MessageLite* prototype, Arena* arena) { + return prototype->New(arena); +} +template <> +void GenericTypeHandler<MessageLite>::Merge(const MessageLite& from, + MessageLite* to) { + to->CheckTypeAndMergeFrom(from); +} +template <> +void GenericTypeHandler<TProtoStringType>::Merge(const TProtoStringType& from, + TProtoStringType* to) { + *to = from; +} + +// Non-inline variants of TProtoStringType specializations for +// various InternalMetadata routines. +template <> +void InternalMetadata::DoClear<TProtoStringType>() { + mutable_unknown_fields<TProtoStringType>()->clear(); +} + +template <> +void InternalMetadata::DoMergeFrom<TProtoStringType>(const TProtoStringType& other) { + mutable_unknown_fields<TProtoStringType>()->append(other); +} + +template <> +void InternalMetadata::DoSwap<TProtoStringType>(TProtoStringType* other) { + mutable_unknown_fields<TProtoStringType>()->swap(*other); +} + +} // namespace internal + + +// =================================================================== +// Shutdown support. + +namespace internal { + +struct ShutdownData { + ~ShutdownData() { + std::reverse(functions.begin(), functions.end()); + for (auto pair : functions) pair.first(pair.second); + } + + static ShutdownData* get() { + static auto* data = new ShutdownData; + return data; + } + + std::vector<std::pair<void (*)(const void*), const void*>> functions; + Mutex mutex; +}; + +static void RunZeroArgFunc(const void* arg) { + void (*func)() = reinterpret_cast<void (*)()>(const_cast<void*>(arg)); + func(); +} + +void OnShutdown(void (*func)()) { + OnShutdownRun(RunZeroArgFunc, reinterpret_cast<void*>(func)); +} + +void OnShutdownRun(void (*f)(const void*), const void* arg) { + auto shutdown_data = ShutdownData::get(); + MutexLock lock(&shutdown_data->mutex); + shutdown_data->functions.push_back(std::make_pair(f, arg)); +} + +} // namespace internal + +void ShutdownProtobufLibrary() { + // This function should be called only once, but accepts multiple calls. + static bool is_shutdown = false; + if (!is_shutdown) { + delete internal::ShutdownData::get(); + is_shutdown = true; + } +} + + +} // namespace protobuf +} // namespace google + +#include <google/protobuf/port_undef.inc> diff --git a/contrib/libs/protobuf_old/src/google/protobuf/message_lite.h b/contrib/libs/protobuf_old/src/google/protobuf/message_lite.h new file mode 100644 index 0000000000..eb5b156303 --- /dev/null +++ b/contrib/libs/protobuf_old/src/google/protobuf/message_lite.h @@ -0,0 +1,607 @@ +// 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. + +// Authors: wink@google.com (Wink Saville), +// kenton@google.com (Kenton Varda) +// Based on original Protocol Buffers design by +// Sanjay Ghemawat, Jeff Dean, and others. +// +// Defines MessageLite, the abstract interface implemented by all (lite +// and non-lite) protocol message objects. + +#ifndef GOOGLE_PROTOBUF_MESSAGE_LITE_H__ +#define GOOGLE_PROTOBUF_MESSAGE_LITE_H__ + +#if defined(_MSC_VER) +#define PROTOBUF_MUST_USE_RESULT +#else +#define PROTOBUF_MUST_USE_RESULT __attribute__((warn_unused_result)) +#endif + +#include <climits> +#include <string> + +#include <google/protobuf/stubs/common.h> +#include <google/protobuf/stubs/logging.h> +#include <google/protobuf/io/coded_stream.h> +#include <google/protobuf/arena.h> +#include <google/protobuf/explicitly_constructed.h> +#include <google/protobuf/metadata_lite.h> +#include <google/protobuf/stubs/once.h> +#include <google/protobuf/port.h> +#include <google/protobuf/stubs/strutil.h> + + +// clang-format off +#include <google/protobuf/port_def.inc> +// clang-format on + +#ifdef SWIG +#error "You cannot SWIG proto headers" +#endif + +namespace google { +namespace protobuf { + +template <typename T> +class RepeatedPtrField; + +class FastReflectionMessageMutator; +class FastReflectionStringSetter; +class Reflection; + +namespace io { + +class CodedInputStream; +class CodedOutputStream; +class ZeroCopyInputStream; +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 { + explicit ConstantInitialized() = default; +}; + +// See parse_context.h for explanation +class ParseContext; + +class ExtensionSet; +class LazyField; +class RepeatedPtrFieldBase; +class TcParser; +class WireFormatLite; +class WeakFieldMap; + +template <typename Type> +class GenericTypeHandler; // defined in repeated_field.h + +// We compute sizes as size_t but cache them as int. This function converts a +// computed size to a cached size. Since we don't proceed with serialization +// if the total size was > INT_MAX, it is not important what this function +// returns for inputs > INT_MAX. However this case should not error or +// GOOGLE_CHECK-fail, because the full size_t resolution is still returned from +// ByteSizeLong() and checked against INT_MAX; we can catch the overflow +// there. +inline int ToCachedSize(size_t size) { return static_cast<int>(size); } + +// We mainly calculate sizes in terms of size_t, but some functions that +// compute sizes return "int". These int sizes are expected to always be +// positive. This function is more efficient than casting an int to size_t +// directly on 64-bit platforms because it avoids making the compiler emit a +// sign extending instruction, which we don't want and don't want to pay for. +inline size_t FromIntSize(int size) { + // Convert to unsigned before widening so sign extension is not necessary. + return static_cast<unsigned int>(size); +} + +// For cases where a legacy function returns an integer size. We GOOGLE_DCHECK() +// that the conversion will fit within an integer; if this is false then we +// are losing information. +inline int ToIntSize(size_t size) { + GOOGLE_DCHECK_LE(size, static_cast<size_t>(INT_MAX)); + return static_cast<int>(size); +} + +// Default empty string object. Don't use this directly. Instead, call +// GetEmptyString() to get the reference. +PROTOBUF_EXPORT extern ExplicitlyConstructed<TProtoStringType> + fixed_address_empty_string; + + +PROTOBUF_EXPORT constexpr const TProtoStringType& GetEmptyStringAlreadyInited() { + return fixed_address_empty_string.get(); +} + +PROTOBUF_EXPORT size_t StringSpaceUsedExcludingSelfLong(const TProtoStringType& str); + +} // namespace internal + +// Interface to light weight protocol messages. +// +// This interface is implemented by all protocol message objects. Non-lite +// messages additionally implement the Message interface, which is a +// subclass of MessageLite. Use MessageLite instead when you only need +// the subset of features which it supports -- namely, nothing that uses +// descriptors or reflection. You can instruct the protocol compiler +// to generate classes which implement only MessageLite, not the full +// Message interface, by adding the following line to the .proto file: +// +// option optimize_for = LITE_RUNTIME; +// +// This is particularly useful on resource-constrained systems where +// the full protocol buffers runtime library is too big. +// +// Note that on non-constrained systems (e.g. servers) when you need +// to link in lots of protocol definitions, a better way to reduce +// total code footprint is to use optimize_for = CODE_SIZE. This +// will make the generated code smaller while still supporting all the +// same features (at the expense of speed). optimize_for = LITE_RUNTIME +// is best when you only have a small number of message types linked +// into your binary, in which case the size of the protocol buffers +// runtime itself is the biggest problem. +// +// Users must not derive from this class. Only the protocol compiler and +// the internal library are allowed to create subclasses. +class PROTOBUF_EXPORT MessageLite { + public: + constexpr MessageLite() {} + virtual ~MessageLite() = default; + + // Basic Operations ------------------------------------------------ + + // Get the name of this message type, e.g. "foo.bar.BazProto". + virtual TProtoStringType GetTypeName() const = 0; + + // Construct a new instance of the same type. Ownership is passed to the + // caller. + MessageLite* New() const { return New(nullptr); } + + // Construct a new instance on the arena. Ownership is passed to the caller + // if arena is a nullptr. + virtual MessageLite* New(Arena* arena) const = 0; + + // Same as GetOwningArena. + Arena* GetArena() const { return GetOwningArena(); } + + // Clear all fields of the message and set them to their default values. + // Clear() avoids freeing memory, assuming that any memory allocated + // to hold parts of the message will be needed again to hold the next + // message. If you actually want to free the memory used by a Message, + // you must delete it. + virtual void Clear() = 0; + + // Quickly check if all required fields have values set. + virtual bool IsInitialized() const = 0; + + // This is not implemented for Lite messages -- it just returns "(cannot + // determine missing fields for lite message)". However, it is implemented + // for full messages. See message.h. + virtual TProtoStringType InitializationErrorString() const; + + // If |other| is the exact same class as this, calls MergeFrom(). Otherwise, + // results are undefined (probably crash). + virtual void CheckTypeAndMergeFrom(const MessageLite& other) = 0; + + // These methods return a human-readable summary of the message. Note that + // since the MessageLite interface does not support reflection, there is very + // little information that these methods can provide. They are shadowed by + // methods of the same name on the Message interface which provide much more + // information. The methods here are intended primarily to facilitate code + // reuse for logic that needs to interoperate with both full and lite protos. + // + // The format of the returned string is subject to change, so please do not + // assume it will remain stable over time. + TProtoStringType DebugString() const; + TProtoStringType ShortDebugString() const { return DebugString(); } + // MessageLite::DebugString is already Utf8 Safe. This is to add compatibility + // with Message. + TProtoStringType Utf8DebugString() const { return DebugString(); } + + // Parsing --------------------------------------------------------- + // Methods for parsing in protocol buffer format. Most of these are + // just simple wrappers around MergeFromCodedStream(). Clear() will be + // called before merging the input. + + // Fill the message with a protocol buffer parsed from the given input + // stream. Returns false on a read error or if the input is in the wrong + // format. A successful return does not indicate the entire input is + // consumed, ensure you call ConsumedEntireMessage() to check that if + // applicable. + PROTOBUF_ATTRIBUTE_REINITIALIZES PROTOBUF_MUST_USE_RESULT bool ParseFromCodedStream( + io::CodedInputStream* input); + // Like ParseFromCodedStream(), but accepts messages that are missing + // required fields. + PROTOBUF_ATTRIBUTE_REINITIALIZES PROTOBUF_MUST_USE_RESULT bool ParsePartialFromCodedStream( + io::CodedInputStream* input); + // Read a protocol buffer from the given zero-copy input stream. If + // successful, the entire input will be consumed. + PROTOBUF_ATTRIBUTE_REINITIALIZES PROTOBUF_MUST_USE_RESULT bool ParseFromZeroCopyStream( + io::ZeroCopyInputStream* input); + // Like ParseFromZeroCopyStream(), but accepts messages that are missing + // required fields. + PROTOBUF_ATTRIBUTE_REINITIALIZES PROTOBUF_MUST_USE_RESULT bool ParsePartialFromZeroCopyStream( + io::ZeroCopyInputStream* input); + // Parse a protocol buffer from a file descriptor. If successful, the entire + // input will be consumed. + PROTOBUF_ATTRIBUTE_REINITIALIZES PROTOBUF_MUST_USE_RESULT bool ParseFromFileDescriptor( + int file_descriptor); + // Like ParseFromFileDescriptor(), but accepts messages that are missing + // required fields. + PROTOBUF_ATTRIBUTE_REINITIALIZES PROTOBUF_MUST_USE_RESULT bool ParsePartialFromFileDescriptor( + int file_descriptor); + // Parse a protocol buffer from a C++ istream. If successful, the entire + // input will be consumed. + PROTOBUF_ATTRIBUTE_REINITIALIZES PROTOBUF_MUST_USE_RESULT bool ParseFromIstream(std::istream* input); + // Like ParseFromIstream(), but accepts messages that are missing + // required fields. + PROTOBUF_ATTRIBUTE_REINITIALIZES PROTOBUF_MUST_USE_RESULT bool ParsePartialFromIstream( + std::istream* input); + // Read a protocol buffer from the given zero-copy input stream, expecting + // the message to be exactly "size" bytes long. If successful, exactly + // this many bytes will have been consumed from the input. + PROTOBUF_MUST_USE_RESULT bool MergePartialFromBoundedZeroCopyStream(io::ZeroCopyInputStream* input, + int size); + // Like ParseFromBoundedZeroCopyStream(), but accepts messages that are + // missing required fields. + PROTOBUF_MUST_USE_RESULT bool MergeFromBoundedZeroCopyStream(io::ZeroCopyInputStream* input, int size); + PROTOBUF_ATTRIBUTE_REINITIALIZES PROTOBUF_MUST_USE_RESULT bool ParseFromBoundedZeroCopyStream( + io::ZeroCopyInputStream* input, int size); + // Like ParseFromBoundedZeroCopyStream(), but accepts messages that are + // missing required fields. + PROTOBUF_ATTRIBUTE_REINITIALIZES PROTOBUF_MUST_USE_RESULT bool ParsePartialFromBoundedZeroCopyStream( + io::ZeroCopyInputStream* input, int size); + // Parses a protocol buffer contained in a string. Returns true on success. + // This function takes a string in the (non-human-readable) binary wire + // format, matching the encoding output by MessageLite::SerializeToString(). + // If you'd like to convert a human-readable string into a protocol buffer + // object, see google::protobuf::TextFormat::ParseFromString(). + PROTOBUF_ATTRIBUTE_REINITIALIZES PROTOBUF_MUST_USE_RESULT bool ParseFromString(ConstStringParam data); + // Like ParseFromString(), but accepts messages that are missing + // required fields. + PROTOBUF_ATTRIBUTE_REINITIALIZES PROTOBUF_MUST_USE_RESULT bool ParsePartialFromString( + ConstStringParam data); + // Parse a protocol buffer contained in an array of bytes. + PROTOBUF_ATTRIBUTE_REINITIALIZES PROTOBUF_MUST_USE_RESULT bool ParseFromArray(const void* data, + int size); + // Like ParseFromArray(), but accepts messages that are missing + // required fields. + PROTOBUF_ATTRIBUTE_REINITIALIZES PROTOBUF_MUST_USE_RESULT bool ParsePartialFromArray(const void* data, + int size); + + + // Reads a protocol buffer from the stream and merges it into this + // Message. Singular fields read from the what is + // already in the Message and repeated fields are appended to those + // already present. + // + // It is the responsibility of the caller to call input->LastTagWas() + // (for groups) or input->ConsumedEntireMessage() (for non-groups) after + // this returns to verify that the message's end was delimited correctly. + // + // ParseFromCodedStream() is implemented as Clear() followed by + // MergeFromCodedStream(). + PROTOBUF_MUST_USE_RESULT bool MergeFromCodedStream(io::CodedInputStream* input); + + // Like MergeFromCodedStream(), but succeeds even if required fields are + // missing in the input. + // + // MergeFromCodedStream() is just implemented as MergePartialFromCodedStream() + // followed by IsInitialized(). + PROTOBUF_MUST_USE_RESULT bool MergePartialFromCodedStream(io::CodedInputStream* input); + + // Merge a protocol buffer contained in a string. + PROTOBUF_MUST_USE_RESULT bool MergeFromString(ConstStringParam data); + + + // Serialization --------------------------------------------------- + // Methods for serializing in protocol buffer format. Most of these + // are just simple wrappers around ByteSize() and SerializeWithCachedSizes(). + + // Write a protocol buffer of this message to the given output. Returns + // false on a write error. If the message is missing required fields, + // this may GOOGLE_CHECK-fail. + PROTOBUF_MUST_USE_RESULT bool SerializeToCodedStream(io::CodedOutputStream* output) const; + // Like SerializeToCodedStream(), but allows missing required fields. + PROTOBUF_MUST_USE_RESULT bool SerializePartialToCodedStream(io::CodedOutputStream* output) const; + // Write the message to the given zero-copy output stream. All required + // fields must be set. + PROTOBUF_MUST_USE_RESULT bool SerializeToZeroCopyStream(io::ZeroCopyOutputStream* output) const; + // Like SerializeToZeroCopyStream(), but allows missing required fields. + PROTOBUF_MUST_USE_RESULT bool SerializePartialToZeroCopyStream(io::ZeroCopyOutputStream* output) const; + // Serialize the message and store it in the given string. All required + // fields must be set. + PROTOBUF_MUST_USE_RESULT bool SerializeToString(TProtoStringType* output) const; + // Like SerializeToString(), but allows missing required fields. + PROTOBUF_MUST_USE_RESULT bool SerializePartialToString(TProtoStringType* output) const; + // Serialize the message and store it in the given byte array. All required + // fields must be set. + PROTOBUF_MUST_USE_RESULT bool SerializeToArray(void* data, int size) const; + // Like SerializeToArray(), but allows missing required fields. + PROTOBUF_MUST_USE_RESULT bool SerializePartialToArray(void* data, int size) const; + + // Make a string encoding the message. Is equivalent to calling + // SerializeToString() on a string and using that. Returns the empty + // string if SerializeToString() would have returned an error. + // Note: If you intend to generate many such strings, you may + // reduce heap fragmentation by instead re-using the same string + // object with calls to SerializeToString(). + TProtoStringType SerializeAsString() const; + // Like SerializeAsString(), but allows missing required fields. + TProtoStringType SerializePartialAsString() const; + + // Serialize the message and write it to the given file descriptor. All + // required fields must be set. + PROTOBUF_MUST_USE_RESULT bool SerializeToFileDescriptor(int file_descriptor) const; + // Like SerializeToFileDescriptor(), but allows missing required fields. + PROTOBUF_MUST_USE_RESULT bool SerializePartialToFileDescriptor(int file_descriptor) const; + // Serialize the message and write it to the given C++ ostream. All + // required fields must be set. + PROTOBUF_MUST_USE_RESULT bool SerializeToOstream(std::ostream* output) const; + // Like SerializeToOstream(), but allows missing required fields. + PROTOBUF_MUST_USE_RESULT bool SerializePartialToOstream(std::ostream* output) const; + + // Like SerializeToString(), but appends to the data to the string's + // existing contents. All required fields must be set. + PROTOBUF_MUST_USE_RESULT bool AppendToString(TProtoStringType* output) const; + // Like AppendToString(), but allows missing required fields. + PROTOBUF_MUST_USE_RESULT bool AppendPartialToString(TProtoStringType* output) const; + + + // Computes the serialized size of the message. This recursively calls + // ByteSizeLong() on all embedded messages. + // + // ByteSizeLong() is generally linear in the number of fields defined for the + // proto. + virtual size_t ByteSizeLong() const = 0; + + // Legacy ByteSize() API. + PROTOBUF_DEPRECATED_MSG("Please use ByteSizeLong() instead") + int ByteSize() const { return internal::ToIntSize(ByteSizeLong()); } + + // Serializes the message without recomputing the size. The message must not + // have changed since the last call to ByteSize(), and the value returned by + // ByteSize must be non-negative. Otherwise the results are undefined. + void SerializeWithCachedSizes(io::CodedOutputStream* output) const { + output->SetCur(_InternalSerialize(output->Cur(), output->EpsCopy())); + } + + // Functions below here are not part of the public interface. It isn't + // enforced, but they should be treated as private, and will be private + // at some future time. Unfortunately the implementation of the "friend" + // keyword in GCC is broken at the moment, but we expect it will be fixed. + + // Like SerializeWithCachedSizes, but writes directly to *target, returning + // a pointer to the byte immediately after the last byte written. "target" + // must point at a byte array of at least ByteSize() bytes. Whether to use + // deterministic serialization, e.g., maps in sorted order, is determined by + // CodedOutputStream::IsDefaultSerializationDeterministic(). + uint8_t* SerializeWithCachedSizesToArray(uint8_t* target) const; + + // Returns the result of the last call to ByteSize(). An embedded message's + // size is needed both to serialize it (because embedded messages are + // length-delimited) and to compute the outer message's size. Caching + // the size avoids computing it multiple times. + // + // ByteSize() does not automatically use the cached size when available + // because this would require invalidating it every time the message was + // modified, which would be too hard and expensive. (E.g. if a deeply-nested + // sub-message is changed, all of its parents' cached sizes would need to be + // invalidated, which is too much work for an otherwise inlined setter + // method.) + virtual int GetCachedSize() const = 0; + + virtual const char* _InternalParse(const char* /*ptr*/, + internal::ParseContext* /*ctx*/) { + return nullptr; + } + + protected: + template <typename T> + static T* CreateMaybeMessage(Arena* arena) { + return Arena::CreateMaybeMessage<T>(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_.owning_arena(); } + + // Returns the arena, used for allocating internal objects(e.g., child + // messages, etc), or owning incoming objects (e.g., set allocated). + Arena* GetArenaForAllocation() const { return _internal_metadata_.arena(); } + + internal::InternalMetadata _internal_metadata_; + + public: + enum ParseFlags { + kMerge = 0, + kParse = 1, + kMergePartial = 2, + kParsePartial = 3, + kMergeWithAliasing = 4, + kParseWithAliasing = 5, + kMergePartialWithAliasing = 6, + kParsePartialWithAliasing = 7 + }; + + template <ParseFlags flags, typename T> + PROTOBUF_MUST_USE_RESULT bool ParseFrom(const T& input); + + // Fast path when conditions match (ie. non-deterministic) + // uint8_t* _InternalSerialize(uint8_t* ptr) const; + virtual uint8_t* _InternalSerialize( + uint8_t* ptr, io::EpsCopyOutputStream* stream) const = 0; + + // Identical to IsInitialized() except that it logs an error message. + bool IsInitializedWithErrors() const { + if (IsInitialized()) return true; + LogInitializationErrorMessage(); + return false; + } + + #if PROTOBUF_USE_EXCEPTIONS && defined(__cpp_lib_string_view) + PROTOBUF_ATTRIBUTE_REINITIALIZES void ParseFromStringOrThrow(std::string_view s) noexcept(false); + #endif + + #if PROTOBUF_USE_EXCEPTIONS + TProtoStringType SerializeAsStringOrThrow() const noexcept(false); + #endif + + private: + // TODO(gerbens) make this a pure abstract function + virtual const void* InternalGetTable() const { return nullptr; } + + friend class FastReflectionMessageMutator; + friend class FastReflectionStringSetter; + friend class Message; + friend class Reflection; + friend class internal::ExtensionSet; + friend class internal::LazyField; + friend class internal::SwapFieldHelper; + friend class internal::TcParser; + friend class internal::WeakFieldMap; + friend class internal::WireFormatLite; + + template <typename Type> + friend class Arena::InternalHelper; + template <typename Type> + friend class internal::GenericTypeHandler; + + void LogInitializationErrorMessage() const; + + PROTOBUF_MUST_USE_RESULT bool MergeFromImpl(io::CodedInputStream* input, ParseFlags parse_flags); + + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(MessageLite); +}; + +namespace internal { + +template <bool alias> +PROTOBUF_MUST_USE_RESULT bool MergeFromImpl(StringPiece input, MessageLite* msg, + MessageLite::ParseFlags parse_flags); +extern template PROTOBUF_MUST_USE_RESULT bool MergeFromImpl<false>(StringPiece input, + MessageLite* msg, + MessageLite::ParseFlags parse_flags); +extern template PROTOBUF_MUST_USE_RESULT bool MergeFromImpl<true>(StringPiece input, + MessageLite* msg, + MessageLite::ParseFlags parse_flags); + +template <bool alias> +PROTOBUF_MUST_USE_RESULT bool MergeFromImpl(io::ZeroCopyInputStream* input, MessageLite* msg, + MessageLite::ParseFlags parse_flags); +extern template PROTOBUF_MUST_USE_RESULT bool MergeFromImpl<false>(io::ZeroCopyInputStream* input, + MessageLite* msg, + MessageLite::ParseFlags parse_flags); +extern template PROTOBUF_MUST_USE_RESULT bool MergeFromImpl<true>(io::ZeroCopyInputStream* input, + MessageLite* msg, + MessageLite::ParseFlags parse_flags); + +struct BoundedZCIS { + io::ZeroCopyInputStream* zcis; + int limit; +}; + +template <bool alias> +PROTOBUF_MUST_USE_RESULT bool MergeFromImpl(BoundedZCIS input, MessageLite* msg, + MessageLite::ParseFlags parse_flags); +extern template PROTOBUF_MUST_USE_RESULT bool MergeFromImpl<false>(BoundedZCIS input, MessageLite* msg, + MessageLite::ParseFlags parse_flags); +extern template PROTOBUF_MUST_USE_RESULT bool MergeFromImpl<true>(BoundedZCIS input, MessageLite* msg, + MessageLite::ParseFlags parse_flags); + +template <typename T> +struct SourceWrapper; + +template <bool alias, typename T> +PROTOBUF_MUST_USE_RESULT bool MergeFromImpl(const SourceWrapper<T>& input, MessageLite* msg, + MessageLite::ParseFlags parse_flags) { + return input.template MergeInto<alias>(msg, parse_flags); +} + +} // namespace internal + +template <MessageLite::ParseFlags flags, typename T> +bool MessageLite::ParseFrom(const T& input) { + if (flags & kParse) Clear(); + constexpr bool alias = (flags & kMergeWithAliasing) != 0; + return internal::MergeFromImpl<alias>(input, this, flags); +} + +// =================================================================== +// Shutdown support. + + +// Shut down the entire protocol buffers library, deleting all static-duration +// objects allocated by the library or by generated .pb.cc files. +// +// There are two reasons you might want to call this: +// * You use a draconian definition of "memory leak" in which you expect +// every single malloc() to have a corresponding free(), even for objects +// which live until program exit. +// * You are writing a dynamically-loaded library which needs to clean up +// after itself when the library is unloaded. +// +// It is safe to call this multiple times. However, it is not safe to use +// any other part of the protocol buffers library after +// ShutdownProtobufLibrary() has been called. Furthermore this call is not +// thread safe, user needs to synchronize multiple calls. +PROTOBUF_EXPORT void ShutdownProtobufLibrary(); + +namespace internal { + +// Register a function to be called when ShutdownProtocolBuffers() is called. +PROTOBUF_EXPORT void OnShutdown(void (*func)()); +// Run an arbitrary function on an arg +PROTOBUF_EXPORT void OnShutdownRun(void (*f)(const void*), const void* arg); + +template <typename T> +T* OnShutdownDelete(T* p) { + OnShutdownRun([](const void* pp) { delete static_cast<const T*>(pp); }, p); + return p; +} + +} // namespace internal +} // namespace protobuf +} // namespace google + +#include <google/protobuf/port_undef.inc> + +#endif // GOOGLE_PROTOBUF_MESSAGE_LITE_H__ diff --git a/contrib/libs/protobuf_old/src/google/protobuf/messagext.cc b/contrib/libs/protobuf_old/src/google/protobuf/messagext.cc new file mode 100644 index 0000000000..1923205598 --- /dev/null +++ b/contrib/libs/protobuf_old/src/google/protobuf/messagext.cc @@ -0,0 +1,226 @@ +#include <google/protobuf/io/coded_stream.h> +#include <google/protobuf/io/zero_copy_stream_impl.h> +#include <google/protobuf/messagext.h> +#include <google/protobuf/text_format.h> + +#include <util/ysaveload.h> +#include <util/generic/yexception.h> +#include <util/stream/length.h> + +namespace { + const int MaxSizeBytes = 1 << 27; // 128 MB limits the size of a protobuf message processed by TProtoSerializer +} + +namespace google::protobuf { + +//defined in message_lite.cc +TProtoStringType InitializationErrorMessage(const char* action, const MessageLite& message); + +} // namespace google::protobuf + +namespace google::protobuf::internal { + + IOutputStream& operator <<(IOutputStream& output, const internal::TAsBinary& wrappedMessage) { + bool success = wrappedMessage.Message_.SerializeToArcadiaStream(&output); + if (Y_UNLIKELY(!success)) { + ythrow yexception() << "Cannot serialize a protobuf with AsBinary() (required fields missing?)"; + } + return output; + } + + + IOutputStream& operator <<(IOutputStream& output, const internal::TAsStreamSeq& wrappedMessage) { + ::Save(&output, wrappedMessage.Message_); + return output; + } + +} // namespace google::protobuf::internal + +namespace google::protobuf::io { + +bool ParseFromCodedStreamSeq(Message* msg, io::CodedInputStream* input) { + msg->Clear(); + ui32 size; + if (!input->ReadVarint32(&size)) { + return false; + } + + io::CodedInputStream::Limit limitState = input->PushLimit(size); + bool res = msg->ParseFromCodedStream(input); + input->PopLimit(limitState); + return res; +} + +bool ParseFromZeroCopyStreamSeq(Message* msg, io::ZeroCopyInputStream* input) { + io::CodedInputStream decoder(input); + return ParseFromCodedStreamSeq(msg, &decoder); +} + +bool SerializePartialToCodedStreamSeq(const Message* msg, io::CodedOutputStream* output) { + uint32 size = msg->ByteSize(); // Force size to be cached. + output->WriteVarint32(size); + msg->SerializeWithCachedSizes(output); + return !output->HadError(); +} + +bool SerializeToCodedStreamSeq(const Message* msg, io::CodedOutputStream* output) { + GOOGLE_DCHECK(msg->IsInitialized()) << InitializationErrorMessage("serialize", *msg); + return SerializePartialToCodedStreamSeq(msg, output); +} + +bool SerializeToZeroCopyStreamSeq(const Message* msg, io::ZeroCopyOutputStream* output) { + io::CodedOutputStream encoder(output); + return SerializeToCodedStreamSeq(msg, &encoder); +} + + +int TInputStreamProxy::Read(void* buffer, int size) { + try { + return (int)mSlave->Read(buffer, (size_t)size); + } catch (const yexception& e) { + GOOGLE_LOG(ERROR) << e.what(); + } catch (...) { + GOOGLE_LOG(ERROR) << "unknown exception caught"; + } + TErrorState::SetError(); + return -1; +} + + +bool TOutputStreamProxy::Write(const void* buffer, int size) { + try { + mSlave->Write(buffer, (size_t)size); + return true; + } catch (const yexception& e) { + GOOGLE_LOG(ERROR) << e.what(); + } catch (...) { + GOOGLE_LOG(ERROR) << "unknown exception caught"; + } + TErrorState::SetError(); + return false; +} + + +void TProtoSerializer::Save(IOutputStream* out, const Message& msg) { + int size = msg.ByteSize(); + if (size > MaxSizeBytes) { + ythrow yexception() << "Message size " << size << " exceeds " << MaxSizeBytes; + } + + TCopyingOutputStreamAdaptor adaptor(out); + io::CodedOutputStream encoder(&adaptor); + if (!SerializeToCodedStreamSeq(&msg, &encoder)) + ythrow yexception() << "Cannot write protobuf::Message to output stream"; +} + +// Reading varint32 directly from IInputStream (might be slow if input requires buffering). +// Copy-pasted with small modifications from protobuf/io/coded_stream (ReadVarint32FromArray) + +// Returns true if succeeded, false if stream has ended, throws exception if data is corrupted +static bool ReadVarint32(IInputStream* input, ui32& size) { + size_t res; + ui8 b; + + /* if we can't read anything from stream - it is exhausted */ + if (input->Read(&b, 1) == 0) + return false; + res = (b & 0x7F) ; if (!(b & 0x80)) goto done; + ::Load(input, b); res |= (b & 0x7F) << 7; if (!(b & 0x80)) goto done; + ::Load(input, b); res |= (b & 0x7F) << 14; if (!(b & 0x80)) goto done; + ::Load(input, b); res |= (b & 0x7F) << 21; if (!(b & 0x80)) goto done; + ::Load(input, b); res |= b << 28; if (!(b & 0x80)) goto done; + + // If the input is larger than 32 bits, we still need to read it all + // and discard the high-order bits. + for (int i = 0; i < 5; i++) { + ::Load(input, b); if (!(b & 0x80)) goto done; + } + ythrow yexception() << "We have overrun the maximum size of a varint (10 bytes). Assume the data is corrupt."; + +done: + size = res; + return true; +} + +class TTempBufHelper { +public: + TTempBufHelper(size_t size) { + if (size <= SmallBufSize) { + Buffer = SmallBuf; + } else { + LargeBuf.Reset(new TTempBuf(size)); + Buffer = reinterpret_cast<ui8*>(LargeBuf->Data()); + } + } + + ui8* Data() { + return Buffer; + } + +private: + static const size_t SmallBufSize = 1024; + ui8 SmallBuf[SmallBufSize]; + + THolder<TTempBuf> LargeBuf; + + ui8* Buffer; +}; + +void TProtoSerializer::Load(IInputStream* input, Message& msg) { + msg.Clear(); + MergeFrom(input, msg); +} + +void TProtoSerializer::MergeFrom(IInputStream* input, Message& msg) { + ui32 size; + if (!ReadVarint32(input, size)) + ythrow yexception() << "Stream is exhausted"; + + TTempBufHelper buf(size); + ::LoadPodArray(input, buf.Data(), size); + CodedInputStream decoder(buf.Data(), size); + decoder.SetTotalBytesLimit(MaxSizeBytes); + if (!msg.MergeFromCodedStream(&decoder)) + ythrow yexception() << "Cannot read protobuf::Message (" << msg.GetTypeName() << ") from input stream"; +} + +TProtoReader::TProtoReader(IInputStream* input, const size_t bufferSize) + : IStream(input) + , Buffer(bufferSize) +{ +} + + +bool TProtoReader::Load(Message& msg) { + ui32 size; + if (!ReadVarint32(IStream, size)) + return false; + + Buffer.Reserve(size); + + ::LoadPodArray(IStream, Buffer.Data(), size); + CodedInputStream decoder((const ui8*)Buffer.Data(), size); + if (!msg.ParseFromCodedStream(&decoder)) + ythrow yexception() << "Cannot read protobuf::Message from input stream"; + + return true; +} + +} // namespace google::protobuf::io + +TProtoStringType ShortUtf8DebugString(const google::protobuf::Message& msg) { + google::protobuf::TextFormat::Printer printer; + printer.SetSingleLineMode(true); + printer.SetUseUtf8StringEscaping(true); + + TProtoStringType string; + printer.PrintToString(msg, &string); + + // Copied from text_format.h + // Single line mode currently might have an extra space at the end. + if (string.size() > 0 && string[string.size() - 1] == ' ') { + string.resize(string.size() - 1); + } + + return string; +} diff --git a/contrib/libs/protobuf_old/src/google/protobuf/messagext.h b/contrib/libs/protobuf_old/src/google/protobuf/messagext.h new file mode 100644 index 0000000000..9176cee1e8 --- /dev/null +++ b/contrib/libs/protobuf_old/src/google/protobuf/messagext.h @@ -0,0 +1,166 @@ +#pragma once + +#include <google/protobuf/stubs/port.h> +#include <google/protobuf/io/coded_stream.h> +#include <util/stream/output.h> +#include <util/generic/buffer.h> + +#include <google/protobuf/io/zero_copy_stream_impl.h> + +/// this file is Yandex extensions to protobuf + +namespace google { +namespace protobuf { + +class Message; + +namespace internal { + +struct TAsBinary { + const Message& Message_; + friend IOutputStream& operator <<(IOutputStream& output, const TAsBinary& wrappedMessage); +}; + +struct TAsStreamSeq { + const Message& Message_; + friend IOutputStream& operator <<(IOutputStream& output, const TAsStreamSeq& wrappedMessage); +}; + +} // namespace internal + +namespace io { + +/// Parse*Seq methods read message size from stream to find a message boundary + +/// there is not parse from IInputStream, because it is not push-backable + +bool ParseFromCodedStreamSeq(Message* msg, io::CodedInputStream* input); +bool ParseFromZeroCopyStreamSeq(Message* msg, io::ZeroCopyInputStream* input); + +/// Serialize*Seq methods write message size as varint before writing a message +/// there is no serialize to IOutputStream, because it is not push-backable + +bool SerializePartialToCodedStreamSeq(const Message* msg, io::CodedOutputStream* output); +bool SerializeToCodedStreamSeq(const Message* msg, io::CodedOutputStream* output); +bool SerializeToZeroCopyStreamSeq(const Message* msg, io::ZeroCopyOutputStream* output); + +class TErrorState { +public: + TErrorState() + : HasError_(false) + { + } + bool HasError() const { + return HasError_; + } + void SetError() { + HasError_ = true; + } +private: + bool HasError_; +}; + +class TInputStreamProxy: public io::CopyingInputStream, public TErrorState { + public: + inline TInputStreamProxy(IInputStream* slave) + : mSlave(slave) + { + } + + virtual int Read(void* buffer, int size); + + private: + IInputStream* mSlave; +}; + +class TOutputStreamProxy: public io::CopyingOutputStream, public TErrorState { + public: + inline TOutputStreamProxy(IOutputStream* slave) + : mSlave(slave) + { + } + + virtual bool Write(const void* buffer, int size); + + private: + IOutputStream* mSlave; +}; + + +class TCopyingInputStreamAdaptor: public TInputStreamProxy, public CopyingInputStreamAdaptor { +public: + TCopyingInputStreamAdaptor(IInputStream* inputStream) + : TInputStreamProxy(inputStream) + , CopyingInputStreamAdaptor(this) + { } +}; + +class TCopyingOutputStreamAdaptor: public TOutputStreamProxy, public CopyingOutputStreamAdaptor { +public: + TCopyingOutputStreamAdaptor(IOutputStream* outputStream) + : TOutputStreamProxy(outputStream) + , CopyingOutputStreamAdaptor(this) + { } +}; + + +class TProtoSerializer { +public: + static void Save(IOutputStream* output, const Message& msg); + static void Load(IInputStream* input, Message& msg); + static void MergeFrom(IInputStream* input, Message& msg); + + // similar interface for protobuf coded streams + static inline bool Save(CodedOutputStream* output, const Message& msg) { + return SerializeToCodedStreamSeq(&msg, output); + } + + static inline bool Load(CodedInputStream* input, Message& msg) { + return ParseFromCodedStreamSeq(&msg, input); + } +}; + + +/** + * Special separate simple reader of protobuf files from arcadic streams + * with static one time allocated buffer. + * + * Data can be prepared with TProtoSerializer::Save, format is the same. + * + */ +class TProtoReader { +public: + TProtoReader(IInputStream* input, const size_t bufferSize = DefaultBufferSize); + + /** + * Reads protobuf message + * + * @param msg binary compatible protobuf message + * @returns true if read is ok + * false if stream is exhausted + * yexception if input data is corrupted + */ + bool Load(Message& msg); + +private: + IInputStream* IStream; + TBuffer Buffer; + + static const size_t DefaultBufferSize = (1 << 16); +}; + +} // namespace io +} // namespace protobuf +} // namespace google + +// arcadia-style serialization +inline void Save(IOutputStream* output, const google::protobuf::Message& msg) { + google::protobuf::io::TProtoSerializer::Save(output, msg); +} + +inline void Load(IInputStream* input, google::protobuf::Message& msg) { + google::protobuf::io::TProtoSerializer::Load(input, msg); +} + +// A mix of ShortDebugString and Utf8DebugString +TProtoStringType ShortUtf8DebugString(const google::protobuf::Message& msg); diff --git a/contrib/libs/protobuf_old/src/google/protobuf/metadata_lite.h b/contrib/libs/protobuf_old/src/google/protobuf/metadata_lite.h new file mode 100644 index 0000000000..d180bcda91 --- /dev/null +++ b/contrib/libs/protobuf_old/src/google/protobuf/metadata_lite.h @@ -0,0 +1,270 @@ +// 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_METADATA_LITE_H__ +#define GOOGLE_PROTOBUF_METADATA_LITE_H__ + +#include <string> +#include <google/protobuf/stubs/common.h> +#include <google/protobuf/arena.h> +#include <google/protobuf/port.h> + +#include <google/protobuf/port_def.inc> + +#ifdef SWIG +#error "You cannot SWIG proto headers" +#endif + +namespace google { +namespace protobuf { +namespace internal { + +// This is the representation for messages that support arena allocation. It +// uses a tagged pointer to either store the owning Arena pointer, if there are +// no unknown fields, or a pointer to a block of memory with both the owning +// Arena pointer and the UnknownFieldSet, if there are unknown fields. Besides, +// it also uses the tag to distinguish whether the owning Arena pointer is also +// used by sub-structure allocation. This optimization allows for +// "zero-overhead" storage of the Arena pointer, relative to the above baseline +// implementation. +// +// The tagged pointer uses the least two significant bits to disambiguate cases. +// It uses bit 0 == 0 to indicate an arena pointer and bit 0 == 1 to indicate a +// UFS+Arena-container pointer. Besides it uses bit 1 == 0 to indicate arena +// allocation and bit 1 == 1 to indicate heap allocation. +class InternalMetadata { + public: + 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() { + // Note that Delete<> should be called not more than once. + if (have_unknown_fields()) { + DeleteOutOfLineHelper<T>(); + } + } + + 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; + } else { + return PtrValue<Arena>(); + } + } + + PROTOBUF_NDEBUG_INLINE bool have_unknown_fields() const { + return HasUnknownFieldsTag(); + } + + PROTOBUF_NDEBUG_INLINE void* raw_arena_ptr() const { + return reinterpret_cast<void*>(ptr_); + } + + template <typename T> + PROTOBUF_NDEBUG_INLINE const T& unknown_fields( + const T& (*default_instance)()) const { + if (PROTOBUF_PREDICT_FALSE(have_unknown_fields())) { + return PtrValue<Container<T>>()->unknown_fields; + } else { + return default_instance(); + } + } + + template <typename T> + PROTOBUF_NDEBUG_INLINE T* mutable_unknown_fields() { + if (PROTOBUF_PREDICT_TRUE(have_unknown_fields())) { + return &PtrValue<Container<T>>()->unknown_fields; + } else { + return mutable_unknown_fields_slow<T>(); + } + } + + template <typename T> + PROTOBUF_NDEBUG_INLINE void Swap(InternalMetadata* other) { + // Semantics here are that we swap only the unknown fields, not the arena + // pointer. We cannot simply swap ptr_ with other->ptr_ because we need to + // maintain our own arena ptr. Also, our ptr_ and other's ptr_ may be in + // different states (direct arena pointer vs. container with UFS) so we + // cannot simply swap ptr_ and then restore the arena pointers. We reuse + // UFS's swap implementation instead. + if (have_unknown_fields() || other->have_unknown_fields()) { + DoSwap<T>(other->mutable_unknown_fields<T>()); + } + } + + PROTOBUF_NDEBUG_INLINE void InternalSwap(InternalMetadata* other) { + std::swap(ptr_, other->ptr_); + } + + template <typename T> + PROTOBUF_NDEBUG_INLINE void MergeFrom(const InternalMetadata& other) { + if (other.have_unknown_fields()) { + DoMergeFrom<T>(other.unknown_fields<T>(nullptr)); + } + } + + template <typename T> + PROTOBUF_NDEBUG_INLINE void Clear() { + if (have_unknown_fields()) { + DoClear<T>(); + } + } + + private: + intptr_t ptr_; + + // Tagged pointer implementation. + 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_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*>(ptr_ & kPtrValueMask); + } + + // If ptr_'s tag is kTagContainer, it points to an instance of this struct. + struct ContainerBase { + Arena* arena; + }; + + template <typename T> + struct Container : public ContainerBase { + T unknown_fields; + }; + + template <typename T> + PROTOBUF_NOINLINE void DeleteOutOfLineHelper() { + if (arena() == nullptr) { + delete PtrValue<Container<T>>(); + } + } + + template <typename T> + 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_ = reinterpret_cast<intptr_t>(container); + ptr_ |= kUnknownFieldsTagMask | message_owned_arena_tag; + container->arena = my_arena; + return &(container->unknown_fields); + } + + // Templated functions. + + template <typename T> + PROTOBUF_NOINLINE void DoClear() { + mutable_unknown_fields<T>()->Clear(); + } + + template <typename T> + PROTOBUF_NOINLINE void DoMergeFrom(const T& other) { + mutable_unknown_fields<T>()->MergeFrom(other); + } + + template <typename T> + PROTOBUF_NOINLINE void DoSwap(T* other) { + mutable_unknown_fields<T>()->Swap(other); + } +}; + +// String Template specializations. + +template <> +PROTOBUF_EXPORT void InternalMetadata::DoClear<TProtoStringType>(); +template <> +PROTOBUF_EXPORT void InternalMetadata::DoMergeFrom<TProtoStringType>( + const TProtoStringType& other); +template <> +PROTOBUF_EXPORT void InternalMetadata::DoSwap<TProtoStringType>(TProtoStringType* other); + +// This helper RAII class is needed to efficiently parse unknown fields. We +// should only call mutable_unknown_fields if there are actual unknown fields. +// The obvious thing to just use a stack string and swap it at the end of +// the parse won't work, because the destructor of StringOutputStream needs to +// be called before we can modify the string (it check-fails). Using +// LiteUnknownFieldSetter setter(&_internal_metadata_); +// StringOutputStream stream(setter.buffer()); +// guarantees that the string is only swapped after stream is destroyed. +class PROTOBUF_EXPORT LiteUnknownFieldSetter { + public: + explicit LiteUnknownFieldSetter(InternalMetadata* metadata) + : metadata_(metadata) { + if (metadata->have_unknown_fields()) { + buffer_.swap(*metadata->mutable_unknown_fields<TProtoStringType>()); + } + } + ~LiteUnknownFieldSetter() { + if (!buffer_.empty()) + metadata_->mutable_unknown_fields<TProtoStringType>()->swap(buffer_); + } + TProtoStringType* buffer() { return &buffer_; } + + private: + InternalMetadata* metadata_; + TProtoStringType buffer_; +}; + +} // namespace internal +} // namespace protobuf +} // namespace google + +#include <google/protobuf/port_undef.inc> + +#endif // GOOGLE_PROTOBUF_METADATA_LITE_H__ diff --git a/contrib/libs/protobuf_old/src/google/protobuf/parse_context.cc b/contrib/libs/protobuf_old/src/google/protobuf/parse_context.cc new file mode 100644 index 0000000000..a1995b6c1e --- /dev/null +++ b/contrib/libs/protobuf_old/src/google/protobuf/parse_context.cc @@ -0,0 +1,559 @@ +// 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 <google/protobuf/parse_context.h> + +#include <google/protobuf/stubs/stringprintf.h> +#include <google/protobuf/io/coded_stream.h> +#include <google/protobuf/io/zero_copy_stream.h> +#include <google/protobuf/arenastring.h> +#include <google/protobuf/message_lite.h> +#include <google/protobuf/repeated_field.h> +#include <google/protobuf/wire_format_lite.h> +#include <google/protobuf/stubs/strutil.h> + +#include <google/protobuf/port_def.inc> + +namespace google { +namespace protobuf { +namespace internal { + +namespace { + +// Only call if at start of tag. +bool ParseEndsInSlopRegion(const char* begin, int overrun, int depth) { + constexpr int kSlopBytes = EpsCopyInputStream::kSlopBytes; + GOOGLE_DCHECK(overrun >= 0); + GOOGLE_DCHECK(overrun <= kSlopBytes); + auto ptr = begin + overrun; + auto end = begin + kSlopBytes; + while (ptr < end) { + arc_ui32 tag; + ptr = ReadTag(ptr, &tag); + if (ptr == nullptr || ptr > end) return false; + // ending on 0 tag is allowed and is the major reason for the necessity of + // this function. + if (tag == 0) return true; + switch (tag & 7) { + case 0: { // Varint + arc_ui64 val; + ptr = VarintParse(ptr, &val); + if (ptr == nullptr) return false; + break; + } + case 1: { // fixed64 + ptr += 8; + break; + } + case 2: { // len delim + arc_i32 size = ReadSize(&ptr); + if (ptr == nullptr || size > end - ptr) return false; + ptr += size; + break; + } + case 3: { // start group + depth++; + break; + } + case 4: { // end group + if (--depth < 0) return true; // We exit early + break; + } + case 5: { // fixed32 + ptr += 4; + break; + } + default: + return false; // Unknown wireformat + } + } + return false; +} + +} // namespace + +const char* EpsCopyInputStream::NextBuffer(int overrun, int depth) { + if (next_chunk_ == nullptr) return nullptr; // We've reached end of stream. + if (next_chunk_ != buffer_) { + GOOGLE_DCHECK(size_ > kSlopBytes); + // The chunk is large enough to be used directly + buffer_end_ = next_chunk_ + size_ - kSlopBytes; + auto res = next_chunk_; + next_chunk_ = buffer_; + if (aliasing_ == kOnPatch) aliasing_ = kNoDelta; + return res; + } + // Move the slop bytes of previous buffer to start of the patch buffer. + // Note we must use memmove because the previous buffer could be part of + // buffer_. + std::memmove(buffer_, buffer_end_, kSlopBytes); + if (overall_limit_ > 0 && + (depth < 0 || !ParseEndsInSlopRegion(buffer_, overrun, depth))) { + const void* data; + // ZeroCopyInputStream indicates Next may return 0 size buffers. Hence + // we loop. + while (StreamNext(&data)) { + if (size_ > kSlopBytes) { + // We got a large chunk + std::memcpy(buffer_ + kSlopBytes, data, kSlopBytes); + next_chunk_ = static_cast<const char*>(data); + buffer_end_ = buffer_ + kSlopBytes; + if (aliasing_ >= kNoDelta) aliasing_ = kOnPatch; + return buffer_; + } else if (size_ > 0) { + std::memcpy(buffer_ + kSlopBytes, data, size_); + next_chunk_ = buffer_; + buffer_end_ = buffer_ + size_; + if (aliasing_ >= kNoDelta) aliasing_ = kOnPatch; + return buffer_; + } + GOOGLE_DCHECK(size_ == 0) << size_; + } + overall_limit_ = 0; // Next failed, no more needs for next + } + // End of stream or array + if (aliasing_ == kNoDelta) { + // If there is no more block and aliasing is true, the previous block + // is still valid and we can alias. We have users relying on string_view's + // obtained from protos to outlive the proto, when the parse was from an + // array. This guarantees string_view's are always aliased if parsed from + // an array. + aliasing_ = reinterpret_cast<std::uintptr_t>(buffer_end_) - + reinterpret_cast<std::uintptr_t>(buffer_); + } + next_chunk_ = nullptr; + buffer_end_ = buffer_ + kSlopBytes; + size_ = 0; + return buffer_; +} + +const char* EpsCopyInputStream::Next() { + GOOGLE_DCHECK(limit_ > kSlopBytes); + auto p = NextBuffer(0 /* immaterial */, -1); + if (p == nullptr) { + limit_end_ = buffer_end_; + // Distinguish ending on a pushed limit or ending on end-of-stream. + SetEndOfStream(); + return nullptr; + } + limit_ -= buffer_end_ - p; // Adjust limit_ relative to new anchor + limit_end_ = buffer_end_ + std::min(0, limit_); + return p; +} + +std::pair<const char*, bool> EpsCopyInputStream::DoneFallback(int overrun, + int depth) { + // Did we exceeded the limit (parse error). + if (PROTOBUF_PREDICT_FALSE(overrun > limit_)) return {nullptr, true}; + GOOGLE_DCHECK(overrun != limit_); // Guaranteed by caller. + GOOGLE_DCHECK(overrun < limit_); // Follows from above + // TODO(gerbens) Instead of this dcheck we could just assign, and remove + // updating the limit_end from PopLimit, ie. + // limit_end_ = buffer_end_ + (std::min)(0, limit_); + // if (ptr < limit_end_) return {ptr, false}; + GOOGLE_DCHECK(limit_end_ == buffer_end_ + (std::min)(0, limit_)); + // At this point we know the following assertion holds. + GOOGLE_DCHECK(limit_ > 0); + GOOGLE_DCHECK(limit_end_ == buffer_end_); // because limit_ > 0 + const char* p; + do { + // We are past the end of buffer_end_, in the slop region. + GOOGLE_DCHECK(overrun >= 0); + p = NextBuffer(overrun, depth); + if (p == nullptr) { + // We are at the end of the stream + if (PROTOBUF_PREDICT_FALSE(overrun != 0)) return {nullptr, true}; + GOOGLE_DCHECK(limit_ > 0); + limit_end_ = buffer_end_; + // Distinguish ending on a pushed limit or ending on end-of-stream. + SetEndOfStream(); + return {buffer_end_, true}; + } + limit_ -= buffer_end_ - p; // Adjust limit_ relative to new anchor + p += overrun; + overrun = p - buffer_end_; + } while (overrun >= 0); + limit_end_ = buffer_end_ + std::min(0, limit_); + return {p, false}; +} + +const char* EpsCopyInputStream::SkipFallback(const char* ptr, int size) { + return AppendSize(ptr, size, [](const char* /*p*/, int /*s*/) {}); +} + +const char* EpsCopyInputStream::ReadStringFallback(const char* ptr, int size, + TProtoStringType* str) { + str->clear(); + if (PROTOBUF_PREDICT_TRUE(size <= buffer_end_ - ptr + limit_)) { + // Reserve the string up to a static safe size. If strings are bigger than + // this we proceed by growing the string as needed. This protects against + // malicious payloads making protobuf hold on to a lot of memory. + str->reserve(str->size() + std::min<int>(size, kSafeStringSize)); + } + return AppendSize(ptr, size, + [str](const char* p, int s) { str->append(p, s); }); +} + +const char* EpsCopyInputStream::AppendStringFallback(const char* ptr, int size, + TProtoStringType* str) { + if (PROTOBUF_PREDICT_TRUE(size <= buffer_end_ - ptr + limit_)) { + // Reserve the string up to a static safe size. If strings are bigger than + // this we proceed by growing the string as needed. This protects against + // malicious payloads making protobuf hold on to a lot of memory. + str->reserve(str->size() + std::min<int>(size, kSafeStringSize)); + } + return AppendSize(ptr, size, + [str](const char* p, int s) { str->append(p, s); }); +} + + +template <int> +void byteswap(void* p); +template <> +void byteswap<1>(void* /*p*/) {} +template <> +void byteswap<4>(void* p) { + *static_cast<arc_ui32*>(p) = bswap_32(*static_cast<arc_ui32*>(p)); +} +template <> +void byteswap<8>(void* p) { + *static_cast<arc_ui64*>(p) = bswap_64(*static_cast<arc_ui64*>(p)); +} + +const char* EpsCopyInputStream::InitFrom(io::ZeroCopyInputStream* zcis) { + zcis_ = zcis; + const void* data; + int size; + limit_ = INT_MAX; + if (zcis->Next(&data, &size)) { + overall_limit_ -= size; + if (size > kSlopBytes) { + auto ptr = static_cast<const char*>(data); + limit_ -= size - kSlopBytes; + limit_end_ = buffer_end_ = ptr + size - kSlopBytes; + next_chunk_ = buffer_; + if (aliasing_ == kOnPatch) aliasing_ = kNoDelta; + return ptr; + } else { + limit_end_ = buffer_end_ = buffer_ + kSlopBytes; + next_chunk_ = buffer_; + auto ptr = buffer_ + 2 * kSlopBytes - size; + std::memcpy(ptr, data, size); + return ptr; + } + } + overall_limit_ = 0; + next_chunk_ = nullptr; + size_ = 0; + limit_end_ = buffer_end_ = buffer_; + return buffer_; +} + +const char* ParseContext::ReadSizeAndPushLimitAndDepth(const char* ptr, + int* old_limit) { + int size = ReadSize(&ptr); + if (PROTOBUF_PREDICT_FALSE(!ptr)) { + *old_limit = 0; // Make sure this isn't uninitialized even on error return + return nullptr; + } + *old_limit = PushLimit(ptr, size); + if (--depth_ < 0) return nullptr; + return ptr; +} + +const char* ParseContext::ParseMessage(MessageLite* msg, const char* ptr) { + int old; + ptr = ReadSizeAndPushLimitAndDepth(ptr, &old); + ptr = ptr ? msg->_InternalParse(ptr, this) : nullptr; + depth_++; + if (!PopLimit(old)) return nullptr; + return ptr; +} + +inline void WriteVarint(arc_ui64 val, TProtoStringType* s) { + while (val >= 128) { + uint8_t c = val | 0x80; + s->push_back(c); + val >>= 7; + } + s->push_back(val); +} + +void WriteVarint(arc_ui32 num, arc_ui64 val, TProtoStringType* s) { + WriteVarint(num << 3, s); + WriteVarint(val, s); +} + +void WriteLengthDelimited(arc_ui32 num, StringPiece val, TProtoStringType* s) { + WriteVarint((num << 3) + 2, s); + WriteVarint(val.size(), s); + s->append(val.data(), val.size()); +} + +std::pair<const char*, arc_ui32> VarintParseSlow32(const char* p, + arc_ui32 res) { + for (arc_ui32 i = 2; i < 5; i++) { + arc_ui32 byte = static_cast<uint8_t>(p[i]); + res += (byte - 1) << (7 * i); + if (PROTOBUF_PREDICT_TRUE(byte < 128)) { + return {p + i + 1, res}; + } + } + // Accept >5 bytes + for (arc_ui32 i = 5; i < 10; i++) { + arc_ui32 byte = static_cast<uint8_t>(p[i]); + if (PROTOBUF_PREDICT_TRUE(byte < 128)) { + return {p + i + 1, res}; + } + } + return {nullptr, 0}; +} + +std::pair<const char*, arc_ui64> VarintParseSlow64(const char* p, + arc_ui32 res32) { + arc_ui64 res = res32; + for (arc_ui32 i = 2; i < 10; i++) { + arc_ui64 byte = static_cast<uint8_t>(p[i]); + res += (byte - 1) << (7 * i); + if (PROTOBUF_PREDICT_TRUE(byte < 128)) { + return {p + i + 1, res}; + } + } + return {nullptr, 0}; +} + +std::pair<const char*, arc_ui32> ReadTagFallback(const char* p, arc_ui32 res) { + for (arc_ui32 i = 2; i < 5; i++) { + arc_ui32 byte = static_cast<uint8_t>(p[i]); + res += (byte - 1) << (7 * i); + if (PROTOBUF_PREDICT_TRUE(byte < 128)) { + return {p + i + 1, res}; + } + } + return {nullptr, 0}; +} + +std::pair<const char*, arc_i32> ReadSizeFallback(const char* p, arc_ui32 res) { + for (arc_ui32 i = 1; i < 4; i++) { + arc_ui32 byte = static_cast<uint8_t>(p[i]); + res += (byte - 1) << (7 * i); + if (PROTOBUF_PREDICT_TRUE(byte < 128)) { + return {p + i + 1, res}; + } + } + arc_ui32 byte = static_cast<uint8_t>(p[4]); + if (PROTOBUF_PREDICT_FALSE(byte >= 8)) return {nullptr, 0}; // size >= 2gb + res += (byte - 1) << 28; + // Protect against sign integer overflow in PushLimit. Limits are relative + // to buffer ends and ptr could potential be kSlopBytes beyond a buffer end. + // To protect against overflow we reject limits absurdly close to INT_MAX. + if (PROTOBUF_PREDICT_FALSE(res > INT_MAX - ParseContext::kSlopBytes)) { + return {nullptr, 0}; + } + return {p + 5, res}; +} + +const char* StringParser(const char* begin, const char* end, void* object, + ParseContext*) { + auto str = static_cast<TProtoStringType*>(object); + str->append(begin, end - begin); + return end; +} + +// Defined in wire_format_lite.cc +void PrintUTF8ErrorLog(const char* field_name, const char* operation_str, + bool emit_stacktrace); + +bool VerifyUTF8(StringPiece str, const char* field_name) { + if (!IsStructurallyValidUTF8(str)) { + PrintUTF8ErrorLog(field_name, "parsing", false); + return false; + } + return true; +} + +const char* InlineGreedyStringParser(TProtoStringType* s, const char* ptr, + ParseContext* ctx) { + int size = ReadSize(&ptr); + if (!ptr) return nullptr; + return ctx->ReadString(ptr, size, s); +} + + +template <typename T, bool sign> +const char* VarintParser(void* object, const char* ptr, ParseContext* ctx) { + return ctx->ReadPackedVarint(ptr, [object](arc_ui64 varint) { + T val; + if (sign) { + if (sizeof(T) == 8) { + val = WireFormatLite::ZigZagDecode64(varint); + } else { + val = WireFormatLite::ZigZagDecode32(varint); + } + } else { + val = varint; + } + static_cast<RepeatedField<T>*>(object)->Add(val); + }); +} + +const char* PackedInt32Parser(void* object, const char* ptr, + ParseContext* ctx) { + return VarintParser<arc_i32, false>(object, ptr, ctx); +} +const char* PackedUInt32Parser(void* object, const char* ptr, + ParseContext* ctx) { + return VarintParser<arc_ui32, false>(object, ptr, ctx); +} +const char* PackedInt64Parser(void* object, const char* ptr, + ParseContext* ctx) { + return VarintParser<arc_i64, false>(object, ptr, ctx); +} +const char* PackedUInt64Parser(void* object, const char* ptr, + ParseContext* ctx) { + return VarintParser<arc_ui64, false>(object, ptr, ctx); +} +const char* PackedSInt32Parser(void* object, const char* ptr, + ParseContext* ctx) { + return VarintParser<arc_i32, true>(object, ptr, ctx); +} +const char* PackedSInt64Parser(void* object, const char* ptr, + ParseContext* ctx) { + return VarintParser<arc_i64, true>(object, ptr, ctx); +} + +const char* PackedEnumParser(void* object, const char* ptr, ParseContext* ctx) { + return VarintParser<int, false>(object, ptr, ctx); +} + +const char* PackedBoolParser(void* object, const char* ptr, ParseContext* ctx) { + return VarintParser<bool, false>(object, ptr, ctx); +} + +template <typename T> +const char* FixedParser(void* object, const char* ptr, ParseContext* ctx) { + int size = ReadSize(&ptr); + return ctx->ReadPackedFixed(ptr, size, + static_cast<RepeatedField<T>*>(object)); +} + +const char* PackedFixed32Parser(void* object, const char* ptr, + ParseContext* ctx) { + return FixedParser<arc_ui32>(object, ptr, ctx); +} +const char* PackedSFixed32Parser(void* object, const char* ptr, + ParseContext* ctx) { + return FixedParser<arc_i32>(object, ptr, ctx); +} +const char* PackedFixed64Parser(void* object, const char* ptr, + ParseContext* ctx) { + return FixedParser<arc_ui64>(object, ptr, ctx); +} +const char* PackedSFixed64Parser(void* object, const char* ptr, + ParseContext* ctx) { + return FixedParser<arc_i64>(object, ptr, ctx); +} +const char* PackedFloatParser(void* object, const char* ptr, + ParseContext* ctx) { + return FixedParser<float>(object, ptr, ctx); +} +const char* PackedDoubleParser(void* object, const char* ptr, + ParseContext* ctx) { + return FixedParser<double>(object, ptr, ctx); +} + +class UnknownFieldLiteParserHelper { + public: + explicit UnknownFieldLiteParserHelper(TProtoStringType* unknown) + : unknown_(unknown) {} + + void AddVarint(arc_ui32 num, arc_ui64 value) { + if (unknown_ == nullptr) return; + WriteVarint(num * 8, unknown_); + WriteVarint(value, unknown_); + } + void AddFixed64(arc_ui32 num, arc_ui64 value) { + if (unknown_ == nullptr) return; + WriteVarint(num * 8 + 1, unknown_); + char buffer[8]; + io::CodedOutputStream::WriteLittleEndian64ToArray( + value, reinterpret_cast<uint8_t*>(buffer)); + unknown_->append(buffer, 8); + } + const char* ParseLengthDelimited(arc_ui32 num, const char* ptr, + ParseContext* ctx) { + int size = ReadSize(&ptr); + GOOGLE_PROTOBUF_PARSER_ASSERT(ptr); + if (unknown_ == nullptr) return ctx->Skip(ptr, size); + WriteVarint(num * 8 + 2, unknown_); + WriteVarint(size, unknown_); + return ctx->AppendString(ptr, size, unknown_); + } + const char* ParseGroup(arc_ui32 num, const char* ptr, ParseContext* ctx) { + if (unknown_) WriteVarint(num * 8 + 3, unknown_); + ptr = ctx->ParseGroup(this, ptr, num * 8 + 3); + GOOGLE_PROTOBUF_PARSER_ASSERT(ptr); + if (unknown_) WriteVarint(num * 8 + 4, unknown_); + return ptr; + } + void AddFixed32(arc_ui32 num, arc_ui32 value) { + if (unknown_ == nullptr) return; + WriteVarint(num * 8 + 5, unknown_); + char buffer[4]; + io::CodedOutputStream::WriteLittleEndian32ToArray( + value, reinterpret_cast<uint8_t*>(buffer)); + unknown_->append(buffer, 4); + } + + const char* _InternalParse(const char* ptr, ParseContext* ctx) { + return WireFormatParser(*this, ptr, ctx); + } + + private: + TProtoStringType* unknown_; +}; + +const char* UnknownGroupLiteParse(TProtoStringType* unknown, const char* ptr, + ParseContext* ctx) { + UnknownFieldLiteParserHelper field_parser(unknown); + return WireFormatParser(field_parser, ptr, ctx); +} + +const char* UnknownFieldParse(arc_ui32 tag, TProtoStringType* unknown, + const char* ptr, ParseContext* ctx) { + UnknownFieldLiteParserHelper field_parser(unknown); + return FieldParser(tag, field_parser, ptr, ctx); +} + +} // namespace internal +} // namespace protobuf +} // namespace google + +#include <google/protobuf/port_undef.inc> diff --git a/contrib/libs/protobuf_old/src/google/protobuf/parse_context.h b/contrib/libs/protobuf_old/src/google/protobuf/parse_context.h new file mode 100644 index 0000000000..32c72f9c64 --- /dev/null +++ b/contrib/libs/protobuf_old/src/google/protobuf/parse_context.h @@ -0,0 +1,940 @@ +// 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_PARSE_CONTEXT_H__ +#define GOOGLE_PROTOBUF_PARSE_CONTEXT_H__ + +#include <cstdint> +#include <cstring> +#include <string> + +#include <google/protobuf/io/coded_stream.h> +#include <google/protobuf/io/zero_copy_stream.h> +#include <google/protobuf/arena.h> +#include <google/protobuf/arenastring.h> +#include <google/protobuf/implicit_weak_message.h> +#include <google/protobuf/inlined_string_field.h> +#include <google/protobuf/metadata_lite.h> +#include <google/protobuf/port.h> +#include <google/protobuf/repeated_field.h> +#include <google/protobuf/wire_format_lite.h> +#include <google/protobuf/stubs/strutil.h> + +#include <google/protobuf/port_def.inc> + + +namespace google { +namespace protobuf { + +class UnknownFieldSet; +class DescriptorPool; +class MessageFactory; + +namespace internal { + +// Template code below needs to know about the existence of these functions. +PROTOBUF_EXPORT void WriteVarint(arc_ui32 num, arc_ui64 val, TProtoStringType* s); +PROTOBUF_EXPORT void WriteLengthDelimited(arc_ui32 num, StringPiece val, + TProtoStringType* s); +// Inline because it is just forwarding to s->WriteVarint +inline void WriteVarint(arc_ui32 num, arc_ui64 val, UnknownFieldSet* s); +inline void WriteLengthDelimited(arc_ui32 num, StringPiece val, + UnknownFieldSet* s); + + +// The basic abstraction the parser is designed for is a slight modification +// of the ZeroCopyInputStream (ZCIS) abstraction. A ZCIS presents a serialized +// stream as a series of buffers that concatenate to the full stream. +// Pictorially a ZCIS presents a stream in chunks like so +// [---------------------------------------------------------------] +// [---------------------] chunk 1 +// [----------------------------] chunk 2 +// chunk 3 [--------------] +// +// Where the '-' represent the bytes which are vertically lined up with the +// bytes of the stream. The proto parser requires its input to be presented +// similarly with the extra +// property that each chunk has kSlopBytes past its end that overlaps with the +// first kSlopBytes of the next chunk, or if there is no next chunk at least its +// still valid to read those bytes. Again, pictorially, we now have +// +// [---------------------------------------------------------------] +// [-------------------....] chunk 1 +// [------------------------....] chunk 2 +// chunk 3 [------------------..**] +// chunk 4 [--****] +// Here '-' mean the bytes of the stream or chunk and '.' means bytes past the +// chunk that match up with the start of the next chunk. Above each chunk has +// 4 '.' after the chunk. In the case these 'overflow' bytes represents bytes +// past the stream, indicated by '*' above, their values are unspecified. It is +// still legal to read them (ie. should not segfault). Reading past the +// end should be detected by the user and indicated as an error. +// +// The reason for this, admittedly, unconventional invariant is to ruthlessly +// optimize the protobuf parser. Having an overlap helps in two important ways. +// Firstly it alleviates having to performing bounds checks if a piece of code +// is guaranteed to not read more than kSlopBytes. Secondly, and more +// importantly, the protobuf wireformat is such that reading a key/value pair is +// always less than 16 bytes. This removes the need to change to next buffer in +// the middle of reading primitive values. Hence there is no need to store and +// load the current position. + +class PROTOBUF_EXPORT EpsCopyInputStream { + public: + enum { kSlopBytes = 16, kMaxCordBytesToCopy = 512 }; + + explicit EpsCopyInputStream(bool enable_aliasing) + : aliasing_(enable_aliasing ? kOnPatch : kNoAliasing) {} + + void BackUp(const char* ptr) { + GOOGLE_DCHECK(ptr <= buffer_end_ + kSlopBytes); + int count; + if (next_chunk_ == buffer_) { + count = static_cast<int>(buffer_end_ + kSlopBytes - ptr); + } else { + count = size_ + static_cast<int>(buffer_end_ - ptr); + } + if (count > 0) StreamBackUp(count); + } + + // If return value is negative it's an error + PROTOBUF_NODISCARD int PushLimit(const char* ptr, int limit) { + GOOGLE_DCHECK(limit >= 0 && limit <= INT_MAX - kSlopBytes); + // This add is safe due to the invariant above, because + // ptr - buffer_end_ <= kSlopBytes. + limit += static_cast<int>(ptr - buffer_end_); + limit_end_ = buffer_end_ + (std::min)(0, limit); + auto old_limit = limit_; + limit_ = limit; + return old_limit - limit; + } + + PROTOBUF_NODISCARD bool PopLimit(int delta) { + if (PROTOBUF_PREDICT_FALSE(!EndedAtLimit())) return false; + limit_ = limit_ + delta; + // TODO(gerbens) We could remove this line and hoist the code to + // DoneFallback. Study the perf/bin-size effects. + limit_end_ = buffer_end_ + (std::min)(0, limit_); + return true; + } + + PROTOBUF_NODISCARD const char* Skip(const char* ptr, int size) { + if (size <= buffer_end_ + kSlopBytes - ptr) { + return ptr + size; + } + return SkipFallback(ptr, size); + } + PROTOBUF_NODISCARD const char* ReadString(const char* ptr, int size, + TProtoStringType* s) { + if (size <= buffer_end_ + kSlopBytes - ptr) { + s->assign(ptr, size); + return ptr + size; + } + return ReadStringFallback(ptr, size, s); + } + PROTOBUF_NODISCARD const char* AppendString(const char* ptr, int size, + TProtoStringType* s) { + if (size <= buffer_end_ + kSlopBytes - ptr) { + s->append(ptr, size); + return ptr + size; + } + return AppendStringFallback(ptr, size, s); + } + // Implemented in arenastring.cc + PROTOBUF_NODISCARD const char* ReadArenaString(const char* ptr, + ArenaStringPtr* s, + Arena* arena); + + template <typename Tag, typename T> + PROTOBUF_NODISCARD const char* ReadRepeatedFixed(const char* ptr, + Tag expected_tag, + RepeatedField<T>* out); + + template <typename T> + PROTOBUF_NODISCARD const char* ReadPackedFixed(const char* ptr, int size, + RepeatedField<T>* out); + template <typename Add> + PROTOBUF_NODISCARD const char* ReadPackedVarint(const char* ptr, Add add); + + arc_ui32 LastTag() const { return last_tag_minus_1_ + 1; } + bool ConsumeEndGroup(arc_ui32 start_tag) { + bool res = last_tag_minus_1_ == start_tag; + last_tag_minus_1_ = 0; + return res; + } + bool EndedAtLimit() const { return last_tag_minus_1_ == 0; } + bool EndedAtEndOfStream() const { return last_tag_minus_1_ == 1; } + void SetLastTag(arc_ui32 tag) { last_tag_minus_1_ = tag - 1; } + void SetEndOfStream() { last_tag_minus_1_ = 1; } + bool IsExceedingLimit(const char* ptr) { + return ptr > limit_end_ && + (next_chunk_ == nullptr || ptr - buffer_end_ > limit_); + } + int BytesUntilLimit(const char* ptr) const { + return limit_ + static_cast<int>(buffer_end_ - ptr); + } + // Returns true if more data is available, if false is returned one has to + // call Done for further checks. + bool DataAvailable(const char* ptr) { return ptr < limit_end_; } + + protected: + // Returns true is limit (either an explicit limit or end of stream) is + // reached. It aligns *ptr across buffer seams. + // If limit is exceeded it returns true and ptr is set to null. + bool DoneWithCheck(const char** ptr, int d) { + GOOGLE_DCHECK(*ptr); + if (PROTOBUF_PREDICT_TRUE(*ptr < limit_end_)) return false; + int overrun = static_cast<int>(*ptr - buffer_end_); + GOOGLE_DCHECK_LE(overrun, kSlopBytes); // Guaranteed by parse loop. + if (overrun == + limit_) { // No need to flip buffers if we ended on a limit. + // If we actually overrun the buffer and next_chunk_ is null. It means + // the stream ended and we passed the stream end. + if (overrun > 0 && next_chunk_ == nullptr) *ptr = nullptr; + return true; + } + auto res = DoneFallback(overrun, d); + *ptr = res.first; + return res.second; + } + + const char* InitFrom(StringPiece flat) { + overall_limit_ = 0; + if (flat.size() > kSlopBytes) { + limit_ = kSlopBytes; + limit_end_ = buffer_end_ = flat.data() + flat.size() - kSlopBytes; + next_chunk_ = buffer_; + if (aliasing_ == kOnPatch) aliasing_ = kNoDelta; + return flat.data(); + } else { + if (!flat.empty()) { + std::memcpy(buffer_, flat.data(), flat.size()); + } + limit_ = 0; + limit_end_ = buffer_end_ = buffer_ + flat.size(); + next_chunk_ = nullptr; + if (aliasing_ == kOnPatch) { + aliasing_ = reinterpret_cast<std::uintptr_t>(flat.data()) - + reinterpret_cast<std::uintptr_t>(buffer_); + } + return buffer_; + } + } + + const char* InitFrom(io::ZeroCopyInputStream* zcis); + + const char* InitFrom(io::ZeroCopyInputStream* zcis, int limit) { + if (limit == -1) return InitFrom(zcis); + overall_limit_ = limit; + auto res = InitFrom(zcis); + limit_ = limit - static_cast<int>(buffer_end_ - res); + limit_end_ = buffer_end_ + (std::min)(0, limit_); + return res; + } + + private: + const char* limit_end_; // buffer_end_ + min(limit_, 0) + const char* buffer_end_; + const char* next_chunk_; + int size_; + int limit_; // relative to buffer_end_; + io::ZeroCopyInputStream* zcis_ = nullptr; + char buffer_[2 * kSlopBytes] = {}; + enum { kNoAliasing = 0, kOnPatch = 1, kNoDelta = 2 }; + std::uintptr_t aliasing_ = kNoAliasing; + // This variable is used to communicate how the parse ended, in order to + // completely verify the parsed data. A wire-format parse can end because of + // one of the following conditions: + // 1) A parse can end on a pushed limit. + // 2) A parse can end on End Of Stream (EOS). + // 3) A parse can end on 0 tag (only valid for toplevel message). + // 4) A parse can end on an end-group tag. + // This variable should always be set to 0, which indicates case 1. If the + // parse terminated due to EOS (case 2), it's set to 1. In case the parse + // ended due to a terminating tag (case 3 and 4) it's set to (tag - 1). + // This var doesn't really belong in EpsCopyInputStream and should be part of + // the ParseContext, but case 2 is most easily and optimally implemented in + // DoneFallback. + arc_ui32 last_tag_minus_1_ = 0; + int overall_limit_ = INT_MAX; // Overall limit independent of pushed limits. + // Pretty random large number that seems like a safe allocation on most + // systems. TODO(gerbens) do we need to set this as build flag? + enum { kSafeStringSize = 50000000 }; + + // Advances to next buffer chunk returns a pointer to the same logical place + // in the stream as set by overrun. Overrun indicates the position in the slop + // region the parse was left (0 <= overrun <= kSlopBytes). Returns true if at + // limit, at which point the returned pointer maybe null if there was an + // error. The invariant of this function is that it's guaranteed that + // kSlopBytes bytes can be accessed from the returned ptr. This function might + // advance more buffers than one in the underlying ZeroCopyInputStream. + std::pair<const char*, bool> DoneFallback(int overrun, int depth); + // Advances to the next buffer, at most one call to Next() on the underlying + // ZeroCopyInputStream is made. This function DOES NOT match the returned + // pointer to where in the slop region the parse ends, hence no overrun + // parameter. This is useful for string operations where you always copy + // to the end of the buffer (including the slop region). + const char* Next(); + // overrun is the location in the slop region the stream currently is + // (0 <= overrun <= kSlopBytes). To prevent flipping to the next buffer of + // the ZeroCopyInputStream in the case the parse will end in the last + // kSlopBytes of the current buffer. depth is the current depth of nested + // groups (or negative if the use case does not need careful tracking). + inline const char* NextBuffer(int overrun, int depth); + const char* SkipFallback(const char* ptr, int size); + const char* AppendStringFallback(const char* ptr, int size, TProtoStringType* str); + const char* ReadStringFallback(const char* ptr, int size, TProtoStringType* str); + bool StreamNext(const void** data) { + bool res = zcis_->Next(data, &size_); + if (res) overall_limit_ -= size_; + return res; + } + void StreamBackUp(int count) { + zcis_->BackUp(count); + overall_limit_ += count; + } + + template <typename A> + const char* AppendSize(const char* ptr, int size, const A& append) { + int chunk_size = buffer_end_ + kSlopBytes - ptr; + do { + GOOGLE_DCHECK(size > chunk_size); + if (next_chunk_ == nullptr) return nullptr; + append(ptr, chunk_size); + ptr += chunk_size; + size -= chunk_size; + // TODO(gerbens) Next calls NextBuffer which generates buffers with + // overlap and thus incurs cost of copying the slop regions. This is not + // necessary for reading strings. We should just call Next buffers. + if (limit_ <= kSlopBytes) return nullptr; + ptr = Next(); + if (ptr == nullptr) return nullptr; // passed the limit + ptr += kSlopBytes; + chunk_size = buffer_end_ + kSlopBytes - ptr; + } while (size > chunk_size); + append(ptr, size); + return ptr + size; + } + + // AppendUntilEnd appends data until a limit (either a PushLimit or end of + // stream. Normal payloads are from length delimited fields which have an + // explicit size. Reading until limit only comes when the string takes + // the place of a protobuf, ie RawMessage/StringRawMessage, lazy fields and + // implicit weak messages. We keep these methods private and friend them. + template <typename A> + const char* AppendUntilEnd(const char* ptr, const A& append) { + if (ptr - buffer_end_ > limit_) return nullptr; + while (limit_ > kSlopBytes) { + size_t chunk_size = buffer_end_ + kSlopBytes - ptr; + append(ptr, chunk_size); + ptr = Next(); + if (ptr == nullptr) return limit_end_; + ptr += kSlopBytes; + } + auto end = buffer_end_ + limit_; + GOOGLE_DCHECK(end >= ptr); + append(ptr, end - ptr); + return end; + } + + PROTOBUF_NODISCARD const char* AppendString(const char* ptr, + TProtoStringType* str) { + return AppendUntilEnd( + ptr, [str](const char* p, ptrdiff_t s) { str->append(p, s); }); + } + friend class ImplicitWeakMessage; +}; + +// ParseContext holds all data that is global to the entire parse. Most +// importantly it contains the input stream, but also recursion depth and also +// stores the end group tag, in case a parser ended on a endgroup, to verify +// matching start/end group tags. +class PROTOBUF_EXPORT ParseContext : public EpsCopyInputStream { + public: + struct Data { + const DescriptorPool* pool = nullptr; + MessageFactory* factory = nullptr; + Arena* arena = nullptr; + }; + + template <typename... T> + ParseContext(int depth, bool aliasing, const char** start, T&&... args) + : EpsCopyInputStream(aliasing), depth_(depth) { + *start = InitFrom(std::forward<T>(args)...); + } + + void TrackCorrectEnding() { group_depth_ = 0; } + + bool Done(const char** ptr) { return DoneWithCheck(ptr, group_depth_); } + + int depth() const { return depth_; } + + Data& data() { return data_; } + const Data& data() const { return data_; } + + const char* ParseMessage(MessageLite* msg, const char* ptr); + + // This overload supports those few cases where ParseMessage is called + // on a class that is not actually a proto message. + // TODO(jorg): Eliminate this use case. + template <typename T, + typename std::enable_if<!std::is_base_of<MessageLite, T>::value, + bool>::type = true> + PROTOBUF_NODISCARD const char* ParseMessage(T* msg, const char* ptr); + + template <typename T> + PROTOBUF_NODISCARD PROTOBUF_NDEBUG_INLINE const char* ParseGroup( + T* msg, const char* ptr, arc_ui32 tag) { + if (--depth_ < 0) return nullptr; + group_depth_++; + ptr = msg->_InternalParse(ptr, this); + group_depth_--; + depth_++; + if (PROTOBUF_PREDICT_FALSE(!ConsumeEndGroup(tag))) return nullptr; + return ptr; + } + + private: + // Out-of-line routine to save space in ParseContext::ParseMessage<T> + // int old; + // ptr = ReadSizeAndPushLimitAndDepth(ptr, &old) + // is equivalent to: + // int size = ReadSize(&ptr); + // if (!ptr) return nullptr; + // int old = PushLimit(ptr, size); + // if (--depth_ < 0) return nullptr; + PROTOBUF_NODISCARD const char* ReadSizeAndPushLimitAndDepth(const char* ptr, + int* old_limit); + + // The context keeps an internal stack to keep track of the recursive + // part of the parse state. + // Current depth of the active parser, depth counts down. + // This is used to limit recursion depth (to prevent overflow on malicious + // data), but is also used to index in stack_ to store the current state. + int depth_; + // Unfortunately necessary for the fringe case of ending on 0 or end-group tag + // in the last kSlopBytes of a ZeroCopyInputStream chunk. + int group_depth_ = INT_MIN; + Data data_; +}; + +template <arc_ui32 tag> +bool ExpectTag(const char* ptr) { + if (tag < 128) { + return *ptr == static_cast<char>(tag); + } else { + static_assert(tag < 128 * 128, "We only expect tags for 1 or 2 bytes"); + char buf[2] = {static_cast<char>(tag | 0x80), static_cast<char>(tag >> 7)}; + return std::memcmp(ptr, buf, 2) == 0; + } +} + +template <int> +struct EndianHelper; + +template <> +struct EndianHelper<1> { + static uint8_t Load(const void* p) { return *static_cast<const uint8_t*>(p); } +}; + +template <> +struct EndianHelper<2> { + static uint16_t Load(const void* p) { + uint16_t tmp; + std::memcpy(&tmp, p, 2); +#ifndef PROTOBUF_LITTLE_ENDIAN + tmp = bswap_16(tmp); +#endif + return tmp; + } +}; + +template <> +struct EndianHelper<4> { + static arc_ui32 Load(const void* p) { + arc_ui32 tmp; + std::memcpy(&tmp, p, 4); +#ifndef PROTOBUF_LITTLE_ENDIAN + tmp = bswap_32(tmp); +#endif + return tmp; + } +}; + +template <> +struct EndianHelper<8> { + static arc_ui64 Load(const void* p) { + arc_ui64 tmp; + std::memcpy(&tmp, p, 8); +#ifndef PROTOBUF_LITTLE_ENDIAN + tmp = bswap_64(tmp); +#endif + return tmp; + } +}; + +template <typename T> +T UnalignedLoad(const char* p) { + auto tmp = EndianHelper<sizeof(T)>::Load(p); + T res; + memcpy(&res, &tmp, sizeof(T)); + return res; +} + +PROTOBUF_EXPORT +std::pair<const char*, arc_ui32> VarintParseSlow32(const char* p, arc_ui32 res); +PROTOBUF_EXPORT +std::pair<const char*, arc_ui64> VarintParseSlow64(const char* p, arc_ui32 res); + +inline const char* VarintParseSlow(const char* p, arc_ui32 res, arc_ui32* out) { + auto tmp = VarintParseSlow32(p, res); + *out = tmp.second; + return tmp.first; +} + +inline const char* VarintParseSlow(const char* p, arc_ui32 res, arc_ui64* out) { + auto tmp = VarintParseSlow64(p, res); + *out = tmp.second; + return tmp.first; +} + +template <typename T> +PROTOBUF_NODISCARD const char* VarintParse(const char* p, T* out) { + auto ptr = reinterpret_cast<const uint8_t*>(p); + arc_ui32 res = ptr[0]; + if (!(res & 0x80)) { + *out = res; + return p + 1; + } + arc_ui32 byte = ptr[1]; + res += (byte - 1) << 7; + if (!(byte & 0x80)) { + *out = res; + return p + 2; + } + return VarintParseSlow(p, res, out); +} + +// Used for tags, could read up to 5 bytes which must be available. +// Caller must ensure its safe to call. + +PROTOBUF_EXPORT +std::pair<const char*, arc_ui32> ReadTagFallback(const char* p, arc_ui32 res); + +// Same as ParseVarint but only accept 5 bytes at most. +inline const char* ReadTag(const char* p, arc_ui32* out, + arc_ui32 /*max_tag*/ = 0) { + arc_ui32 res = static_cast<uint8_t>(p[0]); + if (res < 128) { + *out = res; + return p + 1; + } + arc_ui32 second = static_cast<uint8_t>(p[1]); + res += (second - 1) << 7; + if (second < 128) { + *out = res; + return p + 2; + } + auto tmp = ReadTagFallback(p, res); + *out = tmp.second; + return tmp.first; +} + +// Decode 2 consecutive bytes of a varint and returns the value, shifted left +// by 1. It simultaneous updates *ptr to *ptr + 1 or *ptr + 2 depending if the +// first byte's continuation bit is set. +// If bit 15 of return value is set (equivalent to the continuation bits of both +// bytes being set) the varint continues, otherwise the parse is done. On x86 +// movsx eax, dil +// add edi, eax +// adc [rsi], 1 +// add eax, eax +// and eax, edi +inline arc_ui32 DecodeTwoBytes(const char** ptr) { + arc_ui32 value = UnalignedLoad<uint16_t>(*ptr); + // Sign extend the low byte continuation bit + arc_ui32 x = static_cast<int8_t>(value); + // This add is an amazing operation, it cancels the low byte continuation bit + // from y transferring it to the carry. Simultaneously it also shifts the 7 + // LSB left by one tightly against high byte varint bits. Hence value now + // contains the unpacked value shifted left by 1. + value += x; + // Use the carry to update the ptr appropriately. + *ptr += value < x ? 2 : 1; + return value & (x + x); // Mask out the high byte iff no continuation +} + +// More efficient varint parsing for big varints +inline const char* ParseBigVarint(const char* p, arc_ui64* out) { + auto pnew = p; + auto tmp = DecodeTwoBytes(&pnew); + arc_ui64 res = tmp >> 1; + if (PROTOBUF_PREDICT_TRUE(static_cast<std::int16_t>(tmp) >= 0)) { + *out = res; + return pnew; + } + for (arc_ui32 i = 1; i < 5; i++) { + pnew = p + 2 * i; + tmp = DecodeTwoBytes(&pnew); + res += (static_cast<arc_ui64>(tmp) - 2) << (14 * i - 1); + if (PROTOBUF_PREDICT_TRUE(static_cast<std::int16_t>(tmp) >= 0)) { + *out = res; + return pnew; + } + } + return nullptr; +} + +PROTOBUF_EXPORT +std::pair<const char*, arc_i32> ReadSizeFallback(const char* p, arc_ui32 first); +// Used for tags, could read up to 5 bytes which must be available. Additionally +// it makes sure the unsigned value fits a arc_i32, otherwise returns nullptr. +// Caller must ensure its safe to call. +inline arc_ui32 ReadSize(const char** pp) { + auto p = *pp; + arc_ui32 res = static_cast<uint8_t>(p[0]); + if (res < 128) { + *pp = p + 1; + return res; + } + auto x = ReadSizeFallback(p, res); + *pp = x.first; + return x.second; +} + +// Some convenience functions to simplify the generated parse loop code. +// Returning the value and updating the buffer pointer allows for nicer +// function composition. We rely on the compiler to inline this. +// Also in debug compiles having local scoped variables tend to generated +// stack frames that scale as O(num fields). +inline arc_ui64 ReadVarint64(const char** p) { + arc_ui64 tmp; + *p = VarintParse(*p, &tmp); + return tmp; +} + +inline arc_ui32 ReadVarint32(const char** p) { + arc_ui32 tmp; + *p = VarintParse(*p, &tmp); + return tmp; +} + +inline arc_i64 ReadVarintZigZag64(const char** p) { + arc_ui64 tmp; + *p = VarintParse(*p, &tmp); + return WireFormatLite::ZigZagDecode64(tmp); +} + +inline arc_i32 ReadVarintZigZag32(const char** p) { + arc_ui64 tmp; + *p = VarintParse(*p, &tmp); + return WireFormatLite::ZigZagDecode32(static_cast<arc_ui32>(tmp)); +} + +template <typename T, typename std::enable_if< + !std::is_base_of<MessageLite, T>::value, bool>::type> +PROTOBUF_NODISCARD const char* ParseContext::ParseMessage(T* msg, + const char* ptr) { + int old; + ptr = ReadSizeAndPushLimitAndDepth(ptr, &old); + ptr = ptr ? msg->_InternalParse(ptr, this) : nullptr; + depth_++; + if (!PopLimit(old)) return nullptr; + 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; +} + +// Add any of the following lines to debug which parse function is failing. + +#define GOOGLE_PROTOBUF_ASSERT_RETURN(predicate, ret) \ + if (!(predicate)) { \ + /* ::raise(SIGINT); */ \ + /* GOOGLE_LOG(ERROR) << "Parse failure"; */ \ + return ret; \ + } + +#define GOOGLE_PROTOBUF_PARSER_ASSERT(predicate) \ + GOOGLE_PROTOBUF_ASSERT_RETURN(predicate, nullptr) + +template <typename T> +const char* EpsCopyInputStream::ReadPackedFixed(const char* ptr, int size, + RepeatedField<T>* out) { + GOOGLE_PROTOBUF_PARSER_ASSERT(ptr); + 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) { + arc_ui64 varint; + ptr = VarintParse(ptr, &varint); + if (ptr == nullptr) return nullptr; + add(varint); + } + return ptr; +} + +template <typename Add> +const char* EpsCopyInputStream::ReadPackedVarint(const char* ptr, Add add) { + int size = ReadSize(&ptr); + GOOGLE_PROTOBUF_PARSER_ASSERT(ptr); + int chunk_size = buffer_end_ - ptr; + while (size > chunk_size) { + ptr = ReadPackedVarintArray(ptr, buffer_end_, add); + if (ptr == nullptr) return nullptr; + int overrun = ptr - buffer_end_; + GOOGLE_DCHECK(overrun >= 0 && overrun <= kSlopBytes); + if (size - chunk_size <= kSlopBytes) { + // The current buffer contains all the information needed, we don't need + // to flip buffers. However we must parse from a buffer with enough space + // so we are not prone to a buffer overflow. + char buf[kSlopBytes + 10] = {}; + std::memcpy(buf, buffer_end_, kSlopBytes); + GOOGLE_CHECK_LE(size - chunk_size, kSlopBytes); + auto end = buf + (size - chunk_size); + auto res = ReadPackedVarintArray(buf + overrun, end, add); + if (res == nullptr || res != end) return nullptr; + return buffer_end_ + (res - buf); + } + size -= overrun + chunk_size; + GOOGLE_DCHECK_GT(size, 0); + // We must flip buffers + if (limit_ <= kSlopBytes) return nullptr; + ptr = Next(); + if (ptr == nullptr) return nullptr; + ptr += overrun; + chunk_size = buffer_end_ - ptr; + } + auto end = ptr + size; + ptr = ReadPackedVarintArray(ptr, end, add); + return end == ptr ? ptr : nullptr; +} + +// Helper for verification of utf8 +PROTOBUF_EXPORT +bool VerifyUTF8(StringPiece s, const char* field_name); + +inline bool VerifyUTF8(const TProtoStringType* s, const char* field_name) { + return VerifyUTF8(*s, field_name); +} + +// All the string parsers with or without UTF checking and for all CTypes. +PROTOBUF_EXPORT PROTOBUF_NODISCARD const char* InlineGreedyStringParser( + TProtoStringType* s, const char* ptr, ParseContext* ctx); + + +template <typename T> +PROTOBUF_NODISCARD const char* FieldParser(arc_ui64 tag, T& field_parser, + const char* ptr, ParseContext* ctx) { + arc_ui32 number = tag >> 3; + GOOGLE_PROTOBUF_PARSER_ASSERT(number != 0); + using WireType = internal::WireFormatLite::WireType; + switch (tag & 7) { + case WireType::WIRETYPE_VARINT: { + arc_ui64 value; + ptr = VarintParse(ptr, &value); + GOOGLE_PROTOBUF_PARSER_ASSERT(ptr); + field_parser.AddVarint(number, value); + break; + } + case WireType::WIRETYPE_FIXED64: { + arc_ui64 value = UnalignedLoad<arc_ui64>(ptr); + ptr += 8; + field_parser.AddFixed64(number, value); + break; + } + case WireType::WIRETYPE_LENGTH_DELIMITED: { + ptr = field_parser.ParseLengthDelimited(number, ptr, ctx); + GOOGLE_PROTOBUF_PARSER_ASSERT(ptr); + break; + } + case WireType::WIRETYPE_START_GROUP: { + ptr = field_parser.ParseGroup(number, ptr, ctx); + GOOGLE_PROTOBUF_PARSER_ASSERT(ptr); + break; + } + case WireType::WIRETYPE_END_GROUP: { + GOOGLE_LOG(FATAL) << "Can't happen"; + break; + } + case WireType::WIRETYPE_FIXED32: { + arc_ui32 value = UnalignedLoad<arc_ui32>(ptr); + ptr += 4; + field_parser.AddFixed32(number, value); + break; + } + default: + return nullptr; + } + return ptr; +} + +template <typename T> +PROTOBUF_NODISCARD const char* WireFormatParser(T& field_parser, + const char* ptr, + ParseContext* ctx) { + while (!ctx->Done(&ptr)) { + arc_ui32 tag; + ptr = ReadTag(ptr, &tag); + GOOGLE_PROTOBUF_PARSER_ASSERT(ptr != nullptr); + if (tag == 0 || (tag & 7) == 4) { + ctx->SetLastTag(tag); + return ptr; + } + ptr = FieldParser(tag, field_parser, ptr, ctx); + GOOGLE_PROTOBUF_PARSER_ASSERT(ptr != nullptr); + } + return ptr; +} + +// The packed parsers parse repeated numeric primitives directly into the +// corresponding field + +// These are packed varints +PROTOBUF_EXPORT PROTOBUF_NODISCARD const char* PackedInt32Parser( + void* object, const char* ptr, ParseContext* ctx); +PROTOBUF_EXPORT PROTOBUF_NODISCARD const char* PackedUInt32Parser( + void* object, const char* ptr, ParseContext* ctx); +PROTOBUF_EXPORT PROTOBUF_NODISCARD const char* PackedInt64Parser( + void* object, const char* ptr, ParseContext* ctx); +PROTOBUF_EXPORT PROTOBUF_NODISCARD const char* PackedUInt64Parser( + void* object, const char* ptr, ParseContext* ctx); +PROTOBUF_EXPORT PROTOBUF_NODISCARD const char* PackedSInt32Parser( + void* object, const char* ptr, ParseContext* ctx); +PROTOBUF_EXPORT PROTOBUF_NODISCARD const char* PackedSInt64Parser( + void* object, const char* ptr, ParseContext* ctx); +PROTOBUF_EXPORT PROTOBUF_NODISCARD const char* PackedEnumParser( + void* object, const char* ptr, ParseContext* ctx); + +template <typename T> +PROTOBUF_NODISCARD const char* PackedEnumParser(void* object, const char* ptr, + ParseContext* ctx, + bool (*is_valid)(int), + InternalMetadata* metadata, + int field_num) { + return ctx->ReadPackedVarint( + ptr, [object, is_valid, metadata, field_num](arc_ui64 val) { + if (is_valid(val)) { + static_cast<RepeatedField<int>*>(object)->Add(val); + } else { + WriteVarint(field_num, val, metadata->mutable_unknown_fields<T>()); + } + }); +} + +template <typename T> +PROTOBUF_NODISCARD const char* PackedEnumParserArg( + void* object, const char* ptr, ParseContext* ctx, + bool (*is_valid)(const void*, int), const void* data, + InternalMetadata* metadata, int field_num) { + return ctx->ReadPackedVarint( + ptr, [object, is_valid, data, metadata, field_num](arc_ui64 val) { + if (is_valid(data, val)) { + static_cast<RepeatedField<int>*>(object)->Add(val); + } else { + WriteVarint(field_num, val, metadata->mutable_unknown_fields<T>()); + } + }); +} + +PROTOBUF_EXPORT PROTOBUF_NODISCARD const char* PackedBoolParser( + void* object, const char* ptr, ParseContext* ctx); +PROTOBUF_EXPORT PROTOBUF_NODISCARD const char* PackedFixed32Parser( + void* object, const char* ptr, ParseContext* ctx); +PROTOBUF_EXPORT PROTOBUF_NODISCARD const char* PackedSFixed32Parser( + void* object, const char* ptr, ParseContext* ctx); +PROTOBUF_EXPORT PROTOBUF_NODISCARD const char* PackedFixed64Parser( + void* object, const char* ptr, ParseContext* ctx); +PROTOBUF_EXPORT PROTOBUF_NODISCARD const char* PackedSFixed64Parser( + void* object, const char* ptr, ParseContext* ctx); +PROTOBUF_EXPORT PROTOBUF_NODISCARD const char* PackedFloatParser( + void* object, const char* ptr, ParseContext* ctx); +PROTOBUF_EXPORT PROTOBUF_NODISCARD const char* PackedDoubleParser( + void* object, const char* ptr, ParseContext* ctx); + +// This is the only recursive parser. +PROTOBUF_EXPORT PROTOBUF_NODISCARD const char* UnknownGroupLiteParse( + TProtoStringType* unknown, const char* ptr, ParseContext* ctx); +// This is a helper to for the UnknownGroupLiteParse but is actually also +// useful in the generated code. It uses overload on TProtoStringType* vs +// UnknownFieldSet* to make the generated code isomorphic between full and lite. +PROTOBUF_EXPORT PROTOBUF_NODISCARD const char* UnknownFieldParse( + arc_ui32 tag, TProtoStringType* unknown, const char* ptr, ParseContext* ctx); + +} // namespace internal +} // namespace protobuf +} // namespace google + +#include <google/protobuf/port_undef.inc> + +#endif // GOOGLE_PROTOBUF_PARSE_CONTEXT_H__ diff --git a/contrib/libs/protobuf_old/src/google/protobuf/port.h b/contrib/libs/protobuf_old/src/google/protobuf/port.h new file mode 100644 index 0000000000..4c09eb1dbe --- /dev/null +++ b/contrib/libs/protobuf_old/src/google/protobuf/port.h @@ -0,0 +1,40 @@ +// 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. + +// A common header that is included across all protobuf headers. We do our best +// to avoid #defining any macros here; instead we generally put macros in +// port_def.inc and port_undef.inc so they are not visible from outside of +// protobuf. + +#ifndef GOOGLE_PROTOBUF_PORT_H__ +#define GOOGLE_PROTOBUF_PORT_H__ + + +#endif // GOOGLE_PROTOBUF_PORT_H__ diff --git a/contrib/libs/protobuf_old/src/google/protobuf/port_def.inc b/contrib/libs/protobuf_old/src/google/protobuf/port_def.inc new file mode 100644 index 0000000000..5706dc22d5 --- /dev/null +++ b/contrib/libs/protobuf_old/src/google/protobuf/port_def.inc @@ -0,0 +1,820 @@ +// 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 defines common macros that are used in protobuf. +// +// To hide these definitions from the outside world (and to prevent collisions +// if more than one version of protobuf is #included in the same project) you +// must follow this pattern when #including port_def.inc in a header file: +// +// #include "other_header.h" +// #include "message.h" +// // etc. +// +// #include "port_def.inc" // MUST be last header included +// +// // Definitions for this header. +// +// #include "port_undef.inc" +// +// This is a textual header with no include guard, because we want to +// detect/prohibit anytime it is #included twice without a corresponding +// #undef. + +// The definitions in this file are intended to be portable across Clang, +// GCC, and MSVC. Function-like macros are usable without an #ifdef guard. +// Syntax macros (for example, attributes) are always defined, although +// they may be empty. +// +// Some definitions rely on the NDEBUG macro and/or (in MSVC) _DEBUG: +// - https://en.cppreference.com/w/c/error/assert +// - https://docs.microsoft.com/en-us/cpp/preprocessor/predefined-macros#microsoft-specific-predefined-macros +// +// References for predefined macros: +// - Standard: https://en.cppreference.com/w/cpp/preprocessor/replace +// - Clang: https://clang.llvm.org/docs/LanguageExtensions.html +// (see also GCC predefined macros) +// - GCC: https://gcc.gnu.org/onlinedocs/cpp/Predefined-Macros.html +// - MSVC: https://docs.microsoft.com/en-us/cpp/preprocessor/predefined-macros +// - Interactive (Clang/GCC only): https://www.compiler-explorer.com/z/hc6jKd3sj +// +// References for attributes (and extension attributes): +// - Standard: https://en.cppreference.com/w/cpp/language/attributes +// - Clang: https://clang.llvm.org/docs/AttributeReference.html +// - GCC: https://gcc.gnu.org/onlinedocs/gcc/Attribute-Syntax.html +// (see Clang attribute docs as well) +// +// References for standard C++ language conformance (and minimum versions): +// - Clang: https://clang.llvm.org/cxx_status.html +// - GCC: https://gcc.gnu.org/projects/cxx-status.html +// - MSVC: https://docs.microsoft.com/en-us/cpp/overview/visual-cpp-language-conformance +// +// Historical release notes (which can help to determine minimum versions): +// - Clang: https://releases.llvm.org/ +// - GCC: https://gcc.gnu.org/releases.html +// - MSVC: https://docs.microsoft.com/en-us/visualstudio/releases/2019/release-notes-history +// https://docs.microsoft.com/en-us/visualstudio/releasenotes/vs2017-relnotes-history + +// Portable fallbacks for C++20 feature test macros: +// https://en.cppreference.com/w/cpp/feature_test +#ifndef __has_cpp_attribute +#define __has_cpp_attribute(x) 0 +#define PROTOBUF_has_cpp_attribute_DEFINED_ +#endif + +// Portable fallback for Clang's __has_feature macro: +// https://clang.llvm.org/docs/LanguageExtensions.html#has-feature-and-has-extension +#ifndef __has_feature +#define __has_feature(x) 0 +#define PROTOBUF_has_feature_DEFINED_ +#endif + +// Portable fallback for Clang's __has_warning macro: +#ifndef __has_warning +#define __has_warning(x) 0 +#define PROTOBUF_has_warning_DEFINED_ +#endif + +// Portable fallbacks for the __has_attribute macro (GCC and Clang): +// https://clang.llvm.org/docs/LanguageExtensions.html#has-attribute +// https://gcc.gnu.org/onlinedocs/cpp/_005f_005fhas_005fattribute.html +#ifndef __has_attribute +#define __has_attribute(x) 0 +#define PROTOBUF_has_attribute_DEFINED_ +#endif + +// Portable fallback for __has_builtin (GCC and Clang): +// https://clang.llvm.org/docs/LanguageExtensions.html#has-builtin +// https://gcc.gnu.org/onlinedocs/cpp/_005f_005fhas_005fbuiltin.html +#ifndef __has_builtin +#define __has_builtin(x) 0 +#define PROTOBUF_has_builtin_DEFINED_ +#endif + +// Portable check for GCC minimum version: +// https://gcc.gnu.org/onlinedocs/cpp/Common-Predefined-Macros.html +#if defined(__GNUC__) && defined(__GNUC_MINOR__) \ + && defined(__GNUC_PATCHLEVEL__) +# define PROTOBUF_GNUC_MIN(x, y) \ + (__GNUC__ > (x) || __GNUC__ == (x) && __GNUC_MINOR__ >= (y)) +#else +# define PROTOBUF_GNUC_MIN(x, y) 0 +#endif + +// Portable check for MSVC minimum version: +// https://docs.microsoft.com/en-us/cpp/preprocessor/predefined-macros +#if defined(_MSC_VER) +#define PROTOBUF_MSC_VER_MIN(x) (_MSC_VER >= x) +#else +#define PROTOBUF_MSC_VER_MIN(x) 0 +#endif + +// Portable check for minimum C++ language version: +// https://en.cppreference.com/w/cpp/preprocessor/replace +// https://docs.microsoft.com/en-us/cpp/preprocessor/predefined-macros +#if !defined(_MSVC_LANG) +#define PROTOBUF_CPLUSPLUS_MIN(x) (__cplusplus >= x) +#else +#define PROTOBUF_CPLUSPLUS_MIN(x) (_MSVC_LANG >= x) +#endif + +// Future versions of protobuf will include breaking changes to some APIs. +// This macro can be set to enable these API changes ahead of time, so that +// user code can be updated before upgrading versions of protobuf. +// #define PROTOBUF_FUTURE_BREAKING_CHANGES 1 + +#ifdef PROTOBUF_VERSION +#error PROTOBUF_VERSION was previously defined +#endif +#define PROTOBUF_VERSION 3019000 + +#ifdef PROTOBUF_MIN_HEADER_VERSION_FOR_PROTOC +#error PROTOBUF_MIN_HEADER_VERSION_FOR_PROTOC was previously defined +#endif +#define PROTOBUF_MIN_HEADER_VERSION_FOR_PROTOC 3019000 + +#ifdef PROTOBUF_MIN_PROTOC_VERSION +#error PROTOBUF_MIN_PROTOC_VERSION was previously defined +#endif +#define PROTOBUF_MIN_PROTOC_VERSION 3019000 + +#ifdef PROTOBUF_VERSION_SUFFIX +#error PROTOBUF_VERSION_SUFFIX was previously defined +#endif +#define PROTOBUF_VERSION_SUFFIX "" + +#if defined(PROTOBUF_NAMESPACE) || defined(PROTOBUF_NAMESPACE_ID) +#error PROTOBUF_NAMESPACE or PROTOBUF_NAMESPACE_ID was previously defined +#endif +#define PROTOBUF_NAMESPACE "google::protobuf" +#define PROTOBUF_NAMESPACE_ID google::protobuf +#define PROTOBUF_NAMESPACE_OPEN \ + namespace google { \ + namespace protobuf { +#define PROTOBUF_NAMESPACE_CLOSE \ + } /* namespace protobuf */ \ + } /* namespace google */ + +#ifdef PROTOBUF_ALWAYS_INLINE +#error PROTOBUF_ALWAYS_INLINE was previously defined +#endif +// For functions we want to force inline. +#if defined(PROTOBUF_NO_INLINE) +# define PROTOBUF_ALWAYS_INLINE +#elif PROTOBUF_GNUC_MIN(3, 1) +# define PROTOBUF_ALWAYS_INLINE __attribute__((always_inline)) +#elif defined(_MSC_VER) +# define PROTOBUF_ALWAYS_INLINE __forceinline +#else +# define PROTOBUF_ALWAYS_INLINE +#endif + +#ifdef PROTOBUF_NDEBUG_INLINE +#error PROTOBUF_NDEBUG_INLINE was previously defined +#endif +// Avoid excessive inlining in non-optimized builds. Without other optimizations +// the inlining is not going to provide benefits anyway and the huge resulting +// functions, especially in the proto-generated serialization functions, produce +// stack frames so large that many tests run into stack overflows (b/32192897). +#if defined(NDEBUG) || (defined(_MSC_VER) && !defined(_DEBUG)) +# define PROTOBUF_NDEBUG_INLINE PROTOBUF_ALWAYS_INLINE +#else +# define PROTOBUF_NDEBUG_INLINE +#endif + +// Note that PROTOBUF_NOINLINE is an attribute applied to functions, to prevent +// them from being inlined by the compiler. This is different from +// PROTOBUF_NO_INLINE, which is a user-supplied macro that disables forced +// inlining by PROTOBUF_(ALWAYS|NDEBUG)_INLINE. +#ifdef PROTOBUF_NOINLINE +#error PROTOBUF_NOINLINE was previously defined +#endif +#if PROTOBUF_GNUC_MIN(3, 1) +# define PROTOBUF_NOINLINE __attribute__((noinline)) +#elif defined(_MSC_VER) +// Seems to have been around since at least Visual Studio 2005 +# define PROTOBUF_NOINLINE __declspec(noinline) +#endif + +#ifdef PROTOBUF_MUSTTAIL +#error PROTOBUF_MUSTTAIL was previously defined +#endif +#ifdef PROTOBUF_TAILCALL +#error PROTOBUF_TAILCALL was previously defined +#endif +#if __has_cpp_attribute(clang::musttail) && \ + !defined(__arm__) && !defined(_ARCH_PPC) && !defined(__wasm__) +# ifndef PROTO2_OPENSOURCE +// Compilation fails on ARM32: b/195943306 +// Compilation fails on powerpc64le: b/187985113 +# endif +#define PROTOBUF_MUSTTAIL [[clang::musttail]] +#define PROTOBUF_TAILCALL true +#else +#define PROTOBUF_MUSTTAIL +#define PROTOBUF_TAILCALL false +#endif + +#ifdef PROTOBUF_EXCLUSIVE_LOCKS_REQUIRED +#error PROTOBUF_EXCLUSIVE_LOCKS_REQUIRED was previously defined +#endif +#if __has_attribute(exclusive_locks_required) +#define PROTOBUF_EXCLUSIVE_LOCKS_REQUIRED(...) \ + __attribute__((exclusive_locks_required(__VA_ARGS__))) +#else +#define PROTOBUF_EXCLUSIVE_LOCKS_REQUIRED(...) +#endif + +#ifdef PROTOBUF_NO_THREAD_SAFETY_ANALYSIS +#error PROTOBUF_NO_THREAD_SAFETY_ANALYSIS was previously defined +#endif +#if __has_attribute(no_thread_safety_analysis) +#define PROTOBUF_NO_THREAD_SAFETY_ANALYSIS \ + __attribute__((no_thread_safety_analysis)) +#else +#define PROTOBUF_NO_THREAD_SAFETY_ANALYSIS +#endif + +#ifdef PROTOBUF_GUARDED_BY +#error PROTOBUF_GUARDED_BY was previously defined +#endif +#if __has_attribute(guarded_by) +#define PROTOBUF_GUARDED_BY(x) __attribute__((guarded_by(x))) +#else +#define PROTOBUF_GUARDED_BY(x) +#endif + +#ifdef PROTOBUF_LOCKS_EXCLUDED +#error PROTOBUF_LOCKS_EXCLUDED was previously defined +#endif +#if __has_attribute(locks_excluded) +#define PROTOBUF_LOCKS_EXCLUDED(...) \ + __attribute__((locks_excluded(__VA_ARGS__))) +#else +#define PROTOBUF_LOCKS_EXCLUDED(...) +#endif + +#ifdef PROTOBUF_COLD +#error PROTOBUF_COLD was previously defined +#endif +#if __has_attribute(cold) || PROTOBUF_GNUC_MIN(4, 3) +# define PROTOBUF_COLD __attribute__((cold)) +#else +# define PROTOBUF_COLD +#endif + +#ifdef PROTOBUF_SECTION_VARIABLE +#error PROTOBUF_SECTION_VARIABLE was previously defined +#endif +#if (__has_attribute(section) || defined(__GNUC__)) && defined(__ELF__) +// Place a variable in the given ELF section. +# define PROTOBUF_SECTION_VARIABLE(x) __attribute__((section(#x))) +#else +# define PROTOBUF_SECTION_VARIABLE(x) +#endif + +#if defined(PROTOBUF_DEPRECATED) +#error PROTOBUF_DEPRECATED was previously defined +#endif +#if defined(PROTOBUF_DEPRECATED_MSG) +#error PROTOBUF_DEPRECATED_MSG was previously defined +#endif +# define PROTOBUF_DEPRECATED +# define PROTOBUF_DEPRECATED_MSG(msg) + +#if defined(PROTOBUF_DEPRECATED_ENUM) +#error PROTOBUF_DEPRECATED_ENUM was previously defined +#endif +# define PROTOBUF_DEPRECATED_ENUM + +#ifdef PROTOBUF_FUNC_ALIGN +#error PROTOBUF_FUNC_ALIGN was previously defined +#endif +#if __has_attribute(aligned) || PROTOBUF_GNUC_MIN(4, 3) +#define PROTOBUF_FUNC_ALIGN(bytes) __attribute__((aligned(bytes))) +#else +#define PROTOBUF_FUNC_ALIGN(bytes) +#endif + +#ifdef PROTOBUF_RETURNS_NONNULL +#error PROTOBUF_RETURNS_NONNULL was previously defined +#endif +#if __has_attribute(returns_nonnull) || PROTOBUF_GNUC_MIN(4, 9) +#define PROTOBUF_RETURNS_NONNULL __attribute__((returns_nonnull)) +#else +#define PROTOBUF_RETURNS_NONNULL +#endif + +#ifdef PROTOBUF_ATTRIBUTE_REINITIALIZES +#error PROTOBUF_ATTRIBUTE_REINITIALIZES was previously defined +#endif +#if __has_cpp_attribute(clang::reinitializes) +#define PROTOBUF_ATTRIBUTE_REINITIALIZES [[clang::reinitializes]] +#else +#define PROTOBUF_ATTRIBUTE_REINITIALIZES +#endif + +// The minimum library version which works with the current version of the +// headers. +#define GOOGLE_PROTOBUF_MIN_LIBRARY_VERSION 3019000 + +#ifdef PROTOBUF_RTTI +#error PROTOBUF_RTTI was previously defined +#endif +#if defined(GOOGLE_PROTOBUF_NO_RTTI) && GOOGLE_PROTOBUF_NO_RTTI +#define PROTOBUF_RTTI 0 +#elif __has_feature(cxx_rtti) +#define PROTOBUF_RTTI 1 +#elif defined(__cxx_rtti) +// https://en.cppreference.com/w/User:D41D8CD98F/feature_testing_macros#C.2B.2B98 +#define PROTOBUF_RTTI 1 +#else +#define PROTOBUF_RTTI 0 +#endif + +// Returns the offset of the given field within the given aggregate type. +// This is equivalent to the ANSI C offsetof() macro. However, according +// to the C++ standard, offsetof() only works on POD types, and GCC +// enforces this requirement with a warning. In practice, this rule is +// unnecessarily strict; there is probably no compiler or platform on +// which the offsets of the direct fields of a class are non-constant. +// Fields inherited from superclasses *can* have non-constant offsets, +// but that's not what this macro will be used for. +#ifdef PROTOBUF_FIELD_OFFSET +#error PROTOBUF_FIELD_OFFSET was previously defined +#endif +#if defined(__clang__) +// For Clang we use __builtin_offsetof() and suppress the warning, +// to avoid Control Flow Integrity and UBSan vptr sanitizers from +// crashing while trying to validate the invalid reinterpret_casts. +#define PROTOBUF_FIELD_OFFSET(TYPE, FIELD) \ + _Pragma("clang diagnostic push") \ + _Pragma("clang diagnostic ignored \"-Winvalid-offsetof\"") \ + __builtin_offsetof(TYPE, FIELD) \ + _Pragma("clang diagnostic pop") +#elif PROTOBUF_GNUC_MIN(4, 8) +#define PROTOBUF_FIELD_OFFSET(TYPE, FIELD) __builtin_offsetof(TYPE, FIELD) +#else // defined(__clang__) +// Note that we calculate relative to the pointer value 16 here since if we +// just use zero, GCC complains about dereferencing a NULL pointer. We +// choose 16 rather than some other number just in case the compiler would +// be confused by an unaligned pointer. +#define PROTOBUF_FIELD_OFFSET(TYPE, FIELD) \ + static_cast< ::arc_ui32>(reinterpret_cast<const char*>( \ + &reinterpret_cast<const TYPE*>(16)->FIELD) - \ + reinterpret_cast<const char*>(16)) +#endif + +#ifdef PROTOBUF_EXPORT +#error PROTOBUF_EXPORT was previously defined +#endif + +#if defined(PROTOBUF_USE_DLLS) && defined(_MSC_VER) +# if defined(LIBPROTOBUF_EXPORTS) +# define PROTOBUF_EXPORT __declspec(dllexport) +# define PROTOBUF_EXPORT_TEMPLATE_DECLARE +# define PROTOBUF_EXPORT_TEMPLATE_DEFINE __declspec(dllexport) +# else +# define PROTOBUF_EXPORT __declspec(dllimport) +# define PROTOBUF_EXPORT_TEMPLATE_DECLARE +# define PROTOBUF_EXPORT_TEMPLATE_DEFINE __declspec(dllimport) +# endif // defined(LIBPROTOBUF_EXPORTS) +#elif defined(PROTOBUF_USE_DLLS) && defined(LIBPROTOBUF_EXPORTS) +# define PROTOBUF_EXPORT __attribute__((visibility("default"))) +# define PROTOBUF_EXPORT_TEMPLATE_DECLARE __attribute__((visibility("default"))) +# define PROTOBUF_EXPORT_TEMPLATE_DEFINE +#else +# define PROTOBUF_EXPORT +# define PROTOBUF_EXPORT_TEMPLATE_DECLARE +# define PROTOBUF_EXPORT_TEMPLATE_DEFINE +#endif + +#ifdef PROTOC_EXPORT +#error PROTOC_EXPORT was previously defined +#endif + +#if defined(PROTOBUF_USE_DLLS) && defined(_MSC_VER) +# if defined(LIBPROTOC_EXPORTS) +# define PROTOC_EXPORT __declspec(dllexport) +# else +# define PROTOC_EXPORT __declspec(dllimport) +# endif // defined(LIBPROTOC_EXPORTS) +#elif defined(PROTOBUF_USE_DLLS) && defined(LIBPROTOBUF_EXPORTS) +# define PROTOC_EXPORT __attribute__((visibility("default"))) +#else +# define PROTOC_EXPORT +#endif + +#if defined(PROTOBUF_PREDICT_TRUE) || defined(PROTOBUF_PREDICT_FALSE) +#error PROTOBUF_PREDICT_(TRUE|FALSE) was previously defined +#endif +#if PROTOBUF_GNUC_MIN(3, 0) +# define PROTOBUF_PREDICT_TRUE(x) (__builtin_expect(false || (x), true)) +# define PROTOBUF_PREDICT_FALSE(x) (__builtin_expect(false || (x), false)) +#else +# define PROTOBUF_PREDICT_TRUE(x) (x) +# define PROTOBUF_PREDICT_FALSE(x) (x) +#endif + +#ifdef PROTOBUF_NODISCARD +#error PROTOBUF_NODISCARD was previously defined +#endif +#if __has_cpp_attribute(nodiscard) +#define PROTOBUF_NODISCARD [[nodiscard]] +#elif __has_attribute(warn_unused_result) || PROTOBUF_GNUC_MIN(4, 8) +#define PROTOBUF_NODISCARD __attribute__((warn_unused_result)) +#else +#define PROTOBUF_NODISCARD +#endif + +#ifdef PROTOBUF_FORCE_COPY_IN_RELEASE +#error PROTOBUF_FORCE_COPY_IN_RELEASE was previously defined +#endif + +#ifdef PROTOBUF_FORCE_COPY_IN_SWAP +#error PROTOBUF_FORCE_COPY_IN_SWAP was previously defined +#endif + +#ifdef PROTOBUF_FORCE_COPY_IN_MOVE +#error PROTOBUF_FORCE_COPY_IN_MOVE was previously defined +#endif + +// Force copy the default string to a string field so that non-optimized builds +// have harder-to-rely-on address stability. +#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING +#error PROTOBUF_FORCE_COPY_DEFAULT_STRING was previously defined +#endif + +#ifdef PROTOBUF_FALLTHROUGH_INTENDED +#error PROTOBUF_FALLTHROUGH_INTENDED was previously defined +#endif +#if __has_cpp_attribute(fallthrough) +#define PROTOBUF_FALLTHROUGH_INTENDED [[fallthrough]] +#elif __has_feature(cxx_attributes) && __has_warning("-Wimplicit-fallthrough") +#define PROTOBUF_FALLTHROUGH_INTENDED [[clang::fallthrough]] +#elif PROTOBUF_GNUC_MIN(7, 0) +#define PROTOBUF_FALLTHROUGH_INTENDED [[gnu::fallthrough]] +#else +#define PROTOBUF_FALLTHROUGH_INTENDED +#endif + +// PROTOBUF_ASSUME(pred) tells the compiler that it can assume pred is true. To +// be safe, we also validate the assumption with a GOOGLE_DCHECK in unoptimized +// builds. The macro does not do anything useful if the compiler does not +// support __builtin_assume. +#ifdef PROTOBUF_ASSUME +#error PROTOBUF_ASSUME was previously defined +#endif +#if __has_builtin(__builtin_assume) +#define PROTOBUF_ASSUME(pred) \ + GOOGLE_DCHECK(pred); \ + __builtin_assume(pred) +#else +#define PROTOBUF_ASSUME(pred) GOOGLE_DCHECK(pred) +#endif + +// Specify memory alignment for structs, classes, etc. +// Use like: +// class PROTOBUF_ALIGNAS(16) MyClass { ... } +// PROTOBUF_ALIGNAS(16) int array[4]; +// +// In most places you can use the C++11 keyword "alignas", which is preferred. +// +// But compilers have trouble mixing __attribute__((...)) syntax with +// alignas(...) syntax. +// +// Doesn't work in clang or gcc: +// struct alignas(16) __attribute__((packed)) S { char c; }; +// Works in clang but not gcc: +// struct __attribute__((packed)) alignas(16) S2 { char c; }; +// Works in clang and gcc: +// struct alignas(16) S3 { char c; } __attribute__((packed)); +// +// There are also some attributes that must be specified *before* a class +// definition: visibility (used for exporting functions/classes) is one of +// these attributes. This means that it is not possible to use alignas() with a +// class that is marked as exported. +#ifdef PROTOBUF_ALIGNAS +#error PROTOBUF_ALIGNAS was previously defined +#endif +#if defined(_MSC_VER) +#define PROTOBUF_ALIGNAS(byte_alignment) __declspec(align(byte_alignment)) +#elif PROTOBUF_GNUC_MIN(3, 0) +#define PROTOBUF_ALIGNAS(byte_alignment) \ + __attribute__((aligned(byte_alignment))) +#else +#define PROTOBUF_ALIGNAS(byte_alignment) alignas(byte_alignment) +#endif + +#ifdef PROTOBUF_FINAL +#error PROTOBUF_FINAL was previously defined +#endif +#define PROTOBUF_FINAL final + +#ifdef PROTOBUF_THREAD_LOCAL +#error PROTOBUF_THREAD_LOCAL was previously defined +#endif +#if defined(_MSC_VER) +#define PROTOBUF_THREAD_LOCAL __declspec(thread) +#else +#define PROTOBUF_THREAD_LOCAL __thread +#endif + +// For enabling message owned arena, one major blocker is semantic change from +// moving to copying when there is ownership transfer (e.g., move ctor, swap, +// set allocated, release). This change not only causes performance regression +// but also breaks users code (e.g., dangling reference). For top-level +// messages, since it owns the arena, we can mitigate the issue by transferring +// ownership of arena. However, we cannot do that for nested messages. In order +// to tell how many usages of nested messages affected by message owned arena, +// we need to simulate the arena ownership. +// This experiment is purely for the purpose of gathering data. All code guarded +// by this flag is supposed to be removed after this experiment. +#define PROTOBUF_MESSAGE_OWNED_ARENA_EXPERIMENT +#ifdef PROTOBUF_CONSTINIT +#error PROTOBUF_CONSTINIT was previously defined +#endif +#if defined(__cpp_constinit) && !PROTOBUF_GNUC_MIN(3, 0) && !defined(_MSC_VER) +// Our use of constinit does not yet work with GCC: +// https://github.com/protocolbuffers/protobuf/issues/8310 +// Does not work yet with Visual Studio 2019 Update 16.10 +#define PROTOBUF_CONSTINIT constinit +#elif !defined(_MSC_VER) && \ + __has_cpp_attribute(clang::require_constant_initialization) +#define PROTOBUF_CONSTINIT [[clang::require_constant_initialization]] +#else +#define PROTOBUF_CONSTINIT +#endif + +// Some globals with an empty non-trivial destructor are annotated with +// no_destroy for performance reasons. It reduces the cost of these globals in +// non-opt mode and under sanitizers. +#ifdef PROTOBUF_ATTRIBUTE_NO_DESTROY +#error PROTOBUF_ATTRIBUTE_NO_DESTROY was previously defined +#endif +#if __has_cpp_attribute(clang::no_destroy) +#define PROTOBUF_ATTRIBUTE_NO_DESTROY [[clang::no_destroy]] +#else +#define PROTOBUF_ATTRIBUTE_NO_DESTROY +#endif + +// Protobuf extensions and reflection require registration of the protos linked +// in the binary. Not until everything is registered does the runtime have a +// complete view on all protos. When code is using reflection or extensions +// in between registration calls this can lead to surprising behavior. By +// having the registration run first we mitigate this scenario. +// Highest priority is 101. We use 102 to allow code that really wants to +// higher priority to still beat us. +#ifdef PROTOBUF_ATTRIBUTE_INIT_PRIORITY +#error PROTOBUF_ATTRIBUTE_INIT_PRIORITY was previously defined +#endif +#if PROTOBUF_GNUC_MIN(3, 0) && (!defined(__APPLE__) || defined(__clang__)) && !((defined(sun) || defined(__sun)) && (defined(__SVR4) || defined(__svr4__))) +#define PROTOBUF_ATTRIBUTE_INIT_PRIORITY __attribute__((init_priority((102)))) +#else +#define PROTOBUF_ATTRIBUTE_INIT_PRIORITY +#endif + +#ifdef PROTOBUF_PRAGMA_INIT_SEG +#error PROTOBUF_PRAGMA_INIT_SEG was previously defined +#endif +#if _MSC_VER +#define PROTOBUF_PRAGMA_INIT_SEG __pragma(init_seg(lib)) +#else +#define PROTOBUF_PRAGMA_INIT_SEG +#endif + +#ifdef PROTOBUF_ATTRIBUTE_WEAK +#error PROTOBUF_ATTRIBUTE_WEAK was previously defined +#endif +#if __has_attribute(weak) && \ + !defined(__APPLE__) && \ + (!defined(_WIN32) || __clang_major__ < 9) && \ + !defined(__MINGW32__) +#define PROTOBUF_ATTRIBUTE_WEAK __attribute__((weak)) +#define PROTOBUF_HAVE_ATTRIBUTE_WEAK 1 +#else +#define PROTOBUF_ATTRIBUTE_WEAK +#define PROTOBUF_HAVE_ATTRIBUTE_WEAK 0 +#endif + +// Macros to detect sanitizers. +#ifdef PROTOBUF_ASAN +#error PROTOBUF_ASAN was previously defined +#endif +#ifdef PROTOBUF_MSAN +#error PROTOBUF_MSAN was previously defined +#endif +#ifdef PROTOBUF_TSAN +#error PROTOBUF_TSAN was previously defined +#endif +#if defined(__clang__) +# if __has_feature(address_sanitizer) +# define PROTOBUF_ASAN 1 +# endif +# if __has_feature(thread_sanitizer) +# define PROTOBUF_TSAN 1 +# endif +# if __has_feature(memory_sanitizer) +# define PROTOBUF_MSAN 1 +# endif +#elif PROTOBUF_GNUC_MIN(3, 0) +// Double-guard is needed for -Wundef: +# ifdef __SANITIZE_ADDRESS__ +# if __SANITIZE_ADDRESS__ +# define PROTOBUF_ASAN 1 +# endif +# endif +# ifdef __SANITIZE_THREAD__ +# if __SANITIZE_THREAD__ +# define PROTOBUF_TSAN 1 +# endif +# endif +#endif + +// Tail call table-driven parsing can be enabled by defining +// PROTOBUF_EXPERIMENTAL_USE_TAIL_CALL_TABLE_PARSER at compilation time. Note +// that this macro is for small-scale testing only, and is not supported. +#ifdef PROTOBUF_TAIL_CALL_TABLE_PARSER_ENABLED +#error PROTOBUF_TAIL_CALL_TABLE_PARSER_ENABLED was previously declared +#endif +#if defined(PROTOBUF_EXPERIMENTAL_USE_TAIL_CALL_TABLE_PARSER) +#define PROTOBUF_TAIL_CALL_TABLE_PARSER_ENABLED 1 +// Selectively use static member functions instead of templates: +#ifndef PROTOBUF_TC_STATIC_PARSE_SINGULAR1 +# define PROTOBUF_TC_STATIC_PARSE_SINGULAR1 1 +#endif +#ifndef PROTOBUF_TC_STATIC_PARSE_SINGULAR2 +# define PROTOBUF_TC_STATIC_PARSE_SINGULAR2 0 +#endif +#ifndef PROTOBUF_TC_STATIC_PARSE_REPEATED1 +# define PROTOBUF_TC_STATIC_PARSE_REPEATED1 0 +#endif +#ifndef PROTOBUF_TC_STATIC_PARSE_REPEATED2 +# define PROTOBUF_TC_STATIC_PARSE_REPEATED2 0 +#endif +#endif + +#define PROTOBUF_TC_PARAM_DECL \ + ::google::protobuf::MessageLite *msg, const char *ptr, \ + ::google::protobuf::internal::ParseContext *ctx, \ + const ::google::protobuf::internal::TcParseTableBase *table, \ + arc_ui64 hasbits, ::google::protobuf::internal::TcFieldData data + +#ifdef PROTOBUF_UNUSED +#error PROTOBUF_UNUSED was previously defined +#endif +#if __has_cpp_attribute(maybe_unused) || \ + (PROTOBUF_MSC_VER_MIN(1911) && PROTOBUF_CPLUSPLUS_MIN(201703L)) +#define PROTOBUF_UNUSED [[maybe_unused]] +#elif __has_attribute(unused) || PROTOBUF_GNUC_MIN(3, 0) +#define PROTOBUF_UNUSED __attribute__((__unused__)) +#else +#define PROTOBUF_UNUSED +#endif + +// Windows declares several inconvenient macro names. We #undef them and then +// restore them in port_undef.inc. +#ifdef _MSC_VER +#pragma push_macro("CREATE_NEW") +#undef CREATE_NEW +#pragma push_macro("DELETE") +#undef DELETE +#pragma push_macro("DOUBLE_CLICK") +#undef DOUBLE_CLICK +#pragma push_macro("ERROR") +#undef ERROR +#pragma push_macro("ERROR_BUSY") +#undef ERROR_BUSY +#pragma push_macro("ERROR_INSTALL_FAILED") +#undef ERROR_INSTALL_FAILED +#pragma push_macro("ERROR_NOT_FOUND") +#undef ERROR_NOT_FOUND +#pragma push_macro("GetMessage") +#undef GetMessage +#pragma push_macro("GetObject") +#undef GetObject +#pragma push_macro("IGNORE") +#undef IGNORE +#pragma push_macro("IN") +#undef IN +#pragma push_macro("INPUT_KEYBOARD") +#undef INPUT_KEYBOARD +#pragma push_macro("NO_ERROR") +#undef NO_ERROR +#pragma push_macro("OUT") +#undef OUT +#pragma push_macro("OPTIONAL") +#undef OPTIONAL +#pragma push_macro("min") +#undef min +#pragma push_macro("max") +#undef max +#pragma push_macro("NEAR") +#undef NEAR +#pragma push_macro("NO_DATA") +#undef NO_DATA +#pragma push_macro("REASON_UNKNOWN") +#undef REASON_UNKNOWN +#pragma push_macro("SERVICE_DISABLED") +#undef SERVICE_DISABLED +#pragma push_macro("SEVERITY_ERROR") +#undef SEVERITY_ERROR +#pragma push_macro("STRICT") +#undef STRICT +#pragma push_macro("timezone") +#undef timezone +#endif // _MSC_VER + +#if defined(__clang__) || PROTOBUF_GNUC_MIN(3, 0) || defined(_MSC_VER) +// Don't let Objective-C Macros interfere with proto identifiers with the same +// name. +#pragma push_macro("DEBUG") +#undef DEBUG +#endif // defined(__clang__) || PROTOBUF_GNUC_MIN(3, 0) || defined(_MSC_VER) + +#if defined(__clang__) +#pragma clang diagnostic push +// TODO(gerbens) ideally we cleanup the code. But a cursory try shows many +// violations. So let's ignore for now. +#pragma clang diagnostic ignored "-Wshorten-64-to-32" +#elif PROTOBUF_GNUC_MIN(3, 0) +// GCC does not allow disabling diagnostics within an expression: +// https://gcc.gnu.org/bugzilla/show_bug.cgi?id=60875, so we disable this one +// globally even though it's only used for PROTOBUF_FIELD_OFFSET. +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Winvalid-offsetof" +#endif + +// Silence some MSVC warnings in all our code. +#if _MSC_VER +#pragma warning(push) +// For non-trivial unions +#pragma warning(disable : 4582) +#pragma warning(disable : 4583) +// For init_seg(lib) +#pragma warning(disable : 4073) +// To silence the fact that we will pop this push from another file +#pragma warning(disable : 5031) +// Conditional expression is constant +#pragma warning(disable: 4127) +// decimal digit terminates octal escape sequence +#pragma warning(disable: 4125) +#endif + +// We don't want code outside port_def doing complex testing, so +// remove our portable condition test macros to nudge folks away from +// using it themselves. +#ifdef PROTOBUF_has_cpp_attribute_DEFINED_ +# undef __has_cpp_attribute +# undef PROTOBUF_has_cpp_attribute_DEFINED_ +#endif +#ifdef PROTOBUF_has_feature_DEFINED_ +# undef __has_feature +# undef PROTOBUF_has_feature_DEFINED_ +#endif +#ifdef PROTOBUF_has_warning_DEFINED_ +# undef __has_warning +# undef PROTOBUF_has_warning_DEFINED_ +#endif +#ifdef PROTOBUF_has_attribute_DEFINED_ +# undef __has_attribute +# undef PROTOBUF_has_attribute_DEFINED_ +#endif +#ifdef PROTOBUF_has_builtin_DEFINED_ +# undef __has_builtin +# undef PROTOBUF_has_builtin_DEFINED_ +#endif + +#if defined(__clang__) && defined(_WIN32) +#undef PROTOBUF_MUSTTAIL +#undef PROTOBUF_TAILCALL +#define PROTOBUF_MUSTTAIL +#define PROTOBUF_TAILCALL false +#endif diff --git a/contrib/libs/protobuf_old/src/google/protobuf/port_undef.inc b/contrib/libs/protobuf_old/src/google/protobuf/port_undef.inc new file mode 100644 index 0000000000..c410730ef1 --- /dev/null +++ b/contrib/libs/protobuf_old/src/google/protobuf/port_undef.inc @@ -0,0 +1,146 @@ +// 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. + +// #undefs all macros defined in port_def.inc. See comments in port_def.inc +// for more info. + +#ifndef PROTOBUF_NAMESPACE +#error "port_undef.inc must be included after port_def.inc" +#endif +#undef PROTOBUF_GNUC_MIN +#undef PROTOBUF_MSC_VER_MIN +#undef PROTOBUF_CPLUSPLUS_MIN +#undef PROTOBUF_NAMESPACE +#undef PROTOBUF_NAMESPACE_ID +#undef PROTOBUF_ALWAYS_INLINE +#undef PROTOBUF_NDEBUG_INLINE +#undef PROTOBUF_MUSTTAIL +#undef PROTOBUF_TAILCALL +#undef PROTOBUF_COLD +#undef PROTOBUF_NOINLINE +#undef PROTOBUF_SECTION_VARIABLE +#undef PROTOBUF_DEPRECATED +#undef PROTOBUF_DEPRECATED_ENUM +#undef PROTOBUF_DEPRECATED_MSG +#undef PROTOBUF_FUNC_ALIGN +#undef PROTOBUF_RETURNS_NONNULL +#undef PROTOBUF_ATTRIBUTE_REINITIALIZES +#undef PROTOBUF_RTTI +#undef PROTOBUF_VERSION +#undef PROTOBUF_VERSION_SUFFIX +#undef PROTOBUF_FIELD_OFFSET +#undef PROTOBUF_MIN_HEADER_VERSION_FOR_PROTOC +#undef PROTOBUF_MIN_PROTOC_VERSION +#undef PROTOBUF_PREDICT_TRUE +#undef PROTOBUF_PREDICT_FALSE +#undef PROTOBUF_FALLTHROUGH_INTENDED +#undef PROTOBUF_EXPORT +#undef PROTOC_EXPORT +#undef PROTOBUF_NODISCARD +#undef PROTOBUF_FORCE_COPY_IN_RELEASE +#undef PROTOBUF_FORCE_COPY_IN_SWAP +#undef PROTOBUF_FORCE_COPY_IN_MOVE +#undef PROTOBUF_FORCE_COPY_DEFAULT_STRING +#undef PROTOBUF_NAMESPACE_OPEN +#undef PROTOBUF_NAMESPACE_CLOSE +#undef PROTOBUF_UNUSED +#undef PROTOBUF_ASSUME +#undef PROTOBUF_EXPORT_TEMPLATE_DECLARE +#undef PROTOBUF_EXPORT_TEMPLATE_DEFINE +#undef PROTOBUF_ALIGNAS +#undef PROTOBUF_FINAL +#undef PROTOBUF_THREAD_LOCAL +#undef PROTOBUF_MESSAGE_OWNED_ARENA_EXPERIMENT +#undef PROTOBUF_CONSTINIT +#undef PROTOBUF_ATTRIBUTE_WEAK +#undef PROTOBUF_HAVE_ATTRIBUTE_WEAK +#undef PROTOBUF_ATTRIBUTE_NO_DESTROY +#undef PROTOBUF_ATTRIBUTE_INIT_PRIORITY +#undef PROTOBUF_PRAGMA_INIT_SEG +#undef PROTOBUF_ASAN +#undef PROTOBUF_MSAN +#undef PROTOBUF_TSAN +#undef PROTOBUF_TAIL_CALL_TABLE_PARSER_ENABLED +#undef PROTOBUF_TC_STATIC_PARSE_SINGULAR1 +#undef PROTOBUF_TC_STATIC_PARSE_SINGULAR2 +#undef PROTOBUF_TC_STATIC_PARSE_REPEATED1 +#undef PROTOBUF_TC_STATIC_PARSE_REPEATED2 +#undef PROTOBUF_TC_PARAM_DECL +#undef PROTOBUF_EXCLUSIVE_LOCKS_REQUIRED +#undef PROTOBUF_LOCKS_EXCLUDED +#undef PROTOBUF_NO_THREAD_SAFETY_ANALYSIS +#undef PROTOBUF_GUARDED_BY + +#ifdef PROTOBUF_FUTURE_BREAKING_CHANGES +#undef PROTOBUF_FUTURE_BREAKING_CHANGES +#endif + +// Restore macro that may have been #undef'd in port_def.inc. +#ifdef _MSC_VER +#pragma pop_macro("CREATE_NEW") +#pragma pop_macro("DELETE") +#pragma pop_macro("DOUBLE_CLICK") +#pragma pop_macro("ERROR") +#pragma pop_macro("ERROR_BUSY") +#pragma pop_macro("ERROR_INSTALL_FAILED") +#pragma pop_macro("ERROR_NOT_FOUND") +#pragma pop_macro("GetMessage") +#pragma pop_macro("GetObject") +#pragma pop_macro("IGNORE") +#pragma pop_macro("IN") +#pragma pop_macro("INPUT_KEYBOARD") +#pragma pop_macro("OUT") +#pragma pop_macro("OPTIONAL") +#pragma pop_macro("min") +#pragma pop_macro("max") +#pragma pop_macro("NEAR") +#pragma pop_macro("NO_DATA") +#pragma pop_macro("NO_ERROR") +#pragma pop_macro("REASON_UNKNOWN") +#pragma pop_macro("SERVICE_DISABLED") +#pragma pop_macro("SEVERITY_ERROR") +#pragma pop_macro("STRICT") +#pragma pop_macro("timezone") +#endif + +#if defined(__clang__) || defined(__GNUC__) || defined(_MSC_VER) +#pragma pop_macro("DEBUG") +#endif // defined(__clang__) || defined(__GNUC__) || defined(_MSC_VER) + +#if defined(__clang__) +#pragma clang diagnostic pop +#elif defined(__GNUC__) +#pragma GCC diagnostic pop +#endif + +// Pop the warning(push) from port_def.inc +#if _MSC_VER +#pragma warning(pop) +#endif diff --git a/contrib/libs/protobuf_old/src/google/protobuf/reflection.h b/contrib/libs/protobuf_old/src/google/protobuf/reflection.h new file mode 100644 index 0000000000..859724aab2 --- /dev/null +++ b/contrib/libs/protobuf_old/src/google/protobuf/reflection.h @@ -0,0 +1,568 @@ +// 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 header defines the RepeatedFieldRef class template used to access +// repeated fields with protobuf reflection API. +#ifndef GOOGLE_PROTOBUF_REFLECTION_H__ +#define GOOGLE_PROTOBUF_REFLECTION_H__ + +#include <memory> + +#include <google/protobuf/message.h> +#include <google/protobuf/generated_enum_util.h> + +#ifdef SWIG +#error "You cannot SWIG proto headers" +#endif + +#include <google/protobuf/port_def.inc> + +namespace google { +namespace protobuf { +namespace internal { +template <typename T, typename Enable = void> +struct RefTypeTraits; +} // namespace internal + +template <typename T> +RepeatedFieldRef<T> Reflection::GetRepeatedFieldRef( + const Message& message, const FieldDescriptor* field) const { + return RepeatedFieldRef<T>(message, field); +} + +template <typename T> +MutableRepeatedFieldRef<T> Reflection::GetMutableRepeatedFieldRef( + Message* message, const FieldDescriptor* field) const { + return MutableRepeatedFieldRef<T>(message, field); +} + +// RepeatedFieldRef definition for non-message types. +template <typename T> +class RepeatedFieldRef< + T, typename std::enable_if<!std::is_base_of<Message, T>::value>::type> { + typedef typename internal::RefTypeTraits<T>::iterator IteratorType; + typedef typename internal::RefTypeTraits<T>::AccessorType AccessorType; + + public: + bool empty() const { return accessor_->IsEmpty(data_); } + int size() const { return accessor_->Size(data_); } + T Get(int index) const { return accessor_->template Get<T>(data_, index); } + + typedef IteratorType iterator; + typedef IteratorType const_iterator; + typedef T value_type; + typedef T& reference; + typedef const T& const_reference; + typedef int size_type; + typedef ptrdiff_t difference_type; + + iterator begin() const { return iterator(data_, accessor_, true); } + iterator end() const { return iterator(data_, accessor_, false); } + + private: + friend class Reflection; + RepeatedFieldRef(const Message& message, const FieldDescriptor* field) { + const Reflection* reflection = message.GetReflection(); + data_ = reflection->RepeatedFieldData(const_cast<Message*>(&message), field, + internal::RefTypeTraits<T>::cpp_type, + nullptr); + accessor_ = reflection->RepeatedFieldAccessor(field); + } + + const void* data_; + const AccessorType* accessor_; +}; + +// MutableRepeatedFieldRef definition for non-message types. +template <typename T> +class MutableRepeatedFieldRef< + T, typename std::enable_if<!std::is_base_of<Message, T>::value>::type> { + typedef typename internal::RefTypeTraits<T>::AccessorType AccessorType; + + public: + bool empty() const { return accessor_->IsEmpty(data_); } + int size() const { return accessor_->Size(data_); } + T Get(int index) const { return accessor_->template Get<T>(data_, index); } + + void Set(int index, const T& value) const { + accessor_->template Set<T>(data_, index, value); + } + void Add(const T& value) const { accessor_->template Add<T>(data_, value); } + void RemoveLast() const { accessor_->RemoveLast(data_); } + void SwapElements(int index1, int index2) const { + accessor_->SwapElements(data_, index1, index2); + } + void Clear() const { accessor_->Clear(data_); } + + void Swap(const MutableRepeatedFieldRef& other) const { + accessor_->Swap(data_, other.accessor_, other.data_); + } + + template <typename Container> + void MergeFrom(const Container& container) const { + typedef typename Container::const_iterator Iterator; + for (Iterator it = container.begin(); it != container.end(); ++it) { + Add(*it); + } + } + template <typename Container> + void CopyFrom(const Container& container) const { + Clear(); + MergeFrom(container); + } + + private: + friend class Reflection; + MutableRepeatedFieldRef(Message* message, const FieldDescriptor* field) { + const Reflection* reflection = message->GetReflection(); + data_ = reflection->RepeatedFieldData( + message, field, internal::RefTypeTraits<T>::cpp_type, nullptr); + accessor_ = reflection->RepeatedFieldAccessor(field); + } + + void* data_; + const AccessorType* accessor_; +}; + +// RepeatedFieldRef definition for message types. +template <typename T> +class RepeatedFieldRef< + T, typename std::enable_if<std::is_base_of<Message, T>::value>::type> { + typedef typename internal::RefTypeTraits<T>::iterator IteratorType; + typedef typename internal::RefTypeTraits<T>::AccessorType AccessorType; + + public: + bool empty() const { return accessor_->IsEmpty(data_); } + int size() const { return accessor_->Size(data_); } + // This method returns a reference to the underlying message object if it + // exists. If a message object doesn't exist (e.g., data stored in serialized + // form), scratch_space will be filled with the data and a reference to it + // will be returned. + // + // Example: + // RepeatedFieldRef<Message> h = ... + // unique_ptr<Message> scratch_space(h.NewMessage()); + // const Message& item = h.Get(index, scratch_space.get()); + const T& Get(int index, T* scratch_space) const { + return *static_cast<const T*>(accessor_->Get(data_, index, scratch_space)); + } + // Create a new message of the same type as the messages stored in this + // repeated field. Caller takes ownership of the returned object. + T* NewMessage() const { return static_cast<T*>(default_instance_->New()); } + + typedef IteratorType iterator; + typedef IteratorType const_iterator; + typedef T value_type; + typedef T& reference; + typedef const T& const_reference; + typedef int size_type; + typedef ptrdiff_t difference_type; + + iterator begin() const { + return iterator(data_, accessor_, true, NewMessage()); + } + iterator end() const { + // The end iterator must not be dereferenced, no need for scratch space. + return iterator(data_, accessor_, false, nullptr); + } + + private: + friend class Reflection; + RepeatedFieldRef(const Message& message, const FieldDescriptor* field) { + const Reflection* reflection = message.GetReflection(); + data_ = reflection->RepeatedFieldData( + const_cast<Message*>(&message), field, + internal::RefTypeTraits<T>::cpp_type, + internal::RefTypeTraits<T>::GetMessageFieldDescriptor()); + accessor_ = reflection->RepeatedFieldAccessor(field); + default_instance_ = + reflection->GetMessageFactory()->GetPrototype(field->message_type()); + } + + const void* data_; + const AccessorType* accessor_; + const Message* default_instance_; +}; + +// MutableRepeatedFieldRef definition for message types. +template <typename T> +class MutableRepeatedFieldRef< + T, typename std::enable_if<std::is_base_of<Message, T>::value>::type> { + typedef typename internal::RefTypeTraits<T>::AccessorType AccessorType; + + public: + bool empty() const { return accessor_->IsEmpty(data_); } + int size() const { return accessor_->Size(data_); } + // See comments for RepeatedFieldRef<Message>::Get() + const T& Get(int index, T* scratch_space) const { + return *static_cast<const T*>(accessor_->Get(data_, index, scratch_space)); + } + // Create a new message of the same type as the messages stored in this + // repeated field. Caller takes ownership of the returned object. + T* NewMessage() const { return static_cast<T*>(default_instance_->New()); } + + void Set(int index, const T& value) const { + accessor_->Set(data_, index, &value); + } + void Add(const T& value) const { accessor_->Add(data_, &value); } + void RemoveLast() const { accessor_->RemoveLast(data_); } + void SwapElements(int index1, int index2) const { + accessor_->SwapElements(data_, index1, index2); + } + void Clear() const { accessor_->Clear(data_); } + + void Swap(const MutableRepeatedFieldRef& other) const { + accessor_->Swap(data_, other.accessor_, other.data_); + } + + template <typename Container> + void MergeFrom(const Container& container) const { + typedef typename Container::const_iterator Iterator; + for (Iterator it = container.begin(); it != container.end(); ++it) { + Add(*it); + } + } + template <typename Container> + void CopyFrom(const Container& container) const { + Clear(); + MergeFrom(container); + } + + private: + friend class Reflection; + MutableRepeatedFieldRef(Message* message, const FieldDescriptor* field) { + const Reflection* reflection = message->GetReflection(); + data_ = reflection->RepeatedFieldData( + message, field, internal::RefTypeTraits<T>::cpp_type, + internal::RefTypeTraits<T>::GetMessageFieldDescriptor()); + accessor_ = reflection->RepeatedFieldAccessor(field); + default_instance_ = + reflection->GetMessageFactory()->GetPrototype(field->message_type()); + } + + void* data_; + const AccessorType* accessor_; + const Message* default_instance_; +}; + +namespace internal { +// Interfaces used to implement reflection RepeatedFieldRef API. +// Reflection::GetRepeatedAccessor() should return a pointer to an singleton +// object that implements the below interface. +// +// This interface passes/returns values using void pointers. The actual type +// of the value depends on the field's cpp_type. Following is a mapping from +// cpp_type to the type that should be used in this interface: +// +// field->cpp_type() T Actual type of void* +// CPPTYPE_INT32 arc_i32 arc_i32 +// CPPTYPE_UINT32 arc_ui32 arc_ui32 +// CPPTYPE_INT64 arc_i64 arc_i64 +// CPPTYPE_UINT64 arc_ui64 arc_ui64 +// CPPTYPE_DOUBLE double double +// CPPTYPE_FLOAT float float +// CPPTYPE_BOOL bool bool +// CPPTYPE_ENUM generated enum type arc_i32 +// CPPTYPE_STRING string TProtoStringType +// CPPTYPE_MESSAGE generated message type google::protobuf::Message +// or google::protobuf::Message +// +// Note that for enums we use arc_i32 in the interface. +// +// You can map from T to the actual type using RefTypeTraits: +// typedef RefTypeTraits<T>::AccessorValueType ActualType; +class PROTOBUF_EXPORT RepeatedFieldAccessor { + public: + // Typedefs for clarity. + typedef void Field; + typedef void Value; + typedef void Iterator; + + virtual bool IsEmpty(const Field* data) const = 0; + virtual int Size(const Field* data) const = 0; + // Depends on the underlying representation of the repeated field, this + // method can return a pointer to the underlying object if such an object + // exists, or fill the data into scratch_space and return scratch_space. + // Callers of this method must ensure scratch_space is a valid pointer + // to a mutable object of the correct type. + virtual const Value* Get(const Field* data, int index, + Value* scratch_space) const = 0; + + virtual void Clear(Field* data) const = 0; + virtual void Set(Field* data, int index, const Value* value) const = 0; + virtual void Add(Field* data, const Value* value) const = 0; + virtual void RemoveLast(Field* data) const = 0; + virtual void SwapElements(Field* data, int index1, int index2) const = 0; + virtual void Swap(Field* data, const RepeatedFieldAccessor* other_mutator, + Field* other_data) const = 0; + + // Create an iterator that points at the beginning of the repeated field. + virtual Iterator* BeginIterator(const Field* data) const = 0; + // Create an iterator that points at the end of the repeated field. + virtual Iterator* EndIterator(const Field* data) const = 0; + // Make a copy of an iterator and return the new copy. + virtual Iterator* CopyIterator(const Field* data, + const Iterator* iterator) const = 0; + // Move an iterator to point to the next element. + virtual Iterator* AdvanceIterator(const Field* data, + Iterator* iterator) const = 0; + // Compare whether two iterators point to the same element. + virtual bool EqualsIterator(const Field* data, const Iterator* a, + const Iterator* b) const = 0; + // Delete an iterator created by BeginIterator(), EndIterator() and + // CopyIterator(). + virtual void DeleteIterator(const Field* data, Iterator* iterator) const = 0; + // Like Get() but for iterators. + virtual const Value* GetIteratorValue(const Field* data, + const Iterator* iterator, + Value* scratch_space) const = 0; + + // Templated methods that make using this interface easier for non-message + // types. + template <typename T> + T Get(const Field* data, int index) const { + typedef typename RefTypeTraits<T>::AccessorValueType ActualType; + ActualType scratch_space; + return static_cast<T>(*reinterpret_cast<const ActualType*>( + Get(data, index, static_cast<Value*>(&scratch_space)))); + } + + template <typename T, typename ValueType> + void Set(Field* data, int index, const ValueType& value) const { + typedef typename RefTypeTraits<T>::AccessorValueType ActualType; + // In this RepeatedFieldAccessor interface we pass/return data using + // raw pointers. Type of the data these raw pointers point to should + // be ActualType. Here we have a ValueType object and want a ActualType + // pointer. We can't cast a ValueType pointer to an ActualType pointer + // directly because their type might be different (for enums ValueType + // may be a generated enum type while ActualType is arc_i32). To be safe + // we make a copy to get a temporary ActualType object and use it. + ActualType tmp = static_cast<ActualType>(value); + Set(data, index, static_cast<const Value*>(&tmp)); + } + + template <typename T, typename ValueType> + void Add(Field* data, const ValueType& value) const { + typedef typename RefTypeTraits<T>::AccessorValueType ActualType; + // In this RepeatedFieldAccessor interface we pass/return data using + // raw pointers. Type of the data these raw pointers point to should + // be ActualType. Here we have a ValueType object and want a ActualType + // pointer. We can't cast a ValueType pointer to an ActualType pointer + // directly because their type might be different (for enums ValueType + // may be a generated enum type while ActualType is arc_i32). To be safe + // we make a copy to get a temporary ActualType object and use it. + ActualType tmp = static_cast<ActualType>(value); + Add(data, static_cast<const Value*>(&tmp)); + } + + protected: + // We want the destructor to be completely trivial as to allow it to be + // a function local static. Hence we make it non-virtual and protected, + // this class only live as part of a global singleton and should not be + // deleted. + ~RepeatedFieldAccessor() = default; +}; + +// Implement (Mutable)RepeatedFieldRef::iterator +template <typename T> +class RepeatedFieldRefIterator { + typedef typename RefTypeTraits<T>::AccessorValueType AccessorValueType; + typedef typename RefTypeTraits<T>::IteratorValueType IteratorValueType; + typedef typename RefTypeTraits<T>::IteratorPointerType IteratorPointerType; + + public: + using iterator_category = std::forward_iterator_tag; + using value_type = T; + using pointer = T*; + using reference = T&; + using difference_type = std::ptrdiff_t; + + // Constructor for non-message fields. + RepeatedFieldRefIterator(const void* data, + const RepeatedFieldAccessor* accessor, bool begin) + : data_(data), + accessor_(accessor), + iterator_(begin ? accessor->BeginIterator(data) + : accessor->EndIterator(data)), + // The end iterator must not be dereferenced, no need for scratch space. + scratch_space_(begin ? new AccessorValueType : nullptr) {} + // Constructor for message fields. + RepeatedFieldRefIterator(const void* data, + const RepeatedFieldAccessor* accessor, bool begin, + AccessorValueType* scratch_space) + : data_(data), + accessor_(accessor), + iterator_(begin ? accessor->BeginIterator(data) + : accessor->EndIterator(data)), + scratch_space_(scratch_space) {} + ~RepeatedFieldRefIterator() { accessor_->DeleteIterator(data_, iterator_); } + RepeatedFieldRefIterator operator++(int) { + RepeatedFieldRefIterator tmp(*this); + iterator_ = accessor_->AdvanceIterator(data_, iterator_); + return tmp; + } + RepeatedFieldRefIterator& operator++() { + iterator_ = accessor_->AdvanceIterator(data_, iterator_); + return *this; + } + IteratorValueType operator*() const { + return static_cast<IteratorValueType>( + *static_cast<const AccessorValueType*>(accessor_->GetIteratorValue( + data_, iterator_, scratch_space_.get()))); + } + IteratorPointerType operator->() const { + return static_cast<IteratorPointerType>( + accessor_->GetIteratorValue(data_, iterator_, scratch_space_.get())); + } + bool operator!=(const RepeatedFieldRefIterator& other) const { + assert(data_ == other.data_); + assert(accessor_ == other.accessor_); + return !accessor_->EqualsIterator(data_, iterator_, other.iterator_); + } + bool operator==(const RepeatedFieldRefIterator& other) const { + return !this->operator!=(other); + } + + RepeatedFieldRefIterator(const RepeatedFieldRefIterator& other) + : data_(other.data_), + accessor_(other.accessor_), + iterator_(accessor_->CopyIterator(data_, other.iterator_)) {} + RepeatedFieldRefIterator& operator=(const RepeatedFieldRefIterator& other) { + if (this != &other) { + accessor_->DeleteIterator(data_, iterator_); + data_ = other.data_; + accessor_ = other.accessor_; + iterator_ = accessor_->CopyIterator(data_, other.iterator_); + } + return *this; + } + + protected: + const void* data_; + const RepeatedFieldAccessor* accessor_; + void* iterator_; + std::unique_ptr<AccessorValueType> scratch_space_; +}; + +// TypeTraits that maps the type parameter T of RepeatedFieldRef or +// MutableRepeatedFieldRef to corresponding iterator type, +// RepeatedFieldAccessor type, etc. +template <typename T> +struct PrimitiveTraits { + static constexpr bool is_primitive = false; +}; +#define DEFINE_PRIMITIVE(TYPE, type) \ + template <> \ + struct PrimitiveTraits<type> { \ + static const bool is_primitive = true; \ + static const FieldDescriptor::CppType cpp_type = \ + FieldDescriptor::CPPTYPE_##TYPE; \ + }; +DEFINE_PRIMITIVE(INT32, arc_i32) +DEFINE_PRIMITIVE(UINT32, arc_ui32) +DEFINE_PRIMITIVE(INT64, arc_i64) +DEFINE_PRIMITIVE(UINT64, arc_ui64) +DEFINE_PRIMITIVE(FLOAT, float) +DEFINE_PRIMITIVE(DOUBLE, double) +DEFINE_PRIMITIVE(BOOL, bool) +#undef DEFINE_PRIMITIVE + +template <typename T> +struct RefTypeTraits< + T, typename std::enable_if<PrimitiveTraits<T>::is_primitive>::type> { + typedef RepeatedFieldRefIterator<T> iterator; + typedef RepeatedFieldAccessor AccessorType; + typedef T AccessorValueType; + typedef T IteratorValueType; + typedef T* IteratorPointerType; + static constexpr FieldDescriptor::CppType cpp_type = + PrimitiveTraits<T>::cpp_type; + static const Descriptor* GetMessageFieldDescriptor() { return nullptr; } +}; + +template <typename T> +struct RefTypeTraits< + T, typename std::enable_if<is_proto_enum<T>::value>::type> { + typedef RepeatedFieldRefIterator<T> iterator; + typedef RepeatedFieldAccessor AccessorType; + // We use arc_i32 for repeated enums in RepeatedFieldAccessor. + typedef arc_i32 AccessorValueType; + typedef T IteratorValueType; + typedef arc_i32* IteratorPointerType; + static constexpr FieldDescriptor::CppType cpp_type = + FieldDescriptor::CPPTYPE_ENUM; + static const Descriptor* GetMessageFieldDescriptor() { return nullptr; } +}; + +template <typename T> +struct RefTypeTraits< + T, typename std::enable_if<std::is_same<TProtoStringType, T>::value>::type> { + typedef RepeatedFieldRefIterator<T> iterator; + typedef RepeatedFieldAccessor AccessorType; + typedef TProtoStringType AccessorValueType; + typedef const TProtoStringType IteratorValueType; + typedef const TProtoStringType* IteratorPointerType; + static constexpr FieldDescriptor::CppType cpp_type = + FieldDescriptor::CPPTYPE_STRING; + static const Descriptor* GetMessageFieldDescriptor() { return nullptr; } +}; + +template <typename T> +struct MessageDescriptorGetter { + static const Descriptor* get() { + return T::default_instance().GetDescriptor(); + } +}; +template <> +struct MessageDescriptorGetter<Message> { + static const Descriptor* get() { return nullptr; } +}; + +template <typename T> +struct RefTypeTraits< + T, typename std::enable_if<std::is_base_of<Message, T>::value>::type> { + typedef RepeatedFieldRefIterator<T> iterator; + typedef RepeatedFieldAccessor AccessorType; + typedef Message AccessorValueType; + typedef const T& IteratorValueType; + typedef const T* IteratorPointerType; + static constexpr FieldDescriptor::CppType cpp_type = + FieldDescriptor::CPPTYPE_MESSAGE; + static const Descriptor* GetMessageFieldDescriptor() { + return MessageDescriptorGetter<T>::get(); + } +}; +} // namespace internal +} // namespace protobuf +} // namespace google + +#include <google/protobuf/port_undef.inc> + +#endif // GOOGLE_PROTOBUF_REFLECTION_H__ diff --git a/contrib/libs/protobuf_old/src/google/protobuf/reflection_internal.h b/contrib/libs/protobuf_old/src/google/protobuf/reflection_internal.h new file mode 100644 index 0000000000..0035db23a5 --- /dev/null +++ b/contrib/libs/protobuf_old/src/google/protobuf/reflection_internal.h @@ -0,0 +1,364 @@ +// 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_REFLECTION_INTERNAL_H__ +#define GOOGLE_PROTOBUF_REFLECTION_INTERNAL_H__ + +#include <google/protobuf/map_field.h> +#include <google/protobuf/reflection.h> +#include <google/protobuf/repeated_field.h> + +namespace google { +namespace protobuf { +namespace internal { +// A base class for RepeatedFieldAccessor implementations that can support +// random-access efficiently. All iterator methods delegates the work to +// corresponding random-access methods. +class RandomAccessRepeatedFieldAccessor : public RepeatedFieldAccessor { + public: + Iterator* BeginIterator(const Field* /*data*/) const override { + return PositionToIterator(0); + } + Iterator* EndIterator(const Field* data) const override { + return PositionToIterator(this->Size(data)); + } + Iterator* CopyIterator(const Field* /*data*/, + const Iterator* iterator) const override { + return const_cast<Iterator*>(iterator); + } + Iterator* AdvanceIterator(const Field* /*data*/, + Iterator* iterator) const override { + return PositionToIterator(IteratorToPosition(iterator) + 1); + } + bool EqualsIterator(const Field* /*data*/, const Iterator* a, + const Iterator* b) const override { + return a == b; + } + void DeleteIterator(const Field* /*data*/, + Iterator* /*iterator*/) const override {} + const Value* GetIteratorValue(const Field* data, const Iterator* iterator, + Value* scratch_space) const override { + return Get(data, static_cast<int>(IteratorToPosition(iterator)), + scratch_space); + } + + protected: + ~RandomAccessRepeatedFieldAccessor() = default; + + private: + static intptr_t IteratorToPosition(const Iterator* iterator) { + return reinterpret_cast<intptr_t>(iterator); + } + static Iterator* PositionToIterator(intptr_t position) { + return reinterpret_cast<Iterator*>(position); + } +}; + +// Base class for RepeatedFieldAccessor implementations that manipulates +// RepeatedField<T>. +template <typename T> +class RepeatedFieldWrapper : public RandomAccessRepeatedFieldAccessor { + public: + RepeatedFieldWrapper() {} + bool IsEmpty(const Field* data) const override { + return GetRepeatedField(data)->empty(); + } + int Size(const Field* data) const override { + return GetRepeatedField(data)->size(); + } + const Value* Get(const Field* data, int index, + Value* scratch_space) const override { + return ConvertFromT(GetRepeatedField(data)->Get(index), scratch_space); + } + void Clear(Field* data) const override { + MutableRepeatedField(data)->Clear(); + } + void Set(Field* data, int index, const Value* value) const override { + MutableRepeatedField(data)->Set(index, ConvertToT(value)); + } + void Add(Field* data, const Value* value) const override { + MutableRepeatedField(data)->Add(ConvertToT(value)); + } + void RemoveLast(Field* data) const override { + MutableRepeatedField(data)->RemoveLast(); + } + void SwapElements(Field* data, int index1, int index2) const override { + MutableRepeatedField(data)->SwapElements(index1, index2); + } + + protected: + ~RepeatedFieldWrapper() = default; + typedef RepeatedField<T> RepeatedFieldType; + static const RepeatedFieldType* GetRepeatedField(const Field* data) { + return reinterpret_cast<const RepeatedFieldType*>(data); + } + static RepeatedFieldType* MutableRepeatedField(Field* data) { + return reinterpret_cast<RepeatedFieldType*>(data); + } + + // Convert an object received by this accessor to an object to be stored in + // the underlying RepeatedField. + virtual T ConvertToT(const Value* value) const = 0; + + // Convert an object stored in RepeatedPtrField to an object that will be + // returned by this accessor. If the two objects have the same type (true for + // string fields with ctype=STRING), a pointer to the source object can be + // returned directly. Otherwise, data should be copied from value to + // scratch_space and scratch_space should be returned. + virtual const Value* ConvertFromT(const T& value, + Value* scratch_space) const = 0; +}; + +// Base class for RepeatedFieldAccessor implementations that manipulates +// RepeatedPtrField<T>. +template <typename T> +class RepeatedPtrFieldWrapper : public RandomAccessRepeatedFieldAccessor { + public: + bool IsEmpty(const Field* data) const override { + return GetRepeatedField(data)->empty(); + } + int Size(const Field* data) const override { + return GetRepeatedField(data)->size(); + } + const Value* Get(const Field* data, int index, + Value* scratch_space) const override { + return ConvertFromT(GetRepeatedField(data)->Get(index), scratch_space); + } + void Clear(Field* data) const override { + MutableRepeatedField(data)->Clear(); + } + void Set(Field* data, int index, const Value* value) const override { + ConvertToT(value, MutableRepeatedField(data)->Mutable(index)); + } + void Add(Field* data, const Value* value) const override { + T* allocated = New(value); + ConvertToT(value, allocated); + MutableRepeatedField(data)->AddAllocated(allocated); + } + void RemoveLast(Field* data) const override { + MutableRepeatedField(data)->RemoveLast(); + } + void SwapElements(Field* data, int index1, int index2) const override { + MutableRepeatedField(data)->SwapElements(index1, index2); + } + + protected: + ~RepeatedPtrFieldWrapper() = default; + typedef RepeatedPtrField<T> RepeatedFieldType; + static const RepeatedFieldType* GetRepeatedField(const Field* data) { + return reinterpret_cast<const RepeatedFieldType*>(data); + } + static RepeatedFieldType* MutableRepeatedField(Field* data) { + return reinterpret_cast<RepeatedFieldType*>(data); + } + + // Create a new T instance. For repeated message fields, T can be specified + // as google::protobuf::Message so we can't use "new T()" directly. In that case, value + // should be a message of the same type (it's ensured by the caller) and a + // new message object will be created using it. + virtual T* New(const Value* value) const = 0; + + // Convert an object received by this accessor to an object that will be + // stored in the underlying RepeatedPtrField. + virtual void ConvertToT(const Value* value, T* result) const = 0; + + // Convert an object stored in RepeatedPtrField to an object that will be + // returned by this accessor. If the two objects have the same type (true for + // string fields with ctype=STRING), a pointer to the source object can be + // returned directly. Otherwise, data should be copied from value to + // scratch_space and scratch_space should be returned. + virtual const Value* ConvertFromT(const T& value, + Value* scratch_space) const = 0; +}; + +// An implementation of RandomAccessRepeatedFieldAccessor that manipulates +// MapFieldBase. +class MapFieldAccessor final : public RandomAccessRepeatedFieldAccessor { + public: + MapFieldAccessor() {} + virtual ~MapFieldAccessor() {} + bool IsEmpty(const Field* data) const override { + return GetRepeatedField(data)->empty(); + } + int Size(const Field* data) const override { + return GetRepeatedField(data)->size(); + } + const Value* Get(const Field* data, int index, + Value* scratch_space) const override { + return ConvertFromEntry(GetRepeatedField(data)->Get(index), scratch_space); + } + void Clear(Field* data) const override { + MutableRepeatedField(data)->Clear(); + } + void Set(Field* data, int index, const Value* value) const override { + ConvertToEntry(value, MutableRepeatedField(data)->Mutable(index)); + } + void Add(Field* data, const Value* value) const override { + Message* allocated = New(value); + ConvertToEntry(value, allocated); + MutableRepeatedField(data)->AddAllocated(allocated); + } + void RemoveLast(Field* data) const override { + MutableRepeatedField(data)->RemoveLast(); + } + void SwapElements(Field* data, int index1, int index2) const override { + MutableRepeatedField(data)->SwapElements(index1, index2); + } + void Swap(Field* data, const internal::RepeatedFieldAccessor* other_mutator, + Field* other_data) const override { + GOOGLE_CHECK(this == other_mutator); + MutableRepeatedField(data)->Swap(MutableRepeatedField(other_data)); + } + + protected: + typedef RepeatedPtrField<Message> RepeatedFieldType; + static const RepeatedFieldType* GetRepeatedField(const Field* data) { + return reinterpret_cast<const RepeatedFieldType*>( + (&reinterpret_cast<const MapFieldBase*>(data)->GetRepeatedField())); + } + static RepeatedFieldType* MutableRepeatedField(Field* data) { + return reinterpret_cast<RepeatedFieldType*>( + reinterpret_cast<MapFieldBase*>(data)->MutableRepeatedField()); + } + virtual Message* New(const Value* value) const { + return static_cast<const Message*>(value)->New(); + } + // Convert an object received by this accessor to an MapEntry message to be + // stored in the underlying MapFieldBase. + virtual void ConvertToEntry(const Value* value, Message* result) const { + result->CopyFrom(*static_cast<const Message*>(value)); + } + // Convert a MapEntry message stored in the underlying MapFieldBase to an + // object that will be returned by this accessor. + virtual const Value* ConvertFromEntry(const Message& value, + Value* /*scratch_space*/) const { + return static_cast<const Value*>(&value); + } +}; + +// Default implementations of RepeatedFieldAccessor for primitive types. +template <typename T> +class RepeatedFieldPrimitiveAccessor final : public RepeatedFieldWrapper<T> { + typedef void Field; + typedef void Value; + using RepeatedFieldWrapper<T>::MutableRepeatedField; + + public: + RepeatedFieldPrimitiveAccessor() {} + void Swap(Field* data, const internal::RepeatedFieldAccessor* other_mutator, + Field* other_data) const override { + // Currently RepeatedFieldPrimitiveAccessor is the only implementation of + // RepeatedFieldAccessor for primitive types. As we are using singletons + // for these accessors, here "other_mutator" must be "this". + GOOGLE_CHECK(this == other_mutator); + MutableRepeatedField(data)->Swap(MutableRepeatedField(other_data)); + } + + protected: + T ConvertToT(const Value* value) const override { + return *static_cast<const T*>(value); + } + const Value* ConvertFromT(const T& value, + Value* /*scratch_space*/) const override { + return static_cast<const Value*>(&value); + } +}; + +// Default implementation of RepeatedFieldAccessor for string fields with +// ctype=STRING. +class RepeatedPtrFieldStringAccessor final + : public RepeatedPtrFieldWrapper<TProtoStringType> { + typedef void Field; + typedef void Value; + using RepeatedFieldAccessor::Add; + + public: + RepeatedPtrFieldStringAccessor() {} + void Swap(Field* data, const internal::RepeatedFieldAccessor* other_mutator, + Field* other_data) const override { + if (this == other_mutator) { + MutableRepeatedField(data)->Swap(MutableRepeatedField(other_data)); + } else { + RepeatedPtrField<TProtoStringType> tmp; + tmp.Swap(MutableRepeatedField(data)); + int other_size = other_mutator->Size(other_data); + for (int i = 0; i < other_size; ++i) { + Add<TProtoStringType>(data, other_mutator->Get<TProtoStringType>(other_data, i)); + } + int size = Size(data); + other_mutator->Clear(other_data); + for (int i = 0; i < size; ++i) { + other_mutator->Add<TProtoStringType>(other_data, tmp.Get(i)); + } + } + } + + protected: + TProtoStringType* New(const Value*) const override { return new TProtoStringType(); } + void ConvertToT(const Value* value, TProtoStringType* result) const override { + *result = *static_cast<const TProtoStringType*>(value); + } + const Value* ConvertFromT(const TProtoStringType& value, + Value* /*scratch_space*/) const override { + return static_cast<const Value*>(&value); + } +}; + + +class RepeatedPtrFieldMessageAccessor final + : public RepeatedPtrFieldWrapper<Message> { + typedef void Field; + typedef void Value; + + public: + RepeatedPtrFieldMessageAccessor() {} + void Swap(Field* data, const internal::RepeatedFieldAccessor* other_mutator, + Field* other_data) const override { + GOOGLE_CHECK(this == other_mutator); + MutableRepeatedField(data)->Swap(MutableRepeatedField(other_data)); + } + + protected: + Message* New(const Value* value) const override { + return static_cast<const Message*>(value)->New(); + } + void ConvertToT(const Value* value, Message* result) const override { + result->CopyFrom(*static_cast<const Message*>(value)); + } + const Value* ConvertFromT(const Message& value, + Value* /*scratch_space*/) const override { + return static_cast<const Value*>(&value); + } +}; +} // namespace internal +} // namespace protobuf +} // namespace google + +#endif // GOOGLE_PROTOBUF_REFLECTION_INTERNAL_H__ diff --git a/contrib/libs/protobuf_old/src/google/protobuf/reflection_ops.cc b/contrib/libs/protobuf_old/src/google/protobuf/reflection_ops.cc new file mode 100644 index 0000000000..a369ddb001 --- /dev/null +++ b/contrib/libs/protobuf_old/src/google/protobuf/reflection_ops.cc @@ -0,0 +1,454 @@ +// 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: kenton@google.com (Kenton Varda) +// Based on original Protocol Buffers design by +// Sanjay Ghemawat, Jeff Dean, and others. +#include <google/protobuf/reflection_ops.h> + +#include <string> +#include <vector> + +#include <google/protobuf/stubs/logging.h> +#include <google/protobuf/stubs/common.h> +#include <google/protobuf/descriptor.pb.h> +#include <google/protobuf/descriptor.h> +#include <google/protobuf/map_field.h> +#include <google/protobuf/map_field_inl.h> +#include <google/protobuf/unknown_field_set.h> + +#include <google/protobuf/port_def.inc> + +namespace google { +namespace protobuf { +namespace internal { + +static const Reflection* GetReflectionOrDie(const Message& m) { + const Reflection* r = m.GetReflection(); + if (r == nullptr) { + const Descriptor* d = m.GetDescriptor(); + const TProtoStringType& mtype = d ? d->name() : "unknown"; + // RawMessage is one known type for which GetReflection() returns nullptr. + GOOGLE_LOG(FATAL) << "Message does not support reflection (type " << mtype << ")."; + } + return r; +} + +void ReflectionOps::Copy(const Message& from, Message* to) { + if (&from == to) return; + Clear(to); + Merge(from, to); +} + +void ReflectionOps::Merge(const Message& from, Message* to) { + GOOGLE_CHECK_NE(&from, to); + + const Descriptor* descriptor = from.GetDescriptor(); + GOOGLE_CHECK_EQ(to->GetDescriptor(), descriptor) + << "Tried to merge messages of different types " + << "(merge " << descriptor->full_name() << " to " + << to->GetDescriptor()->full_name() << ")"; + + const Reflection* from_reflection = GetReflectionOrDie(from); + const Reflection* to_reflection = GetReflectionOrDie(*to); + bool is_from_generated = (from_reflection->GetMessageFactory() == + google::protobuf::MessageFactory::generated_factory()); + bool is_to_generated = (to_reflection->GetMessageFactory() == + google::protobuf::MessageFactory::generated_factory()); + + std::vector<const FieldDescriptor*> fields; + from_reflection->ListFieldsOmitStripped(from, &fields); + for (const FieldDescriptor* field : fields) { + if (field->is_repeated()) { + // Use map reflection if both are in map status and have the + // same map type to avoid sync with repeated field. + // Note: As from and to messages have the same descriptor, the + // map field types are the same if they are both generated + // messages or both dynamic messages. + if (is_from_generated == is_to_generated && field->is_map()) { + const MapFieldBase* from_field = + from_reflection->GetMapData(from, field); + MapFieldBase* to_field = to_reflection->MutableMapData(to, field); + if (to_field->IsMapValid() && from_field->IsMapValid()) { + to_field->MergeFrom(*from_field); + continue; + } + } + int count = from_reflection->FieldSize(from, field); + for (int j = 0; j < count; j++) { + switch (field->cpp_type()) { +#define HANDLE_TYPE(CPPTYPE, METHOD) \ + case FieldDescriptor::CPPTYPE_##CPPTYPE: \ + to_reflection->Add##METHOD( \ + to, field, from_reflection->GetRepeated##METHOD(from, field, j)); \ + break; + + HANDLE_TYPE(INT32, Int32); + HANDLE_TYPE(INT64, Int64); + HANDLE_TYPE(UINT32, UInt32); + HANDLE_TYPE(UINT64, UInt64); + HANDLE_TYPE(FLOAT, Float); + HANDLE_TYPE(DOUBLE, Double); + HANDLE_TYPE(BOOL, Bool); + HANDLE_TYPE(STRING, String); + HANDLE_TYPE(ENUM, Enum); +#undef HANDLE_TYPE + + case FieldDescriptor::CPPTYPE_MESSAGE: + const Message& from_child = + from_reflection->GetRepeatedMessage(from, field, j); + if (from_reflection == to_reflection) { + to_reflection + ->AddMessage(to, field, + from_child.GetReflection()->GetMessageFactory()) + ->MergeFrom(from_child); + } else { + to_reflection->AddMessage(to, field)->MergeFrom(from_child); + } + break; + } + } + } else { + switch (field->cpp_type()) { +#define HANDLE_TYPE(CPPTYPE, METHOD) \ + case FieldDescriptor::CPPTYPE_##CPPTYPE: \ + to_reflection->Set##METHOD(to, field, \ + from_reflection->Get##METHOD(from, field)); \ + break; + + HANDLE_TYPE(INT32, Int32); + HANDLE_TYPE(INT64, Int64); + HANDLE_TYPE(UINT32, UInt32); + HANDLE_TYPE(UINT64, UInt64); + HANDLE_TYPE(FLOAT, Float); + HANDLE_TYPE(DOUBLE, Double); + HANDLE_TYPE(BOOL, Bool); + HANDLE_TYPE(STRING, String); + HANDLE_TYPE(ENUM, Enum); +#undef HANDLE_TYPE + + case FieldDescriptor::CPPTYPE_MESSAGE: + const Message& from_child = from_reflection->GetMessage(from, field); + if (from_reflection == to_reflection) { + to_reflection + ->MutableMessage( + to, field, from_child.GetReflection()->GetMessageFactory()) + ->MergeFrom(from_child); + } else { + to_reflection->MutableMessage(to, field)->MergeFrom(from_child); + } + break; + } + } + } + + to_reflection->MutableUnknownFields(to)->MergeFrom( + from_reflection->GetUnknownFields(from)); +} + +void ReflectionOps::Clear(Message* message) { + const Reflection* reflection = GetReflectionOrDie(*message); + + std::vector<const FieldDescriptor*> fields; + reflection->ListFieldsOmitStripped(*message, &fields); + for (const FieldDescriptor* field : fields) { + reflection->ClearField(message, field); + } + + reflection->MutableUnknownFields(message)->Clear(); +} + +bool ReflectionOps::IsInitialized(const Message& message, bool check_fields, + bool check_descendants) { + const Descriptor* descriptor = message.GetDescriptor(); + const Reflection* reflection = GetReflectionOrDie(message); + if (const int field_count = descriptor->field_count()) { + const FieldDescriptor* begin = descriptor->field(0); + const FieldDescriptor* end = begin + field_count; + GOOGLE_DCHECK_EQ(descriptor->field(field_count - 1), end - 1); + + if (check_fields) { + // Check required fields of this message. + for (const FieldDescriptor* field = begin; field != end; ++field) { + if (field->is_required() && !reflection->HasField(message, field)) { + return false; + } + } + } + + if (check_descendants) { + for (const FieldDescriptor* field = begin; field != end; ++field) { + if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) { + const Descriptor* message_type = field->message_type(); + if (PROTOBUF_PREDICT_FALSE(message_type->options().map_entry())) { + if (message_type->field(1)->cpp_type() == + FieldDescriptor::CPPTYPE_MESSAGE) { + const MapFieldBase* map_field = + reflection->GetMapData(message, field); + if (map_field->IsMapValid()) { + MapIterator it(const_cast<Message*>(&message), field); + MapIterator end_map(const_cast<Message*>(&message), field); + for (map_field->MapBegin(&it), map_field->MapEnd(&end_map); + it != end_map; ++it) { + if (!it.GetValueRef().GetMessageValue().IsInitialized()) { + return false; + } + } + } + } + } else if (field->is_repeated()) { + const int size = reflection->FieldSize(message, field); + for (int j = 0; j < size; j++) { + if (!reflection->GetRepeatedMessage(message, field, j) + .IsInitialized()) { + return false; + } + } + } else if (reflection->HasField(message, field)) { + if (!reflection->GetMessage(message, field).IsInitialized()) { + return false; + } + } + } + } + } + } + if (check_descendants && reflection->HasExtensionSet(message) && + !reflection->GetExtensionSet(message).IsInitialized()) { + return false; + } + return true; +} + +bool ReflectionOps::IsInitialized(const Message& message) { + const Descriptor* descriptor = message.GetDescriptor(); + const Reflection* reflection = GetReflectionOrDie(message); + + // Check required fields of this message. + { + const int field_count = descriptor->field_count(); + for (int i = 0; i < field_count; i++) { + if (descriptor->field(i)->is_required()) { + if (!reflection->HasField(message, descriptor->field(i))) { + return false; + } + } + } + } + + // Check that sub-messages are initialized. + std::vector<const FieldDescriptor*> fields; + // Should be safe to skip stripped fields because required fields are not + // stripped. + reflection->ListFieldsOmitStripped(message, &fields); + for (const FieldDescriptor* field : fields) { + if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) { + + if (field->is_map()) { + const FieldDescriptor* value_field = field->message_type()->field(1); + if (value_field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) { + const MapFieldBase* map_field = + reflection->GetMapData(message, field); + if (map_field->IsMapValid()) { + MapIterator iter(const_cast<Message*>(&message), field); + MapIterator end(const_cast<Message*>(&message), field); + for (map_field->MapBegin(&iter), map_field->MapEnd(&end); + iter != end; ++iter) { + if (!iter.GetValueRef().GetMessageValue().IsInitialized()) { + return false; + } + } + continue; + } + } else { + continue; + } + } + + if (field->is_repeated()) { + int size = reflection->FieldSize(message, field); + + for (int j = 0; j < size; j++) { + if (!reflection->GetRepeatedMessage(message, field, j) + .IsInitialized()) { + return false; + } + } + } else { + if (!reflection->GetMessage(message, field).IsInitialized()) { + return false; + } + } + } + } + + return true; +} + +static bool IsMapValueMessageTyped(const FieldDescriptor* map_field) { + return map_field->message_type()->field(1)->cpp_type() == + FieldDescriptor::CPPTYPE_MESSAGE; +} + +void ReflectionOps::DiscardUnknownFields(Message* message) { + const Reflection* reflection = GetReflectionOrDie(*message); + + reflection->MutableUnknownFields(message)->Clear(); + + // Walk through the fields of this message and DiscardUnknownFields on any + // messages present. + std::vector<const FieldDescriptor*> fields; + reflection->ListFields(*message, &fields); + for (const FieldDescriptor* field : fields) { + // Skip over non-message fields. + if (field->cpp_type() != FieldDescriptor::CPPTYPE_MESSAGE) { + continue; + } + // Discard the unknown fields in maps that contain message values. + if (field->is_map() && IsMapValueMessageTyped(field)) { + const MapFieldBase* map_field = + reflection->MutableMapData(message, field); + if (map_field->IsMapValid()) { + MapIterator iter(message, field); + MapIterator end(message, field); + for (map_field->MapBegin(&iter), map_field->MapEnd(&end); iter != end; + ++iter) { + iter.MutableValueRef()->MutableMessageValue()->DiscardUnknownFields(); + } + } + // Discard every unknown field inside messages in a repeated field. + } else if (field->is_repeated()) { + int size = reflection->FieldSize(*message, field); + for (int j = 0; j < size; j++) { + reflection->MutableRepeatedMessage(message, field, j) + ->DiscardUnknownFields(); + } + // Discard the unknown fields inside an optional message. + } else { + reflection->MutableMessage(message, field)->DiscardUnknownFields(); + } + } +} + +static TProtoStringType SubMessagePrefix(const TProtoStringType& prefix, + const FieldDescriptor* field, int index) { + TProtoStringType result(prefix); + if (field->is_extension()) { + result.append("("); + result.append(field->full_name()); + result.append(")"); + } else { + result.append(field->name()); + } + if (index != -1) { + result.append("["); + result.append(StrCat(index)); + result.append("]"); + } + result.append("."); + return result; +} + +void ReflectionOps::FindInitializationErrors(const Message& message, + const TProtoStringType& prefix, + std::vector<TProtoStringType>* errors) { + const Descriptor* descriptor = message.GetDescriptor(); + const Reflection* reflection = GetReflectionOrDie(message); + + // Check required fields of this message. + { + const int field_count = descriptor->field_count(); + for (int i = 0; i < field_count; i++) { + if (descriptor->field(i)->is_required()) { + if (!reflection->HasField(message, descriptor->field(i))) { + errors->push_back(prefix + descriptor->field(i)->name()); + } + } + } + } + + // Check sub-messages. + std::vector<const FieldDescriptor*> fields; + reflection->ListFieldsOmitStripped(message, &fields); + for (const FieldDescriptor* field : fields) { + if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) { + + if (field->is_repeated()) { + int size = reflection->FieldSize(message, field); + + for (int j = 0; j < size; j++) { + const Message& sub_message = + reflection->GetRepeatedMessage(message, field, j); + FindInitializationErrors(sub_message, + SubMessagePrefix(prefix, field, j), errors); + } + } else { + const Message& sub_message = reflection->GetMessage(message, field); + FindInitializationErrors(sub_message, + SubMessagePrefix(prefix, field, -1), errors); + } + } + } +} + +void GenericSwap(Message* lhs, Message* rhs) { +#ifndef PROTOBUF_FORCE_COPY_IN_SWAP + GOOGLE_DCHECK(Arena::InternalHelper<Message>::GetOwningArena(lhs) != + Arena::InternalHelper<Message>::GetOwningArena(rhs)); + GOOGLE_DCHECK(Arena::InternalHelper<Message>::GetOwningArena(lhs) != nullptr || + Arena::InternalHelper<Message>::GetOwningArena(rhs) != nullptr); +#endif // !PROTOBUF_FORCE_COPY_IN_SWAP + // At least one of these must have an arena, so make `rhs` point to it. + Arena* arena = Arena::InternalHelper<Message>::GetOwningArena(rhs); + if (arena == nullptr) { + std::swap(lhs, rhs); + arena = Arena::InternalHelper<Message>::GetOwningArena(rhs); + } + + // Improve efficiency by placing the temporary on an arena so that messages + // are copied twice rather than three times. + Message* tmp = rhs->New(arena); + tmp->CheckTypeAndMergeFrom(*lhs); + lhs->Clear(); + lhs->CheckTypeAndMergeFrom(*rhs); +#ifdef PROTOBUF_FORCE_COPY_IN_SWAP + rhs->Clear(); + rhs->CheckTypeAndMergeFrom(*tmp); + if (arena == nullptr) delete tmp; +#else // PROTOBUF_FORCE_COPY_IN_SWAP + rhs->GetReflection()->Swap(tmp, rhs); +#endif // !PROTOBUF_FORCE_COPY_IN_SWAP +} + +} // namespace internal +} // namespace protobuf +} // namespace google + +#include <google/protobuf/port_undef.inc> diff --git a/contrib/libs/protobuf_old/src/google/protobuf/reflection_ops.h b/contrib/libs/protobuf_old/src/google/protobuf/reflection_ops.h new file mode 100644 index 0000000000..50b68aeef2 --- /dev/null +++ b/contrib/libs/protobuf_old/src/google/protobuf/reflection_ops.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. + +// Author: kenton@google.com (Kenton Varda) +// Based on original Protocol Buffers design by +// Sanjay Ghemawat, Jeff Dean, and others. +// +// This header is logically internal, but is made public because it is used +// from protocol-compiler-generated code, which may reside in other components. + +#ifndef GOOGLE_PROTOBUF_REFLECTION_OPS_H__ +#define GOOGLE_PROTOBUF_REFLECTION_OPS_H__ + +#include <google/protobuf/stubs/common.h> +#include <google/protobuf/message.h> + +#ifdef SWIG +#error "You cannot SWIG proto headers" +#endif + +#include <google/protobuf/port_def.inc> + +namespace google { +namespace protobuf { +namespace internal { + +// Basic operations that can be performed using reflection. +// These can be used as a cheap way to implement the corresponding +// methods of the Message interface, though they are likely to be +// slower than implementations tailored for the specific message type. +// +// This class should stay limited to operations needed to implement +// the Message interface. +// +// This class is really a namespace that contains only static methods. +class PROTOBUF_EXPORT ReflectionOps { + public: + static void Copy(const Message& from, Message* to); + static void Merge(const Message& from, Message* to); + static void Clear(Message* message); + static bool IsInitialized(const Message& message); + static bool IsInitialized(const Message& message, bool check_fields, + bool check_descendants); + static void DiscardUnknownFields(Message* message); + + // Finds all unset required fields in the message and adds their full + // paths (e.g. "foo.bar[5].baz") to *names. "prefix" will be attached to + // the front of each name. + static void FindInitializationErrors(const Message& message, + const TProtoStringType& prefix, + std::vector<TProtoStringType>* errors); + + private: + // All methods are static. No need to construct. + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ReflectionOps); +}; + +} // namespace internal +} // namespace protobuf +} // namespace google + +#include <google/protobuf/port_undef.inc> + +#endif // GOOGLE_PROTOBUF_REFLECTION_OPS_H__ diff --git a/contrib/libs/protobuf_old/src/google/protobuf/repeated_field.cc b/contrib/libs/protobuf_old/src/google/protobuf/repeated_field.cc new file mode 100644 index 0000000000..016cfbc65e --- /dev/null +++ b/contrib/libs/protobuf_old/src/google/protobuf/repeated_field.cc @@ -0,0 +1,60 @@ +// 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: kenton@google.com (Kenton Varda) +// Based on original Protocol Buffers design by +// Sanjay Ghemawat, Jeff Dean, and others. + +#include <google/protobuf/repeated_field.h> + +#include <algorithm> + +#include <google/protobuf/stubs/logging.h> +#include <google/protobuf/stubs/common.h> + +#include <google/protobuf/port_def.inc> + +namespace google { +namespace protobuf { + + +template class PROTOBUF_EXPORT_TEMPLATE_DEFINE RepeatedField<bool>; +template class PROTOBUF_EXPORT_TEMPLATE_DEFINE RepeatedField<arc_i32>; +template class PROTOBUF_EXPORT_TEMPLATE_DEFINE RepeatedField<arc_ui32>; +template class PROTOBUF_EXPORT_TEMPLATE_DEFINE RepeatedField<arc_i64>; +template class PROTOBUF_EXPORT_TEMPLATE_DEFINE RepeatedField<arc_ui64>; +template class PROTOBUF_EXPORT_TEMPLATE_DEFINE RepeatedField<float>; +template class PROTOBUF_EXPORT_TEMPLATE_DEFINE RepeatedField<double>; +template class PROTOBUF_EXPORT_TEMPLATE_DEFINE RepeatedPtrField<TProtoStringType>; + +} // namespace protobuf +} // namespace google + +#include <google/protobuf/port_undef.inc> diff --git a/contrib/libs/protobuf_old/src/google/protobuf/repeated_field.h b/contrib/libs/protobuf_old/src/google/protobuf/repeated_field.h new file mode 100644 index 0000000000..2b7fe6135d --- /dev/null +++ b/contrib/libs/protobuf_old/src/google/protobuf/repeated_field.h @@ -0,0 +1,1057 @@ +// 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: kenton@google.com (Kenton Varda) +// Based on original Protocol Buffers design by +// Sanjay Ghemawat, Jeff Dean, and others. +// +// RepeatedField and RepeatedPtrField are used by generated protocol message +// classes to manipulate repeated fields. These classes are very similar to +// STL's vector, but include a number of optimizations found to be useful +// specifically in the case of Protocol Buffers. RepeatedPtrField is +// particularly different from STL vector as it manages ownership of the +// pointers that it contains. +// +// Typically, clients should not need to access RepeatedField objects directly, +// but should instead use the accessor functions generated automatically by the +// protocol compiler. +// +// This header covers RepeatedField. + +#ifndef GOOGLE_PROTOBUF_REPEATED_FIELD_H__ +#define GOOGLE_PROTOBUF_REPEATED_FIELD_H__ + +#include <utility> +#ifdef _MSC_VER +// This is required for min/max on VS2013 only. +#include <algorithm> +#endif + +#include <iterator> +#include <limits> +#include <string> +#include <type_traits> + +#include <google/protobuf/stubs/logging.h> +#include <google/protobuf/stubs/common.h> +#include <google/protobuf/repeated_ptr_field.h> +#include <google/protobuf/arena.h> +#include <google/protobuf/message_lite.h> +#include <google/protobuf/port.h> + + +// Must be included last. +#include <google/protobuf/port_def.inc> + +#ifdef SWIG +#error "You cannot SWIG proto headers" +#endif + +namespace google { +namespace protobuf { + +class Message; + +namespace internal { + +// kRepeatedFieldLowerClampLimit is the smallest size that will be allocated +// when growing a repeated field. +constexpr int kRepeatedFieldLowerClampLimit = 4; + +// kRepeatedFieldUpperClampLimit is the lowest signed integer value that +// overflows when multiplied by 2 (which is undefined behavior). Sizes above +// this will clamp to the maximum int value instead of following exponential +// growth when growing a repeated field. +constexpr int kRepeatedFieldUpperClampLimit = + (std::numeric_limits<int>::max() / 2) + 1; + +template <typename Iter> +inline int CalculateReserve(Iter begin, Iter end, std::forward_iterator_tag) { + return static_cast<int>(std::distance(begin, end)); +} + +template <typename Iter> +inline int CalculateReserve(Iter /*begin*/, Iter /*end*/, + std::input_iterator_tag /*unused*/) { + return -1; +} + +template <typename Iter> +inline int CalculateReserve(Iter begin, Iter end) { + typedef typename std::iterator_traits<Iter>::iterator_category Category; + return CalculateReserve(begin, end, Category()); +} + +// Swaps two blocks of memory of size sizeof(T). +template <typename T> +inline void SwapBlock(char* p, char* q) { + T tmp; + memcpy(&tmp, p, sizeof(T)); + memcpy(p, q, sizeof(T)); + memcpy(q, &tmp, sizeof(T)); +} + +// Swaps two blocks of memory of size kSize: +// template <int kSize> void memswap(char* p, char* q); + +template <int kSize> +inline typename std::enable_if<(kSize == 0), void>::type memswap(char*, char*) { +} + +#define PROTO_MEMSWAP_DEF_SIZE(reg_type, max_size) \ + template <int kSize> \ + typename std::enable_if<(kSize >= sizeof(reg_type) && kSize < (max_size)), \ + void>::type \ + memswap(char* p, char* q) { \ + SwapBlock<reg_type>(p, q); \ + memswap<kSize - sizeof(reg_type)>(p + sizeof(reg_type), \ + q + sizeof(reg_type)); \ + } + +PROTO_MEMSWAP_DEF_SIZE(uint8_t, 2) +PROTO_MEMSWAP_DEF_SIZE(uint16_t, 4) +PROTO_MEMSWAP_DEF_SIZE(arc_ui32, 8) + +#ifdef __SIZEOF_INT128__ +PROTO_MEMSWAP_DEF_SIZE(arc_ui64, 16) +PROTO_MEMSWAP_DEF_SIZE(__uint128_t, (1u << 31)) +#else +PROTO_MEMSWAP_DEF_SIZE(arc_ui64, (1u << 31)) +#endif + +#undef PROTO_MEMSWAP_DEF_SIZE + +} // namespace internal + +// RepeatedField is used to represent repeated fields of a primitive type (in +// other words, everything except strings and nested Messages). Most users will +// not ever use a RepeatedField directly; they will use the get-by-index, +// set-by-index, and add accessors that are generated for all repeated fields. +template <typename Element> +class RepeatedField { + static_assert( + alignof(Arena) >= alignof(Element), + "We only support types that have an alignment smaller than Arena"); + + public: + constexpr RepeatedField(); + explicit RepeatedField(Arena* arena); + + RepeatedField(const RepeatedField& other); + + template <typename Iter, + typename = typename std::enable_if<std::is_constructible< + Element, decltype(*std::declval<Iter>())>::value>::type> + RepeatedField(Iter begin, Iter end); + + ~RepeatedField(); + + RepeatedField& operator=(const RepeatedField& other); + + RepeatedField(RepeatedField&& other) noexcept; + RepeatedField& operator=(RepeatedField&& other) noexcept; + + bool empty() const; + int size() const; + + const Element& Get(int index) const; + Element* Mutable(int index); + + const Element& operator[](int index) const { return Get(index); } + Element& operator[](int index) { return *Mutable(index); } + + const Element& at(int index) const; + Element& at(int index); + + void Set(int index, const Element& value); + void Add(const Element& value); + // Appends a new element and return a pointer to it. + // The new element is uninitialized if |Element| is a POD type. + Element* Add(); + // Append elements in the range [begin, end) after reserving + // the appropriate number of elements. + template <typename Iter> + void Add(Iter begin, Iter end); + + // Remove the last element in the array. + void RemoveLast(); + + // Extract elements with indices in "[start .. start+num-1]". + // Copy them into "elements[0 .. num-1]" if "elements" is not nullptr. + // Caution: implementation also moves elements with indices [start+num ..]. + // Calling this routine inside a loop can cause quadratic behavior. + void ExtractSubrange(int start, int num, Element* elements); + + PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear(); + void MergeFrom(const RepeatedField& other); + PROTOBUF_ATTRIBUTE_REINITIALIZES void CopyFrom(const RepeatedField& other); + + // Replaces the contents with RepeatedField(begin, end). + template <typename Iter> + PROTOBUF_ATTRIBUTE_REINITIALIZES void Assign(Iter begin, Iter end); + + // Reserve space to expand the field to at least the given size. If the + // array is grown, it will always be at least doubled in size. + void Reserve(int new_size); + + // Resize the RepeatedField to a new, smaller size. This is O(1). + void Truncate(int new_size); + + void AddAlreadyReserved(const Element& value); + // Appends a new element and return a pointer to it. + // The new element is uninitialized if |Element| is a POD type. + // Should be called only if Capacity() > Size(). + Element* AddAlreadyReserved(); + Element* AddNAlreadyReserved(int elements); + int Capacity() const; + + // Like STL resize. Uses value to fill appended elements. + // Like Truncate() if new_size <= size(), otherwise this is + // O(new_size - size()). + void Resize(int new_size, const Element& value); + + // Gets the underlying array. This pointer is possibly invalidated by + // any add or remove operation. + Element* mutable_data(); + const Element* data() const; + + // Swap entire contents with "other". If they are separate arenas then, copies + // data between each other. + void Swap(RepeatedField* other); + + // Swap entire contents with "other". Should be called only if the caller can + // guarantee that both repeated fields are on the same arena or are on the + // heap. Swapping between different arenas is disallowed and caught by a + // GOOGLE_DCHECK (see API docs for details). + void UnsafeArenaSwap(RepeatedField* other); + + // Swap two elements. + void SwapElements(int index1, int index2); + + // STL-like iterator support + typedef Element* iterator; + typedef const Element* const_iterator; + typedef Element value_type; + typedef value_type& reference; + typedef const value_type& const_reference; + typedef value_type* pointer; + typedef const value_type* const_pointer; + typedef int size_type; + typedef ptrdiff_t difference_type; + + iterator begin(); + const_iterator begin() const; + const_iterator cbegin() const; + iterator end(); + const_iterator end() const; + const_iterator cend() const; + + // Reverse iterator support + typedef std::reverse_iterator<const_iterator> const_reverse_iterator; + typedef std::reverse_iterator<iterator> reverse_iterator; + reverse_iterator rbegin() { return reverse_iterator(end()); } + const_reverse_iterator rbegin() const { + return const_reverse_iterator(end()); + } + reverse_iterator rend() { return reverse_iterator(begin()); } + const_reverse_iterator rend() const { + return const_reverse_iterator(begin()); + } + + // Returns the number of bytes used by the repeated field, excluding + // sizeof(*this) + size_t SpaceUsedExcludingSelfLong() const; + + int SpaceUsedExcludingSelf() const { + return internal::ToIntSize(SpaceUsedExcludingSelfLong()); + } + + // Removes the element referenced by position. + // + // Returns an iterator to the element immediately following the removed + // element. + // + // Invalidates all iterators at or after the removed element, including end(). + iterator erase(const_iterator position); + + // Removes the elements in the range [first, last). + // + // Returns an iterator to the element immediately following the removed range. + // + // Invalidates all iterators at or after the removed range, including end(). + iterator erase(const_iterator first, const_iterator last); + + // Get the Arena on which this RepeatedField stores its elements. + inline Arena* GetArena() const { + return (total_size_ == 0) ? static_cast<Arena*>(arena_or_elements_) + : rep()->arena; + } + + // For internal use only. + // + // This is public due to it being called by generated code. + inline void InternalSwap(RepeatedField* other); + + private: + static constexpr int kInitialSize = 0; + // A note on the representation here (see also comment below for + // RepeatedPtrFieldBase's struct Rep): + // + // We maintain the same sizeof(RepeatedField) as before we added arena support + // so that we do not degrade performance by bloating memory usage. Directly + // adding an arena_ element to RepeatedField is quite costly. By using + // indirection in this way, we keep the same size when the RepeatedField is + // empty (common case), and add only an 8-byte header to the elements array + // when non-empty. We make sure to place the size fields directly in the + // RepeatedField class to avoid costly cache misses due to the indirection. + int current_size_; + int total_size_; + struct Rep { + Arena* arena; + // Here we declare a huge array as a way of approximating C's "flexible + // array member" feature without relying on undefined behavior. + Element elements[(std::numeric_limits<int>::max() - 2 * sizeof(Arena*)) / + sizeof(Element)]; + }; + static constexpr size_t kRepHeaderSize = offsetof(Rep, elements); + + // If total_size_ == 0 this points to an Arena otherwise it points to the + // elements member of a Rep struct. Using this invariant allows the storage of + // the arena pointer without an extra allocation in the constructor. + void* arena_or_elements_; + + // Return pointer to elements array. + // pre-condition: the array must have been allocated. + Element* elements() const { + GOOGLE_DCHECK_GT(total_size_, 0); + // Because of above pre-condition this cast is safe. + return unsafe_elements(); + } + + // Return pointer to elements array if it exists otherwise either null or + // a invalid pointer is returned. This only happens for empty repeated fields, + // where you can't dereference this pointer anyway (it's empty). + Element* unsafe_elements() const { + return static_cast<Element*>(arena_or_elements_); + } + + // Return pointer to the Rep struct. + // pre-condition: the Rep must have been allocated, ie elements() is safe. + Rep* rep() const { + char* addr = reinterpret_cast<char*>(elements()) - offsetof(Rep, elements); + return reinterpret_cast<Rep*>(addr); + } + + friend class Arena; + typedef void InternalArenaConstructable_; + + // Move the contents of |from| into |to|, possibly clobbering |from| in the + // process. For primitive types this is just a memcpy(), but it could be + // specialized for non-primitive types to, say, swap each element instead. + void MoveArray(Element* to, Element* from, int size); + + // Copy the elements of |from| into |to|. + void CopyArray(Element* to, const Element* from, int size); + + // Internal helper to delete all elements and deallocate the storage. + void InternalDeallocate(Rep* rep, int size) { + if (rep != nullptr) { + Element* e = &rep->elements[0]; + if (!std::is_trivial<Element>::value) { + Element* limit = &rep->elements[size]; + for (; e < limit; e++) { + e->~Element(); + } + } + if (rep->arena == nullptr) { +#if defined(__GXX_DELETE_WITH_SIZE__) || defined(__cpp_sized_deallocation) + const size_t bytes = size * sizeof(*e) + kRepHeaderSize; + ::operator delete(static_cast<void*>(rep), bytes); +#else + ::operator delete(static_cast<void*>(rep)); +#endif + } + } + } + + // This class is a performance wrapper around RepeatedField::Add(const T&) + // function. In general unless a RepeatedField is a local stack variable LLVM + // has a hard time optimizing Add. The machine code tends to be + // loop: + // mov %size, dword ptr [%repeated_field] // load + // cmp %size, dword ptr [%repeated_field + 4] + // jae fallback + // mov %buffer, qword ptr [%repeated_field + 8] + // mov dword [%buffer + %size * 4], %value + // inc %size // increment + // mov dword ptr [%repeated_field], %size // store + // jmp loop + // + // This puts a load/store in each iteration of the important loop variable + // size. It's a pretty bad compile that happens even in simple cases, but + // largely the presence of the fallback path disturbs the compilers mem-to-reg + // analysis. + // + // This class takes ownership of a repeated field for the duration of it's + // lifetime. The repeated field should not be accessed during this time, ie. + // only access through this class is allowed. This class should always be a + // function local stack variable. Intended use + // + // void AddSequence(const int* begin, const int* end, RepeatedField<int>* out) + // { + // RepeatedFieldAdder<int> adder(out); // Take ownership of out + // for (auto it = begin; it != end; ++it) { + // adder.Add(*it); + // } + // } + // + // Typically due to the fact adder is a local stack variable. The compiler + // will be successful in mem-to-reg transformation and the machine code will + // be loop: cmp %size, %capacity jae fallback mov dword ptr [%buffer + %size * + // 4], %val inc %size jmp loop + // + // The first version executes at 7 cycles per iteration while the second + // version near 1 or 2 cycles. + template <int = 0, bool = std::is_trivial<Element>::value> + class FastAdderImpl { + public: + explicit FastAdderImpl(RepeatedField* rf) : repeated_field_(rf) { + index_ = repeated_field_->current_size_; + capacity_ = repeated_field_->total_size_; + buffer_ = repeated_field_->unsafe_elements(); + } + ~FastAdderImpl() { repeated_field_->current_size_ = index_; } + + void Add(Element val) { + if (index_ == capacity_) { + repeated_field_->current_size_ = index_; + repeated_field_->Reserve(index_ + 1); + capacity_ = repeated_field_->total_size_; + buffer_ = repeated_field_->unsafe_elements(); + } + buffer_[index_++] = val; + } + + private: + RepeatedField* repeated_field_; + int index_; + int capacity_; + Element* buffer_; + + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(FastAdderImpl); + }; + + // FastAdder is a wrapper for adding fields. The specialization above handles + // POD types more efficiently than RepeatedField. + template <int I> + class FastAdderImpl<I, false> { + public: + explicit FastAdderImpl(RepeatedField* rf) : repeated_field_(rf) {} + void Add(const Element& val) { repeated_field_->Add(val); } + + private: + RepeatedField* repeated_field_; + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(FastAdderImpl); + }; + + using FastAdder = FastAdderImpl<>; + + friend class TestRepeatedFieldHelper; + friend class ::google::protobuf::internal::ParseContext; +}; + +namespace internal { + +// This is a helper template to copy an array of elements efficiently when they +// have a trivial copy constructor, and correctly otherwise. This really +// shouldn't be necessary, but our compiler doesn't optimize std::copy very +// effectively. +template <typename Element, + bool HasTrivialCopy = std::is_trivial<Element>::value> +struct ElementCopier { + void operator()(Element* to, const Element* from, int array_size); +}; + +} // namespace internal + +// implementation ==================================================== + +template <typename Element> +constexpr RepeatedField<Element>::RepeatedField() + : current_size_(0), total_size_(0), arena_or_elements_(nullptr) {} + +template <typename Element> +inline RepeatedField<Element>::RepeatedField(Arena* arena) + : current_size_(0), total_size_(0), arena_or_elements_(arena) {} + +template <typename Element> +inline RepeatedField<Element>::RepeatedField(const RepeatedField& other) + : current_size_(0), total_size_(0), arena_or_elements_(nullptr) { + if (other.current_size_ != 0) { + Reserve(other.size()); + AddNAlreadyReserved(other.size()); + CopyArray(Mutable(0), &other.Get(0), other.size()); + } +} + +template <typename Element> +template <typename Iter, typename> +RepeatedField<Element>::RepeatedField(Iter begin, Iter end) + : current_size_(0), total_size_(0), arena_or_elements_(nullptr) { + Add(begin, end); +} + +template <typename Element> +RepeatedField<Element>::~RepeatedField() { +#ifndef NDEBUG + // Try to trigger segfault / asan failure in non-opt builds. If arena_ + // lifetime has ended before the destructor. + auto arena = GetArena(); + if (arena) (void)arena->SpaceAllocated(); +#endif + if (total_size_ > 0) { + InternalDeallocate(rep(), total_size_); + } +} + +template <typename Element> +inline RepeatedField<Element>& RepeatedField<Element>::operator=( + const RepeatedField& other) { + if (this != &other) CopyFrom(other); + return *this; +} + +template <typename Element> +inline RepeatedField<Element>::RepeatedField(RepeatedField&& other) noexcept + : RepeatedField() { +#ifdef PROTOBUF_FORCE_COPY_IN_MOVE + CopyFrom(other); +#else // PROTOBUF_FORCE_COPY_IN_MOVE + // We don't just call Swap(&other) here because it would perform 3 copies if + // other is on an arena. This field can't be on an arena because arena + // construction always uses the Arena* accepting constructor. + if (other.GetArena()) { + CopyFrom(other); + } else { + InternalSwap(&other); + } +#endif // !PROTOBUF_FORCE_COPY_IN_MOVE +} + +template <typename Element> +inline RepeatedField<Element>& RepeatedField<Element>::operator=( + RepeatedField&& other) noexcept { + // We don't just call Swap(&other) here because it would perform 3 copies if + // the two fields are on different arenas. + if (this != &other) { + if (GetArena() != other.GetArena() +#ifdef PROTOBUF_FORCE_COPY_IN_MOVE + || GetArena() == nullptr +#endif // !PROTOBUF_FORCE_COPY_IN_MOVE + ) { + CopyFrom(other); + } else { + InternalSwap(&other); + } + } + return *this; +} + +template <typename Element> +inline bool RepeatedField<Element>::empty() const { + return current_size_ == 0; +} + +template <typename Element> +inline int RepeatedField<Element>::size() const { + return current_size_; +} + +template <typename Element> +inline int RepeatedField<Element>::Capacity() const { + return total_size_; +} + +template <typename Element> +inline void RepeatedField<Element>::AddAlreadyReserved(const Element& value) { + GOOGLE_DCHECK_LT(current_size_, total_size_); + elements()[current_size_++] = value; +} + +template <typename Element> +inline Element* RepeatedField<Element>::AddAlreadyReserved() { + GOOGLE_DCHECK_LT(current_size_, total_size_); + return &elements()[current_size_++]; +} + +template <typename Element> +inline Element* RepeatedField<Element>::AddNAlreadyReserved(int n) { + GOOGLE_DCHECK_GE(total_size_ - current_size_, n) + << total_size_ << ", " << current_size_; + // Warning: sometimes people call this when n == 0 and total_size_ == 0. In + // this case the return pointer points to a zero size array (n == 0). Hence + // we can just use unsafe_elements(), because the user cannot dereference the + // pointer anyway. + Element* ret = unsafe_elements() + current_size_; + current_size_ += n; + return ret; +} + +template <typename Element> +inline void RepeatedField<Element>::Resize(int new_size, const Element& value) { + GOOGLE_DCHECK_GE(new_size, 0); + if (new_size > current_size_) { + Reserve(new_size); + std::fill(&elements()[current_size_], &elements()[new_size], value); + } + current_size_ = new_size; +} + +template <typename Element> +inline const Element& RepeatedField<Element>::Get(int index) const { + GOOGLE_DCHECK_GE(index, 0); + GOOGLE_DCHECK_LT(index, current_size_); + return elements()[index]; +} + +template <typename Element> +inline const Element& RepeatedField<Element>::at(int index) const { + GOOGLE_CHECK_GE(index, 0); + GOOGLE_CHECK_LT(index, current_size_); + return elements()[index]; +} + +template <typename Element> +inline Element& RepeatedField<Element>::at(int index) { + GOOGLE_CHECK_GE(index, 0); + GOOGLE_CHECK_LT(index, current_size_); + return elements()[index]; +} + +template <typename Element> +inline Element* RepeatedField<Element>::Mutable(int index) { + GOOGLE_DCHECK_GE(index, 0); + GOOGLE_DCHECK_LT(index, current_size_); + return &elements()[index]; +} + +template <typename Element> +inline void RepeatedField<Element>::Set(int index, const Element& value) { + GOOGLE_DCHECK_GE(index, 0); + GOOGLE_DCHECK_LT(index, current_size_); + elements()[index] = value; +} + +template <typename Element> +inline void RepeatedField<Element>::Add(const Element& value) { + arc_ui32 size = current_size_; + if (static_cast<int>(size) == total_size_) { + // value could reference an element of the array. Reserving new space will + // invalidate the reference. So we must make a copy first. + auto tmp = value; + Reserve(total_size_ + 1); + elements()[size] = std::move(tmp); + } else { + elements()[size] = value; + } + current_size_ = size + 1; +} + +template <typename Element> +inline Element* RepeatedField<Element>::Add() { + arc_ui32 size = current_size_; + if (static_cast<int>(size) == total_size_) Reserve(total_size_ + 1); + auto ptr = &elements()[size]; + current_size_ = size + 1; + return ptr; +} + +template <typename Element> +template <typename Iter> +inline void RepeatedField<Element>::Add(Iter begin, Iter end) { + int reserve = internal::CalculateReserve(begin, end); + if (reserve != -1) { + if (reserve == 0) { + return; + } + + Reserve(reserve + size()); + // TODO(ckennelly): The compiler loses track of the buffer freshly + // allocated by Reserve() by the time we call elements, so it cannot + // guarantee that elements does not alias [begin(), end()). + // + // If restrict is available, annotating the pointer obtained from elements() + // causes this to lower to memcpy instead of memmove. + std::copy(begin, end, elements() + size()); + current_size_ = reserve + size(); + } else { + FastAdder fast_adder(this); + for (; begin != end; ++begin) fast_adder.Add(*begin); + } +} + +template <typename Element> +inline void RepeatedField<Element>::RemoveLast() { + GOOGLE_DCHECK_GT(current_size_, 0); + current_size_--; +} + +template <typename Element> +void RepeatedField<Element>::ExtractSubrange(int start, int num, + Element* elements) { + GOOGLE_DCHECK_GE(start, 0); + GOOGLE_DCHECK_GE(num, 0); + GOOGLE_DCHECK_LE(start + num, this->current_size_); + + // Save the values of the removed elements if requested. + if (elements != nullptr) { + for (int i = 0; i < num; ++i) elements[i] = this->Get(i + start); + } + + // Slide remaining elements down to fill the gap. + if (num > 0) { + for (int i = start + num; i < this->current_size_; ++i) + this->Set(i - num, this->Get(i)); + this->Truncate(this->current_size_ - num); + } +} + +template <typename Element> +inline void RepeatedField<Element>::Clear() { + current_size_ = 0; +} + +template <typename Element> +inline void RepeatedField<Element>::MergeFrom(const RepeatedField& other) { + GOOGLE_DCHECK_NE(&other, this); + if (other.current_size_ != 0) { + int existing_size = size(); + Reserve(existing_size + other.size()); + AddNAlreadyReserved(other.size()); + CopyArray(Mutable(existing_size), &other.Get(0), other.size()); + } +} + +template <typename Element> +inline void RepeatedField<Element>::CopyFrom(const RepeatedField& other) { + if (&other == this) return; + Clear(); + MergeFrom(other); +} + +template <typename Element> +template <typename Iter> +inline void RepeatedField<Element>::Assign(Iter begin, Iter end) { + Clear(); + Add(begin, end); +} + +template <typename Element> +inline typename RepeatedField<Element>::iterator RepeatedField<Element>::erase( + const_iterator position) { + return erase(position, position + 1); +} + +template <typename Element> +inline typename RepeatedField<Element>::iterator RepeatedField<Element>::erase( + const_iterator first, const_iterator last) { + size_type first_offset = first - cbegin(); + if (first != last) { + Truncate(std::copy(last, cend(), begin() + first_offset) - cbegin()); + } + return begin() + first_offset; +} + +template <typename Element> +inline Element* RepeatedField<Element>::mutable_data() { + return unsafe_elements(); +} + +template <typename Element> +inline const Element* RepeatedField<Element>::data() const { + return unsafe_elements(); +} + +template <typename Element> +inline void RepeatedField<Element>::InternalSwap(RepeatedField* other) { + GOOGLE_DCHECK(this != other); + + // Swap all fields at once. + static_assert(std::is_standard_layout<RepeatedField<Element>>::value, + "offsetof() requires standard layout before c++17"); + internal::memswap<offsetof(RepeatedField, arena_or_elements_) + + sizeof(this->arena_or_elements_) - + offsetof(RepeatedField, current_size_)>( + reinterpret_cast<char*>(this) + offsetof(RepeatedField, current_size_), + reinterpret_cast<char*>(other) + offsetof(RepeatedField, current_size_)); +} + +template <typename Element> +void RepeatedField<Element>::Swap(RepeatedField* other) { + if (this == other) return; +#ifdef PROTOBUF_FORCE_COPY_IN_SWAP + if (GetArena() != nullptr && GetArena() == other->GetArena()) { +#else // PROTOBUF_FORCE_COPY_IN_SWAP + if (GetArena() == other->GetArena()) { +#endif // !PROTOBUF_FORCE_COPY_IN_SWAP + InternalSwap(other); + } else { + RepeatedField<Element> temp(other->GetArena()); + temp.MergeFrom(*this); + CopyFrom(*other); + other->UnsafeArenaSwap(&temp); + } +} + +template <typename Element> +void RepeatedField<Element>::UnsafeArenaSwap(RepeatedField* other) { + if (this == other) return; + InternalSwap(other); +} + +template <typename Element> +void RepeatedField<Element>::SwapElements(int index1, int index2) { + using std::swap; // enable ADL with fallback + swap(elements()[index1], elements()[index2]); +} + +template <typename Element> +inline typename RepeatedField<Element>::iterator +RepeatedField<Element>::begin() { + return unsafe_elements(); +} +template <typename Element> +inline typename RepeatedField<Element>::const_iterator +RepeatedField<Element>::begin() const { + return unsafe_elements(); +} +template <typename Element> +inline typename RepeatedField<Element>::const_iterator +RepeatedField<Element>::cbegin() const { + return unsafe_elements(); +} +template <typename Element> +inline typename RepeatedField<Element>::iterator RepeatedField<Element>::end() { + return unsafe_elements() + current_size_; +} +template <typename Element> +inline typename RepeatedField<Element>::const_iterator +RepeatedField<Element>::end() const { + return unsafe_elements() + current_size_; +} +template <typename Element> +inline typename RepeatedField<Element>::const_iterator +RepeatedField<Element>::cend() const { + return unsafe_elements() + current_size_; +} + +template <typename Element> +inline size_t RepeatedField<Element>::SpaceUsedExcludingSelfLong() const { + return total_size_ > 0 ? (total_size_ * sizeof(Element) + kRepHeaderSize) : 0; +} + +namespace internal { +// Returns the new size for a reserved field based on its 'total_size' and the +// requested 'new_size'. The result is clamped to the closed interval: +// [internal::kMinRepeatedFieldAllocationSize, +// std::numeric_limits<int>::max()] +// Requires: +// new_size > total_size && +// (total_size == 0 || +// total_size >= kRepeatedFieldLowerClampLimit) +inline int CalculateReserveSize(int total_size, int new_size) { + if (new_size < kRepeatedFieldLowerClampLimit) { + // Clamp to smallest allowed size. + return kRepeatedFieldLowerClampLimit; + } + if (total_size < kRepeatedFieldUpperClampLimit) { + return std::max(total_size * 2, new_size); + } else { + // Clamp to largest allowed size. + GOOGLE_DCHECK_GT(new_size, kRepeatedFieldUpperClampLimit); + return std::numeric_limits<int>::max(); + } +} +} // namespace internal + +// Avoid inlining of Reserve(): new, copy, and delete[] lead to a significant +// amount of code bloat. +template <typename Element> +void RepeatedField<Element>::Reserve(int new_size) { + if (total_size_ >= new_size) return; + Rep* old_rep = total_size_ > 0 ? rep() : nullptr; + Rep* new_rep; + Arena* arena = GetArena(); + new_size = internal::CalculateReserveSize(total_size_, new_size); + GOOGLE_DCHECK_LE( + static_cast<size_t>(new_size), + (std::numeric_limits<size_t>::max() - kRepHeaderSize) / sizeof(Element)) + << "Requested size is too large to fit into size_t."; + size_t bytes = + kRepHeaderSize + sizeof(Element) * static_cast<size_t>(new_size); + if (arena == nullptr) { + new_rep = static_cast<Rep*>(::operator new(bytes)); + } else { + new_rep = reinterpret_cast<Rep*>(Arena::CreateArray<char>(arena, bytes)); + } + new_rep->arena = arena; + int old_total_size = total_size_; + // Already known: new_size >= internal::kMinRepeatedFieldAllocationSize + // Maintain invariant: + // total_size_ == 0 || + // total_size_ >= internal::kMinRepeatedFieldAllocationSize + total_size_ = new_size; + arena_or_elements_ = new_rep->elements; + // Invoke placement-new on newly allocated elements. We shouldn't have to do + // this, since Element is supposed to be POD, but a previous version of this + // code allocated storage with "new Element[size]" and some code uses + // RepeatedField with non-POD types, relying on constructor invocation. If + // Element has a trivial constructor (e.g., arc_i32), gcc (tested with -O2) + // completely removes this loop because the loop body is empty, so this has no + // effect unless its side-effects are required for correctness. + // Note that we do this before MoveArray() below because Element's copy + // assignment implementation will want an initialized instance first. + Element* e = &elements()[0]; + Element* limit = e + total_size_; + for (; e < limit; e++) { + new (e) Element; + } + if (current_size_ > 0) { + MoveArray(&elements()[0], old_rep->elements, current_size_); + } + + // Likewise, we need to invoke destructors on the old array. + InternalDeallocate(old_rep, old_total_size); + +} + +template <typename Element> +inline void RepeatedField<Element>::Truncate(int new_size) { + GOOGLE_DCHECK_LE(new_size, current_size_); + if (current_size_ > 0) { + current_size_ = new_size; + } +} + +template <typename Element> +inline void RepeatedField<Element>::MoveArray(Element* to, Element* from, + int array_size) { + CopyArray(to, from, array_size); +} + +template <typename Element> +inline void RepeatedField<Element>::CopyArray(Element* to, const Element* from, + int array_size) { + internal::ElementCopier<Element>()(to, from, array_size); +} + +namespace internal { + +template <typename Element, bool HasTrivialCopy> +void ElementCopier<Element, HasTrivialCopy>::operator()(Element* to, + const Element* from, + int array_size) { + std::copy(from, from + array_size, to); +} + +template <typename Element> +struct ElementCopier<Element, true> { + void operator()(Element* to, const Element* from, int array_size) { + memcpy(to, from, static_cast<size_t>(array_size) * sizeof(Element)); + } +}; + +} // namespace internal + + +// ------------------------------------------------------------------- + +// Iterators and helper functions that follow the spirit of the STL +// std::back_insert_iterator and std::back_inserter but are tailor-made +// for RepeatedField and RepeatedPtrField. Typical usage would be: +// +// std::copy(some_sequence.begin(), some_sequence.end(), +// RepeatedFieldBackInserter(proto.mutable_sequence())); +// +// Ported by johannes from util/gtl/proto-array-iterators.h + +namespace internal { +// A back inserter for RepeatedField objects. +template <typename T> +class RepeatedFieldBackInsertIterator { + public: + using iterator_category = std::output_iterator_tag; + using value_type = T; + using pointer = void; + using reference = void; + using difference_type = std::ptrdiff_t; + + explicit RepeatedFieldBackInsertIterator( + RepeatedField<T>* const mutable_field) + : field_(mutable_field) {} + RepeatedFieldBackInsertIterator<T>& operator=(const T& value) { + field_->Add(value); + return *this; + } + RepeatedFieldBackInsertIterator<T>& operator*() { return *this; } + RepeatedFieldBackInsertIterator<T>& operator++() { return *this; } + RepeatedFieldBackInsertIterator<T>& operator++(int /* unused */) { + return *this; + } + + private: + RepeatedField<T>* field_; +}; + +} // namespace internal + +// Provides a back insert iterator for RepeatedField instances, +// similar to std::back_inserter(). +template <typename T> +internal::RepeatedFieldBackInsertIterator<T> RepeatedFieldBackInserter( + RepeatedField<T>* const mutable_field) { + return internal::RepeatedFieldBackInsertIterator<T>(mutable_field); +} + +// Extern declarations of common instantiations to reduce library bloat. +extern template class PROTOBUF_EXPORT_TEMPLATE_DECLARE RepeatedField<bool>; +extern template class PROTOBUF_EXPORT_TEMPLATE_DECLARE RepeatedField<arc_i32>; +extern template class PROTOBUF_EXPORT_TEMPLATE_DECLARE RepeatedField<arc_ui32>; +extern template class PROTOBUF_EXPORT_TEMPLATE_DECLARE RepeatedField<arc_i64>; +extern template class PROTOBUF_EXPORT_TEMPLATE_DECLARE RepeatedField<arc_ui64>; +extern template class PROTOBUF_EXPORT_TEMPLATE_DECLARE RepeatedField<float>; +extern template class PROTOBUF_EXPORT_TEMPLATE_DECLARE RepeatedField<double>; + +} // namespace protobuf +} // namespace google + +#include <google/protobuf/port_undef.inc> + +#endif // GOOGLE_PROTOBUF_REPEATED_FIELD_H__ diff --git a/contrib/libs/protobuf_old/src/google/protobuf/repeated_ptr_field.cc b/contrib/libs/protobuf_old/src/google/protobuf/repeated_ptr_field.cc new file mode 100644 index 0000000000..b94b094d48 --- /dev/null +++ b/contrib/libs/protobuf_old/src/google/protobuf/repeated_ptr_field.cc @@ -0,0 +1,157 @@ +// 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: kenton@google.com (Kenton Varda) +// Based on original Protocol Buffers design by +// Sanjay Ghemawat, Jeff Dean, and others. + +#include <google/protobuf/repeated_field.h> + +#include <algorithm> + +#include <google/protobuf/stubs/logging.h> +#include <google/protobuf/stubs/common.h> +#include <google/protobuf/implicit_weak_message.h> + +#include <google/protobuf/port_def.inc> + +namespace google { +namespace protobuf { + +namespace internal { + +void** RepeatedPtrFieldBase::InternalExtend(int extend_amount) { + int new_size = current_size_ + extend_amount; + if (total_size_ >= new_size) { + // N.B.: rep_ is non-nullptr because extend_amount is always > 0, hence + // total_size must be non-zero since it is lower-bounded by new_size. + return &rep_->elements[current_size_]; + } + Rep* old_rep = rep_; + Arena* arena = GetArena(); + new_size = std::max(internal::kRepeatedFieldLowerClampLimit, + std::max(total_size_ * 2, new_size)); + GOOGLE_CHECK_LE(static_cast<arc_i64>(new_size), + static_cast<arc_i64>( + (std::numeric_limits<size_t>::max() - kRepHeaderSize) / + sizeof(old_rep->elements[0]))) + << "Requested size is too large to fit into size_t."; + size_t bytes = kRepHeaderSize + sizeof(old_rep->elements[0]) * new_size; + if (arena == nullptr) { + rep_ = reinterpret_cast<Rep*>(::operator new(bytes)); + } else { + rep_ = reinterpret_cast<Rep*>(Arena::CreateArray<char>(arena, bytes)); + } +#if defined(__GXX_DELETE_WITH_SIZE__) || defined(__cpp_sized_deallocation) + const int old_total_size = total_size_; +#endif + total_size_ = new_size; + if (old_rep && old_rep->allocated_size > 0) { + memcpy(rep_->elements, old_rep->elements, + old_rep->allocated_size * sizeof(rep_->elements[0])); + rep_->allocated_size = old_rep->allocated_size; + } else { + rep_->allocated_size = 0; + } + if (arena == nullptr) { +#if defined(__GXX_DELETE_WITH_SIZE__) || defined(__cpp_sized_deallocation) + const size_t old_size = + old_total_size * sizeof(rep_->elements[0]) + kRepHeaderSize; + ::operator delete(static_cast<void*>(old_rep), old_size); +#else + ::operator delete(static_cast<void*>(old_rep)); +#endif + } + return &rep_->elements[current_size_]; +} + +void RepeatedPtrFieldBase::Reserve(int new_size) { + if (new_size > current_size_) { + InternalExtend(new_size - current_size_); + } +} + +void RepeatedPtrFieldBase::DestroyProtos() { + GOOGLE_DCHECK(rep_); + GOOGLE_DCHECK(arena_ == nullptr); + int n = rep_->allocated_size; + void* const* elements = rep_->elements; + for (int i = 0; i < n; i++) { + delete static_cast<MessageLite*>(elements[i]); + } +#if defined(__GXX_DELETE_WITH_SIZE__) || defined(__cpp_sized_deallocation) + const size_t size = total_size_ * sizeof(elements[0]) + kRepHeaderSize; + ::operator delete(static_cast<void*>(rep_), size); + rep_ = nullptr; +#else + ::operator delete(static_cast<void*>(rep_)); + rep_ = nullptr; +#endif +} + +void* RepeatedPtrFieldBase::AddOutOfLineHelper(void* obj) { + if (!rep_ || rep_->allocated_size == total_size_) { + InternalExtend(1); // Equivalent to "Reserve(total_size_ + 1)" + } + ++rep_->allocated_size; + rep_->elements[current_size_++] = obj; + return obj; +} + +void RepeatedPtrFieldBase::CloseGap(int start, int num) { + if (rep_ == nullptr) return; + // Close up a gap of "num" elements starting at offset "start". + for (int i = start + num; i < rep_->allocated_size; ++i) + rep_->elements[i - num] = rep_->elements[i]; + current_size_ -= num; + rep_->allocated_size -= num; +} + +MessageLite* RepeatedPtrFieldBase::AddWeak(const MessageLite* prototype) { + if (rep_ != nullptr && current_size_ < rep_->allocated_size) { + return reinterpret_cast<MessageLite*>(rep_->elements[current_size_++]); + } + if (!rep_ || rep_->allocated_size == total_size_) { + Reserve(total_size_ + 1); + } + ++rep_->allocated_size; + MessageLite* result = prototype + ? prototype->New(arena_) + : Arena::CreateMessage<ImplicitWeakMessage>(arena_); + rep_->elements[current_size_++] = result; + return result; +} + +} // namespace internal + +} // namespace protobuf +} // namespace google + +#include <google/protobuf/port_undef.inc> diff --git a/contrib/libs/protobuf_old/src/google/protobuf/repeated_ptr_field.h b/contrib/libs/protobuf_old/src/google/protobuf/repeated_ptr_field.h new file mode 100644 index 0000000000..6c38172fd3 --- /dev/null +++ b/contrib/libs/protobuf_old/src/google/protobuf/repeated_ptr_field.h @@ -0,0 +1,2027 @@ +// 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: kenton@google.com (Kenton Varda) +// Based on original Protocol Buffers design by +// Sanjay Ghemawat, Jeff Dean, and others. +// +// RepeatedField and RepeatedPtrField are used by generated protocol message +// classes to manipulate repeated fields. These classes are very similar to +// STL's vector, but include a number of optimizations found to be useful +// specifically in the case of Protocol Buffers. RepeatedPtrField is +// particularly different from STL vector as it manages ownership of the +// pointers that it contains. +// +// Typically, clients should not need to access RepeatedField objects directly, +// but should instead use the accessor functions generated automatically by the +// protocol compiler. +// +// This header covers RepeatedPtrField. + +#ifndef GOOGLE_PROTOBUF_REPEATED_PTR_FIELD_H__ +#define GOOGLE_PROTOBUF_REPEATED_PTR_FIELD_H__ + +#include <utility> +#ifdef _MSC_VER +// This is required for min/max on VS2013 only. +#include <algorithm> +#endif + +#include <iterator> +#include <limits> +#include <string> +#include <type_traits> + +#include <google/protobuf/stubs/logging.h> +#include <google/protobuf/stubs/common.h> +#include <google/protobuf/arena.h> +#include <google/protobuf/message_lite.h> +#include <google/protobuf/port.h> + + +// Must be included last. +#include <google/protobuf/port_def.inc> + +#ifdef SWIG +#error "You cannot SWIG proto headers" +#endif + +namespace google { +namespace protobuf { + +class Message; +class Reflection; + +template <typename T> +struct WeakRepeatedPtrField; + +namespace internal { + +class MergePartialFromCodedStreamHelper; +class SwapFieldHelper; + + +} // namespace internal + +namespace internal { +template <typename It> +class RepeatedPtrIterator; +template <typename It, typename VoidPtr> +class RepeatedPtrOverPtrsIterator; +} // namespace internal + +namespace internal { + +// type-traits helper for RepeatedPtrFieldBase: we only want to invoke +// arena-related "copy if on different arena" behavior if the necessary methods +// exist on the contained type. In particular, we rely on MergeFrom() existing +// as a general proxy for the fact that a copy will work, and we also provide a +// specific override for TProtoStringType*. +template <typename T> +struct TypeImplementsMergeBehaviorProbeForMergeFrom { + typedef char HasMerge; + typedef long HasNoMerge; + + // We accept either of: + // - void MergeFrom(const T& other) + // - bool MergeFrom(const T& other) + // + // We mangle these names a bit to avoid compatibility issues in 'unclean' + // include environments that may have, e.g., "#define test ..." (yes, this + // exists). + template <typename U, typename RetType, RetType (U::*)(const U& arg)> + struct CheckType; + template <typename U> + static HasMerge Check(CheckType<U, void, &U::MergeFrom>*); + template <typename U> + static HasMerge Check(CheckType<U, bool, &U::MergeFrom>*); + template <typename U> + static HasNoMerge Check(...); + + // Resolves to either std::true_type or std::false_type. + typedef std::integral_constant<bool, + (sizeof(Check<T>(0)) == sizeof(HasMerge))> + type; +}; + +template <typename T, typename = void> +struct TypeImplementsMergeBehavior + : TypeImplementsMergeBehaviorProbeForMergeFrom<T> {}; + + +template <> +struct TypeImplementsMergeBehavior<TProtoStringType> { + typedef std::true_type type; +}; + +template <typename T> +struct IsMovable + : std::integral_constant<bool, std::is_move_constructible<T>::value && + std::is_move_assignable<T>::value> {}; + +// This is the common base class for RepeatedPtrFields. It deals only in void* +// pointers. Users should not use this interface directly. +// +// The methods of this interface correspond to the methods of RepeatedPtrField, +// but may have a template argument called TypeHandler. Its signature is: +// class TypeHandler { +// public: +// typedef MyType Type; +// static Type* New(); +// static Type* NewFromPrototype(const Type* prototype, +// Arena* arena); +// static void Delete(Type*); +// static void Clear(Type*); +// static void Merge(const Type& from, Type* to); +// +// // Only needs to be implemented if SpaceUsedExcludingSelf() is called. +// static int SpaceUsedLong(const Type&); +// }; +class PROTOBUF_EXPORT RepeatedPtrFieldBase { + protected: + constexpr RepeatedPtrFieldBase(); + explicit RepeatedPtrFieldBase(Arena* arena); + ~RepeatedPtrFieldBase() { +#ifndef NDEBUG + // Try to trigger segfault / asan failure in non-opt builds. If arena_ + // lifetime has ended before the destructor. + if (arena_) (void)arena_->SpaceAllocated(); +#endif + } + + // Must be called from destructor. + template <typename TypeHandler> + void Destroy(); + bool NeedsDestroy() const { return rep_ != nullptr && arena_ == nullptr; } + void DestroyProtos(); + + bool empty() const; + int size() const; + + template <typename TypeHandler> + const typename TypeHandler::Type& at(int index) const; + template <typename TypeHandler> + typename TypeHandler::Type& at(int index); + + template <typename TypeHandler> + typename TypeHandler::Type* Mutable(int index); + template <typename TypeHandler> + void Delete(int index); + template <typename TypeHandler> + typename TypeHandler::Type* Add( + typename TypeHandler::Type* prototype = nullptr); + + public: + // The next few methods are public so that they can be called from generated + // code when implicit weak fields are used, but they should never be called by + // application code. + + template <typename TypeHandler> + const typename TypeHandler::Type& Get(int index) const; + + // Creates and adds an element using the given prototype, without introducing + // a link-time dependency on the concrete message type. This method is used to + // implement implicit weak fields. The prototype may be nullptr, in which case + // an ImplicitWeakMessage will be used as a placeholder. + MessageLite* AddWeak(const MessageLite* prototype); + + template <typename TypeHandler> + void Clear(); + + template <typename TypeHandler> + void MergeFrom(const RepeatedPtrFieldBase& other); + + inline void InternalSwap(RepeatedPtrFieldBase*); + + protected: + template < + typename TypeHandler, + typename std::enable_if<TypeHandler::Movable::value>::type* = nullptr> + void Add(typename TypeHandler::Type&& value); + + template <typename TypeHandler> + void RemoveLast(); + template <typename TypeHandler> + void CopyFrom(const RepeatedPtrFieldBase& other); + + void CloseGap(int start, int num); + + void Reserve(int new_size); + + template<typename TypeHandler> + void Truncate(int new_size) { + GOOGLE_DCHECK_LE(new_size, current_size_); + for (int i = new_size; i < current_size_; i++) { + TypeHandler::Clear(cast<TypeHandler>(rep_->elements[i])); + } + current_size_ = new_size; + } + + int Capacity() const; + + template <typename TypeHandler> + static inline typename TypeHandler::Type* copy( + typename TypeHandler::Type* value) { + auto* new_value = TypeHandler::NewFromPrototype(value, nullptr); + TypeHandler::Merge(*value, new_value); + return new_value; + } + + // Used for constructing iterators. + void* const* raw_data() const; + void** raw_mutable_data() const; + + template <typename TypeHandler> + typename TypeHandler::Type** mutable_data(); + template <typename TypeHandler> + const typename TypeHandler::Type* const* data() const; + + template <typename TypeHandler> + PROTOBUF_NDEBUG_INLINE void Swap(RepeatedPtrFieldBase* other); + + void SwapElements(int index1, int index2); + + template <typename TypeHandler> + size_t SpaceUsedExcludingSelfLong() const; + + // Advanced memory management -------------------------------------- + + // Like Add(), but if there are no cleared objects to use, returns nullptr. + template <typename TypeHandler> + typename TypeHandler::Type* AddFromCleared(); + + template <typename TypeHandler> + void AddAllocated(typename TypeHandler::Type* value) { + typename TypeImplementsMergeBehavior<typename TypeHandler::Type>::type t; + AddAllocatedInternal<TypeHandler>(value, t); + } + + template <typename TypeHandler> + void UnsafeArenaAddAllocated(typename TypeHandler::Type* value); + + template <typename TypeHandler> + PROTOBUF_NODISCARD typename TypeHandler::Type* ReleaseLast() { + typename TypeImplementsMergeBehavior<typename TypeHandler::Type>::type t; + return ReleaseLastInternal<TypeHandler>(t); + } + + // Releases last element and returns it, but does not do out-of-arena copy. + // And just returns the raw pointer to the contained element in the arena. + template <typename TypeHandler> + typename TypeHandler::Type* UnsafeArenaReleaseLast(); + + int ClearedCount() const; + template <typename TypeHandler> + void AddCleared(typename TypeHandler::Type* value); + template <typename TypeHandler> + PROTOBUF_NODISCARD typename TypeHandler::Type* ReleaseCleared(); + + template <typename TypeHandler> + void AddAllocatedInternal(typename TypeHandler::Type* value, std::true_type); + template <typename TypeHandler> + void AddAllocatedInternal(typename TypeHandler::Type* value, std::false_type); + + template <typename TypeHandler> + PROTOBUF_NOINLINE void AddAllocatedSlowWithCopy( + typename TypeHandler::Type* value, Arena* value_arena, Arena* my_arena); + template <typename TypeHandler> + PROTOBUF_NOINLINE void AddAllocatedSlowWithoutCopy( + typename TypeHandler::Type* value); + + template <typename TypeHandler> + typename TypeHandler::Type* ReleaseLastInternal(std::true_type); + template <typename TypeHandler> + typename TypeHandler::Type* ReleaseLastInternal(std::false_type); + + template <typename TypeHandler> + PROTOBUF_NOINLINE void SwapFallback(RepeatedPtrFieldBase* other); + + inline Arena* GetArena() const { return arena_; } + + private: + static constexpr int kInitialSize = 0; + // A few notes on internal representation: + // + // We use an indirected approach, with struct Rep, to keep + // sizeof(RepeatedPtrFieldBase) equivalent to what it was before arena support + // was added, namely, 3 8-byte machine words on x86-64. An instance of Rep is + // allocated only when the repeated field is non-empty, and it is a + // dynamically-sized struct (the header is directly followed by elements[]). + // We place arena_ and current_size_ directly in the object to avoid cache + // misses due to the indirection, because these fields are checked frequently. + // Placing all fields directly in the RepeatedPtrFieldBase instance costs + // significant performance for memory-sensitive workloads. + Arena* arena_; + int current_size_; + int total_size_; + struct Rep { + int allocated_size; + // Here we declare a huge array as a way of approximating C's "flexible + // array member" feature without relying on undefined behavior. + void* elements[(std::numeric_limits<int>::max() - 2 * sizeof(int)) / + sizeof(void*)]; + }; + static constexpr size_t kRepHeaderSize = offsetof(Rep, elements); + Rep* rep_; + + template <typename TypeHandler> + static inline typename TypeHandler::Type* cast(void* element) { + return reinterpret_cast<typename TypeHandler::Type*>(element); + } + template <typename TypeHandler> + static inline const typename TypeHandler::Type* cast(const void* element) { + return reinterpret_cast<const typename TypeHandler::Type*>(element); + } + + // Non-templated inner function to avoid code duplication. Takes a function + // pointer to the type-specific (templated) inner allocate/merge loop. + void MergeFromInternal(const RepeatedPtrFieldBase& other, + void (RepeatedPtrFieldBase::*inner_loop)(void**, + void**, int, + int)); + + template <typename TypeHandler> + PROTOBUF_NOINLINE void MergeFromInnerLoop(void** our_elems, + void** other_elems, int length, + int already_allocated); + + // Internal helper: extend array space if necessary to contain |extend_amount| + // more elements, and return a pointer to the element immediately following + // the old list of elements. This interface factors out common behavior from + // Reserve() and MergeFrom() to reduce code size. |extend_amount| must be > 0. + void** InternalExtend(int extend_amount); + + // Internal helper for Add: add "obj" as the next element in the + // array, including potentially resizing the array with Reserve if + // needed + void* AddOutOfLineHelper(void* obj); + + // The reflection implementation needs to call protected methods directly, + // reinterpreting pointers as being to Message instead of a specific Message + // subclass. + friend class ::PROTOBUF_NAMESPACE_ID::Reflection; + friend class ::PROTOBUF_NAMESPACE_ID::internal::SwapFieldHelper; + + // ExtensionSet stores repeated message extensions as + // RepeatedPtrField<MessageLite>, but non-lite ExtensionSets need to implement + // SpaceUsedLong(), and thus need to call SpaceUsedExcludingSelfLong() + // reinterpreting MessageLite as Message. ExtensionSet also needs to make use + // of AddFromCleared(), which is not part of the public interface. + friend class ExtensionSet; + + // The MapFieldBase implementation needs to call protected methods directly, + // reinterpreting pointers as being to Message instead of a specific Message + // subclass. + friend class MapFieldBase; + friend class MapFieldBaseStub; + + // The table-driven MergePartialFromCodedStream implementation needs to + // operate on RepeatedPtrField<MessageLite>. + friend class MergePartialFromCodedStreamHelper; + friend class AccessorHelper; + template <typename T> + friend struct google::protobuf::WeakRepeatedPtrField; + + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(RepeatedPtrFieldBase); +}; + +template <typename GenericType> +class GenericTypeHandler { + public: + typedef GenericType Type; + using Movable = IsMovable<GenericType>; + + static inline GenericType* New(Arena* arena) { + return Arena::CreateMaybeMessage<Type>(arena); + } + static inline GenericType* New(Arena* arena, GenericType&& value) { + return Arena::Create<GenericType>(arena, std::move(value)); + } + static inline GenericType* NewFromPrototype(const GenericType* prototype, + Arena* arena = nullptr); + static inline void Delete(GenericType* value, Arena* arena) { + if (arena == nullptr) { + delete value; + } + } + static inline Arena* GetOwningArena(GenericType* value) { + return Arena::GetOwningArena<Type>(value); + } + + static inline void Clear(GenericType* value) { value->Clear(); } + PROTOBUF_NOINLINE + static void Merge(const GenericType& from, GenericType* to); + static inline size_t SpaceUsedLong(const GenericType& value) { + return value.SpaceUsedLong(); + } +}; + +template <typename GenericType> +GenericType* GenericTypeHandler<GenericType>::NewFromPrototype( + const GenericType* /* prototype */, Arena* arena) { + return New(arena); +} +template <typename GenericType> +void GenericTypeHandler<GenericType>::Merge(const GenericType& from, + GenericType* to) { + to->MergeFrom(from); +} + +// NewFromPrototype() and Merge() are not defined inline here, as we will need +// to do a virtual function dispatch anyways to go from Message* to call +// New/Merge. +template <> +MessageLite* GenericTypeHandler<MessageLite>::NewFromPrototype( + const MessageLite* prototype, Arena* arena); +template <> +inline Arena* GenericTypeHandler<MessageLite>::GetOwningArena( + MessageLite* value) { + return value->GetOwningArena(); +} +template <> +void GenericTypeHandler<MessageLite>::Merge(const MessageLite& from, + MessageLite* to); +template <> +inline void GenericTypeHandler<TProtoStringType>::Clear(TProtoStringType* value) { + value->clear(); +} +template <> +void GenericTypeHandler<TProtoStringType>::Merge(const TProtoStringType& from, + TProtoStringType* to); + +// Message specialization bodies defined in message.cc. This split is necessary +// to allow proto2-lite (which includes this header) to be independent of +// Message. +template <> +PROTOBUF_EXPORT Message* GenericTypeHandler<Message>::NewFromPrototype( + const Message* prototype, Arena* arena); +template <> +PROTOBUF_EXPORT Arena* GenericTypeHandler<Message>::GetOwningArena( + Message* value); + +class StringTypeHandler { + public: + typedef TProtoStringType Type; + using Movable = IsMovable<Type>; + + static inline TProtoStringType* New(Arena* arena) { + return Arena::Create<TProtoStringType>(arena); + } + static inline TProtoStringType* New(Arena* arena, TProtoStringType&& value) { + return Arena::Create<TProtoStringType>(arena, std::move(value)); + } + static inline TProtoStringType* NewFromPrototype(const TProtoStringType*, + Arena* arena) { + return New(arena); + } + static inline Arena* GetOwningArena(TProtoStringType*) { return nullptr; } + static inline void Delete(TProtoStringType* value, Arena* arena) { + if (arena == nullptr) { + delete value; + } + } + static inline void Clear(TProtoStringType* value) { value->clear(); } + static inline void Merge(const TProtoStringType& from, TProtoStringType* to) { + *to = from; + } + static size_t SpaceUsedLong(const TProtoStringType& value) { + return sizeof(value) + StringSpaceUsedExcludingSelfLong(value); + } +}; + +} // namespace internal + +// RepeatedPtrField is like RepeatedField, but used for repeated strings or +// Messages. +template <typename Element> +class RepeatedPtrField : private internal::RepeatedPtrFieldBase { + public: + constexpr RepeatedPtrField(); + explicit RepeatedPtrField(Arena* arena); + + RepeatedPtrField(const RepeatedPtrField& other); + + template <typename Iter, + typename = typename std::enable_if<std::is_constructible< + Element, decltype(*std::declval<Iter>())>::value>::type> + RepeatedPtrField(Iter begin, Iter end); + + ~RepeatedPtrField(); + + RepeatedPtrField& operator=(const RepeatedPtrField& other); + + RepeatedPtrField(RepeatedPtrField&& other) noexcept; + RepeatedPtrField& operator=(RepeatedPtrField&& other) noexcept; + + bool empty() const; + int size() const; + + const Element& Get(int index) const; + Element* Mutable(int index); + Element* Add(); + void Add(Element&& value); + // Append elements in the range [begin, end) after reserving + // the appropriate number of elements. + template <typename Iter> + void Add(Iter begin, Iter end); + + const Element& operator[](int index) const { return Get(index); } + Element& operator[](int index) { return *Mutable(index); } + + const Element& at(int index) const; + Element& at(int index); + + // Remove the last element in the array. + // Ownership of the element is retained by the array. + void RemoveLast(); + + // Delete elements with indices in the range [start .. start+num-1]. + // Caution: implementation moves all elements with indices [start+num .. ]. + // Calling this routine inside a loop can cause quadratic behavior. + void DeleteSubrange(int start, int num); + + PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear(); + void MergeFrom(const RepeatedPtrField& other); + PROTOBUF_ATTRIBUTE_REINITIALIZES void CopyFrom(const RepeatedPtrField& other); + + // Replaces the contents with RepeatedPtrField(begin, end). + template <typename Iter> + PROTOBUF_ATTRIBUTE_REINITIALIZES void Assign(Iter begin, Iter end); + + // Reserve space to expand the field to at least the given size. This only + // resizes the pointer array; it doesn't allocate any objects. If the + // array is grown, it will always be at least doubled in size. + void Reserve(int new_size); + + void Truncate(int new_size) { + return RepeatedPtrFieldBase::Truncate<TypeHandler>(new_size); + } + + int Capacity() const; + + // Gets the underlying array. This pointer is possibly invalidated by + // any add or remove operation. + Element** mutable_data(); + const Element* const* data() const; + + // Swap entire contents with "other". If they are on separate arenas, then + // copies data. + void Swap(RepeatedPtrField* other); + + // Swap entire contents with "other". Caller should guarantee that either both + // fields are on the same arena or both are on the heap. Swapping between + // different arenas with this function is disallowed and is caught via + // GOOGLE_DCHECK. + void UnsafeArenaSwap(RepeatedPtrField* other); + + // Swap two elements. + void SwapElements(int index1, int index2); + + // STL-like iterator support + typedef internal::RepeatedPtrIterator<Element> iterator; + typedef internal::RepeatedPtrIterator<const Element> const_iterator; + typedef Element value_type; + typedef value_type& reference; + typedef const value_type& const_reference; + typedef value_type* pointer; + typedef const value_type* const_pointer; + typedef int size_type; + typedef ptrdiff_t difference_type; + + iterator begin(); + const_iterator begin() const; + const_iterator cbegin() const; + iterator end(); + const_iterator end() const; + const_iterator cend() const; + + // Reverse iterator support + typedef std::reverse_iterator<const_iterator> const_reverse_iterator; + typedef std::reverse_iterator<iterator> reverse_iterator; + reverse_iterator rbegin() { return reverse_iterator(end()); } + const_reverse_iterator rbegin() const { + return const_reverse_iterator(end()); + } + reverse_iterator rend() { return reverse_iterator(begin()); } + const_reverse_iterator rend() const { + return const_reverse_iterator(begin()); + } + + // Custom STL-like iterator that iterates over and returns the underlying + // pointers to Element rather than Element itself. + typedef internal::RepeatedPtrOverPtrsIterator<Element*, void*> + pointer_iterator; + typedef internal::RepeatedPtrOverPtrsIterator<const Element* const, + const void* const> + const_pointer_iterator; + pointer_iterator pointer_begin(); + const_pointer_iterator pointer_begin() const; + pointer_iterator pointer_end(); + const_pointer_iterator pointer_end() const; + + // Returns (an estimate of) the number of bytes used by the repeated field, + // excluding sizeof(*this). + size_t SpaceUsedExcludingSelfLong() const; + + int SpaceUsedExcludingSelf() const { + return internal::ToIntSize(SpaceUsedExcludingSelfLong()); + } + + // Advanced memory management -------------------------------------- + // When hardcore memory management becomes necessary -- as it sometimes + // does here at Google -- the following methods may be useful. + + // Add an already-allocated object, passing ownership to the + // RepeatedPtrField. + // + // Note that some special behavior occurs with respect to arenas: + // + // (i) if this field holds submessages, the new submessage will be copied if + // the original is in an arena and this RepeatedPtrField is either in a + // different arena, or on the heap. + // (ii) if this field holds strings, the passed-in string *must* be + // heap-allocated, not arena-allocated. There is no way to dynamically check + // this at runtime, so User Beware. + void AddAllocated(Element* value); + + // Remove the last element and return it, passing ownership to the caller. + // Requires: size() > 0 + // + // If this RepeatedPtrField is on an arena, an object copy is required to pass + // ownership back to the user (for compatible semantics). Use + // UnsafeArenaReleaseLast() if this behavior is undesired. + PROTOBUF_NODISCARD Element* ReleaseLast(); + + // Add an already-allocated object, skipping arena-ownership checks. The user + // must guarantee that the given object is in the same arena as this + // RepeatedPtrField. + // It is also useful in legacy code that uses temporary ownership to avoid + // copies. Example: + // RepeatedPtrField<T> temp_field; + // temp_field.UnsafeArenaAddAllocated(new T); + // ... // Do something with temp_field + // temp_field.UnsafeArenaExtractSubrange(0, temp_field.size(), nullptr); + // If you put temp_field on the arena this fails, because the ownership + // transfers to the arena at the "AddAllocated" call and is not released + // anymore causing a double delete. UnsafeArenaAddAllocated prevents this. + void UnsafeArenaAddAllocated(Element* value); + + // Remove the last element and return it. Unlike ReleaseLast, the returned + // pointer is always to the original object. This may be in an arena, and + // therefore have the arena's lifetime. + // Requires: current_size_ > 0 + Element* UnsafeArenaReleaseLast(); + + // Extract elements with indices in the range "[start .. start+num-1]". + // The caller assumes ownership of the extracted elements and is responsible + // for deleting them when they are no longer needed. + // If "elements" is non-nullptr, then pointers to the extracted elements + // are stored in "elements[0 .. num-1]" for the convenience of the caller. + // If "elements" is nullptr, then the caller must use some other mechanism + // to perform any further operations (like deletion) on these elements. + // Caution: implementation also moves elements with indices [start+num ..]. + // Calling this routine inside a loop can cause quadratic behavior. + // + // Memory copying behavior is identical to ReleaseLast(), described above: if + // this RepeatedPtrField is on an arena, an object copy is performed for each + // returned element, so that all returned element pointers are to + // heap-allocated copies. If this copy is not desired, the user should call + // UnsafeArenaExtractSubrange(). + void ExtractSubrange(int start, int num, Element** elements); + + // Identical to ExtractSubrange() described above, except that no object + // copies are ever performed. Instead, the raw object pointers are returned. + // Thus, if on an arena, the returned objects must not be freed, because they + // will not be heap-allocated objects. + void UnsafeArenaExtractSubrange(int start, int num, Element** elements); + + // When elements are removed by calls to RemoveLast() or Clear(), they + // are not actually freed. Instead, they are cleared and kept so that + // they can be reused later. This can save lots of CPU time when + // repeatedly reusing a protocol message for similar purposes. + // + // Hardcore programs may choose to manipulate these cleared objects + // to better optimize memory management using the following routines. + + // Get the number of cleared objects that are currently being kept + // around for reuse. + int ClearedCount() const; +#ifndef PROTOBUF_FUTURE_BREAKING_CHANGES + // Add an element to the pool of cleared objects, passing ownership to + // the RepeatedPtrField. The element must be cleared prior to calling + // this method. + // + // This method cannot be called when the repeated field is on an arena or when + // |value| is; both cases will trigger a GOOGLE_DCHECK-failure. + void AddCleared(Element* value); + // Remove a single element from the cleared pool and return it, passing + // ownership to the caller. The element is guaranteed to be cleared. + // Requires: ClearedCount() > 0 + // + // + // This method cannot be called when the repeated field is on an arena; doing + // so will trigger a GOOGLE_DCHECK-failure. + PROTOBUF_NODISCARD Element* ReleaseCleared(); +#endif // !PROTOBUF_FUTURE_BREAKING_CHANGES + + // Removes the element referenced by position. + // + // Returns an iterator to the element immediately following the removed + // element. + // + // Invalidates all iterators at or after the removed element, including end(). + iterator erase(const_iterator position); + + // Removes the elements in the range [first, last). + // + // Returns an iterator to the element immediately following the removed range. + // + // Invalidates all iterators at or after the removed range, including end(). + iterator erase(const_iterator first, const_iterator last); + + // Gets the arena on which this RepeatedPtrField stores its elements. + inline Arena* GetArena() const; + + // For internal use only. + // + // This is public due to it being called by generated code. + void InternalSwap(RepeatedPtrField* other) { + internal::RepeatedPtrFieldBase::InternalSwap(other); + } + + private: + // Note: RepeatedPtrField SHOULD NOT be subclassed by users. + class TypeHandler; + + // Implementations for ExtractSubrange(). The copying behavior must be + // included only if the type supports the necessary operations (e.g., + // MergeFrom()), so we must resolve this at compile time. ExtractSubrange() + // uses SFINAE to choose one of the below implementations. + void ExtractSubrangeInternal(int start, int num, Element** elements, + std::true_type); + void ExtractSubrangeInternal(int start, int num, Element** elements, + std::false_type); + + friend class Arena; + + template <typename T> + friend struct WeakRepeatedPtrField; + + typedef void InternalArenaConstructable_; + +}; + +// implementation ==================================================== + +namespace internal { + +constexpr RepeatedPtrFieldBase::RepeatedPtrFieldBase() + : arena_(nullptr), current_size_(0), total_size_(0), rep_(nullptr) {} + +inline RepeatedPtrFieldBase::RepeatedPtrFieldBase(Arena* arena) + : arena_(arena), current_size_(0), total_size_(0), rep_(nullptr) {} + +template <typename TypeHandler> +void RepeatedPtrFieldBase::Destroy() { + if (rep_ != nullptr && arena_ == nullptr) { + int n = rep_->allocated_size; + void* const* elements = rep_->elements; + for (int i = 0; i < n; i++) { + TypeHandler::Delete(cast<TypeHandler>(elements[i]), nullptr); + } +#if defined(__GXX_DELETE_WITH_SIZE__) || defined(__cpp_sized_deallocation) + const size_t size = total_size_ * sizeof(elements[0]) + kRepHeaderSize; + ::operator delete(static_cast<void*>(rep_), size); +#else + ::operator delete(static_cast<void*>(rep_)); +#endif + } + rep_ = nullptr; +} + +template <typename TypeHandler> +inline void RepeatedPtrFieldBase::Swap(RepeatedPtrFieldBase* other) { +#ifdef PROTOBUF_FORCE_COPY_IN_SWAP + if (GetArena() != nullptr && GetArena() == other->GetArena()) { +#else // PROTOBUF_FORCE_COPY_IN_SWAP + if (GetArena() == other->GetArena()) { +#endif // !PROTOBUF_FORCE_COPY_IN_SWAP + InternalSwap(other); + } else { + SwapFallback<TypeHandler>(other); + } +} + +template <typename TypeHandler> +void RepeatedPtrFieldBase::SwapFallback(RepeatedPtrFieldBase* other) { +#ifdef PROTOBUF_FORCE_COPY_IN_SWAP + GOOGLE_DCHECK(GetArena() == nullptr || other->GetArena() != GetArena()); +#else // PROTOBUF_FORCE_COPY_IN_SWAP + GOOGLE_DCHECK(other->GetArena() != GetArena()); +#endif // !PROTOBUF_FORCE_COPY_IN_SWAP + + // Copy semantics in this case. We try to improve efficiency by placing the + // temporary on |other|'s arena so that messages are copied twice rather than + // three times. + RepeatedPtrFieldBase temp(other->GetArena()); + temp.MergeFrom<TypeHandler>(*this); + this->Clear<TypeHandler>(); + this->MergeFrom<TypeHandler>(*other); + other->InternalSwap(&temp); + temp.Destroy<TypeHandler>(); // Frees rep_ if `other` had no arena. +} + +inline bool RepeatedPtrFieldBase::empty() const { return current_size_ == 0; } + +inline int RepeatedPtrFieldBase::size() const { return current_size_; } + +template <typename TypeHandler> +inline const typename TypeHandler::Type& RepeatedPtrFieldBase::Get( + int index) const { + GOOGLE_DCHECK_GE(index, 0); + GOOGLE_DCHECK_LT(index, current_size_); + return *cast<TypeHandler>(rep_->elements[index]); +} + +template <typename TypeHandler> +inline const typename TypeHandler::Type& RepeatedPtrFieldBase::at( + int index) const { + GOOGLE_CHECK_GE(index, 0); + GOOGLE_CHECK_LT(index, current_size_); + return *cast<TypeHandler>(rep_->elements[index]); +} + +template <typename TypeHandler> +inline typename TypeHandler::Type& RepeatedPtrFieldBase::at(int index) { + GOOGLE_CHECK_GE(index, 0); + GOOGLE_CHECK_LT(index, current_size_); + return *cast<TypeHandler>(rep_->elements[index]); +} + +template <typename TypeHandler> +inline typename TypeHandler::Type* RepeatedPtrFieldBase::Mutable(int index) { + GOOGLE_DCHECK_GE(index, 0); + GOOGLE_DCHECK_LT(index, current_size_); + return cast<TypeHandler>(rep_->elements[index]); +} + +template <typename TypeHandler> +inline void RepeatedPtrFieldBase::Delete(int index) { + GOOGLE_DCHECK_GE(index, 0); + GOOGLE_DCHECK_LT(index, current_size_); + TypeHandler::Delete(cast<TypeHandler>(rep_->elements[index]), arena_); +} + +template <typename TypeHandler> +inline typename TypeHandler::Type* RepeatedPtrFieldBase::Add( + typename TypeHandler::Type* prototype) { + if (rep_ != nullptr && current_size_ < rep_->allocated_size) { + return cast<TypeHandler>(rep_->elements[current_size_++]); + } + typename TypeHandler::Type* result = + TypeHandler::NewFromPrototype(prototype, arena_); + return reinterpret_cast<typename TypeHandler::Type*>( + AddOutOfLineHelper(result)); +} + +template <typename TypeHandler, + typename std::enable_if<TypeHandler::Movable::value>::type*> +inline void RepeatedPtrFieldBase::Add(typename TypeHandler::Type&& value) { + if (rep_ != nullptr && current_size_ < rep_->allocated_size) { + *cast<TypeHandler>(rep_->elements[current_size_++]) = std::move(value); + return; + } + if (!rep_ || rep_->allocated_size == total_size_) { + Reserve(total_size_ + 1); + } + ++rep_->allocated_size; + typename TypeHandler::Type* result = + TypeHandler::New(arena_, std::move(value)); + rep_->elements[current_size_++] = result; +} + +template <typename TypeHandler> +inline void RepeatedPtrFieldBase::RemoveLast() { + GOOGLE_DCHECK_GT(current_size_, 0); + TypeHandler::Clear(cast<TypeHandler>(rep_->elements[--current_size_])); +} + +template <typename TypeHandler> +void RepeatedPtrFieldBase::Clear() { + const int n = current_size_; + GOOGLE_DCHECK_GE(n, 0); + if (n > 0) { + void* const* elements = rep_->elements; + int i = 0; + do { + TypeHandler::Clear(cast<TypeHandler>(elements[i++])); + } while (i < n); + current_size_ = 0; + } +} + +// To avoid unnecessary code duplication and reduce binary size, we use a +// layered approach to implementing MergeFrom(). The toplevel method is +// templated, so we get a small thunk per concrete message type in the binary. +// This calls a shared implementation with most of the logic, passing a function +// pointer to another type-specific piece of code that calls the object-allocate +// and merge handlers. +template <typename TypeHandler> +inline void RepeatedPtrFieldBase::MergeFrom(const RepeatedPtrFieldBase& other) { + GOOGLE_DCHECK_NE(&other, this); + if (other.current_size_ == 0) return; + MergeFromInternal(other, + &RepeatedPtrFieldBase::MergeFromInnerLoop<TypeHandler>); +} + +inline void RepeatedPtrFieldBase::MergeFromInternal( + const RepeatedPtrFieldBase& other, + void (RepeatedPtrFieldBase::*inner_loop)(void**, void**, int, int)) { + // Note: wrapper has already guaranteed that other.rep_ != nullptr here. + int other_size = other.current_size_; + void** other_elements = other.rep_->elements; + void** new_elements = InternalExtend(other_size); + int allocated_elems = rep_->allocated_size - current_size_; + (this->*inner_loop)(new_elements, other_elements, other_size, + allocated_elems); + current_size_ += other_size; + if (rep_->allocated_size < current_size_) { + rep_->allocated_size = current_size_; + } +} + +// Merges other_elems to our_elems. +template <typename TypeHandler> +void RepeatedPtrFieldBase::MergeFromInnerLoop(void** our_elems, + void** other_elems, int length, + int already_allocated) { + if (already_allocated < length) { + Arena* arena = GetArena(); + typename TypeHandler::Type* elem_prototype = + reinterpret_cast<typename TypeHandler::Type*>(other_elems[0]); + for (int i = already_allocated; i < length; i++) { + // Allocate a new empty element that we'll merge into below + typename TypeHandler::Type* new_elem = + TypeHandler::NewFromPrototype(elem_prototype, arena); + our_elems[i] = new_elem; + } + } + // Main loop that does the actual merging + for (int i = 0; i < length; i++) { + // Already allocated: use existing element. + typename TypeHandler::Type* other_elem = + reinterpret_cast<typename TypeHandler::Type*>(other_elems[i]); + typename TypeHandler::Type* new_elem = + reinterpret_cast<typename TypeHandler::Type*>(our_elems[i]); + TypeHandler::Merge(*other_elem, new_elem); + } +} + +template <typename TypeHandler> +inline void RepeatedPtrFieldBase::CopyFrom(const RepeatedPtrFieldBase& other) { + if (&other == this) return; + RepeatedPtrFieldBase::Clear<TypeHandler>(); + RepeatedPtrFieldBase::MergeFrom<TypeHandler>(other); +} + +inline int RepeatedPtrFieldBase::Capacity() const { return total_size_; } + +inline void* const* RepeatedPtrFieldBase::raw_data() const { + return rep_ ? rep_->elements : nullptr; +} + +inline void** RepeatedPtrFieldBase::raw_mutable_data() const { + return rep_ ? const_cast<void**>(rep_->elements) : nullptr; +} + +template <typename TypeHandler> +inline typename TypeHandler::Type** RepeatedPtrFieldBase::mutable_data() { + // TODO(kenton): Breaks C++ aliasing rules. We should probably remove this + // method entirely. + return reinterpret_cast<typename TypeHandler::Type**>(raw_mutable_data()); +} + +template <typename TypeHandler> +inline const typename TypeHandler::Type* const* RepeatedPtrFieldBase::data() + const { + // TODO(kenton): Breaks C++ aliasing rules. We should probably remove this + // method entirely. + return reinterpret_cast<const typename TypeHandler::Type* const*>(raw_data()); +} + +inline void RepeatedPtrFieldBase::SwapElements(int index1, int index2) { + using std::swap; // enable ADL with fallback + swap(rep_->elements[index1], rep_->elements[index2]); +} + +template <typename TypeHandler> +inline size_t RepeatedPtrFieldBase::SpaceUsedExcludingSelfLong() const { + size_t allocated_bytes = static_cast<size_t>(total_size_) * sizeof(void*); + if (rep_ != nullptr) { + for (int i = 0; i < rep_->allocated_size; ++i) { + allocated_bytes += + TypeHandler::SpaceUsedLong(*cast<TypeHandler>(rep_->elements[i])); + } + allocated_bytes += kRepHeaderSize; + } + return allocated_bytes; +} + +template <typename TypeHandler> +inline typename TypeHandler::Type* RepeatedPtrFieldBase::AddFromCleared() { + if (rep_ != nullptr && current_size_ < rep_->allocated_size) { + return cast<TypeHandler>(rep_->elements[current_size_++]); + } else { + return nullptr; + } +} + +// AddAllocated version that implements arena-safe copying behavior. +template <typename TypeHandler> +void RepeatedPtrFieldBase::AddAllocatedInternal( + typename TypeHandler::Type* value, std::true_type) { + Arena* element_arena = + reinterpret_cast<Arena*>(TypeHandler::GetOwningArena(value)); + Arena* arena = GetArena(); + if (arena == element_arena && rep_ && rep_->allocated_size < total_size_) { + // Fast path: underlying arena representation (tagged pointer) is equal to + // our arena pointer, and we can add to array without resizing it (at least + // one slot that is not allocated). + void** elems = rep_->elements; + if (current_size_ < rep_->allocated_size) { + // Make space at [current] by moving first allocated element to end of + // allocated list. + elems[rep_->allocated_size] = elems[current_size_]; + } + elems[current_size_] = value; + current_size_ = current_size_ + 1; + rep_->allocated_size = rep_->allocated_size + 1; + } else { + AddAllocatedSlowWithCopy<TypeHandler>(value, element_arena, arena); + } +} + +// Slowpath handles all cases, copying if necessary. +template <typename TypeHandler> +void RepeatedPtrFieldBase::AddAllocatedSlowWithCopy( + // Pass value_arena and my_arena to avoid duplicate virtual call (value) or + // load (mine). + typename TypeHandler::Type* value, Arena* value_arena, Arena* my_arena) { + // Ensure that either the value is in the same arena, or if not, we do the + // appropriate thing: Own() it (if it's on heap and we're in an arena) or copy + // it to our arena/heap (otherwise). + if (my_arena != nullptr && value_arena == nullptr) { + my_arena->Own(value); + } else if (my_arena != value_arena) { + typename TypeHandler::Type* new_value = + TypeHandler::NewFromPrototype(value, my_arena); + TypeHandler::Merge(*value, new_value); + TypeHandler::Delete(value, value_arena); + value = new_value; + } + + UnsafeArenaAddAllocated<TypeHandler>(value); +} + +// AddAllocated version that does not implement arena-safe copying behavior. +template <typename TypeHandler> +void RepeatedPtrFieldBase::AddAllocatedInternal( + typename TypeHandler::Type* value, std::false_type) { + if (rep_ && rep_->allocated_size < total_size_) { + // Fast path: underlying arena representation (tagged pointer) is equal to + // our arena pointer, and we can add to array without resizing it (at least + // one slot that is not allocated). + void** elems = rep_->elements; + if (current_size_ < rep_->allocated_size) { + // Make space at [current] by moving first allocated element to end of + // allocated list. + elems[rep_->allocated_size] = elems[current_size_]; + } + elems[current_size_] = value; + current_size_ = current_size_ + 1; + ++rep_->allocated_size; + } else { + UnsafeArenaAddAllocated<TypeHandler>(value); + } +} + +template <typename TypeHandler> +void RepeatedPtrFieldBase::UnsafeArenaAddAllocated( + typename TypeHandler::Type* value) { + // Make room for the new pointer. + if (!rep_ || current_size_ == total_size_) { + // The array is completely full with no cleared objects, so grow it. + Reserve(total_size_ + 1); + ++rep_->allocated_size; + } else if (rep_->allocated_size == total_size_) { + // There is no more space in the pointer array because it contains some + // cleared objects awaiting reuse. We don't want to grow the array in this + // case because otherwise a loop calling AddAllocated() followed by Clear() + // would leak memory. + TypeHandler::Delete(cast<TypeHandler>(rep_->elements[current_size_]), + arena_); + } else if (current_size_ < rep_->allocated_size) { + // We have some cleared objects. We don't care about their order, so we + // can just move the first one to the end to make space. + rep_->elements[rep_->allocated_size] = rep_->elements[current_size_]; + ++rep_->allocated_size; + } else { + // There are no cleared objects. + ++rep_->allocated_size; + } + + rep_->elements[current_size_++] = value; +} + +// ReleaseLast() for types that implement merge/copy behavior. +template <typename TypeHandler> +inline typename TypeHandler::Type* RepeatedPtrFieldBase::ReleaseLastInternal( + std::true_type) { + // First, release an element. + typename TypeHandler::Type* result = UnsafeArenaReleaseLast<TypeHandler>(); + // Now perform a copy if we're on an arena. + Arena* arena = GetArena(); + + typename TypeHandler::Type* new_result; +#ifdef PROTOBUF_FORCE_COPY_IN_RELEASE + new_result = copy<TypeHandler>(result); + if (arena == nullptr) delete result; +#else // PROTOBUF_FORCE_COPY_IN_RELEASE + new_result = (arena == nullptr) ? result : copy<TypeHandler>(result); +#endif // !PROTOBUF_FORCE_COPY_IN_RELEASE + return new_result; +} + +// ReleaseLast() for types that *do not* implement merge/copy behavior -- this +// is the same as UnsafeArenaReleaseLast(). Note that we GOOGLE_DCHECK-fail if we're on +// an arena, since the user really should implement the copy operation in this +// case. +template <typename TypeHandler> +inline typename TypeHandler::Type* RepeatedPtrFieldBase::ReleaseLastInternal( + std::false_type) { + GOOGLE_DCHECK(GetArena() == nullptr) + << "ReleaseLast() called on a RepeatedPtrField that is on an arena, " + << "with a type that does not implement MergeFrom. This is unsafe; " + << "please implement MergeFrom for your type."; + return UnsafeArenaReleaseLast<TypeHandler>(); +} + +template <typename TypeHandler> +inline typename TypeHandler::Type* +RepeatedPtrFieldBase::UnsafeArenaReleaseLast() { + GOOGLE_DCHECK_GT(current_size_, 0); + typename TypeHandler::Type* result = + cast<TypeHandler>(rep_->elements[--current_size_]); + --rep_->allocated_size; + if (current_size_ < rep_->allocated_size) { + // There are cleared elements on the end; replace the removed element + // with the last allocated element. + rep_->elements[current_size_] = rep_->elements[rep_->allocated_size]; + } + return result; +} + +inline int RepeatedPtrFieldBase::ClearedCount() const { + return rep_ ? (rep_->allocated_size - current_size_) : 0; +} + +template <typename TypeHandler> +inline void RepeatedPtrFieldBase::AddCleared( + typename TypeHandler::Type* value) { + GOOGLE_DCHECK(GetArena() == nullptr) + << "AddCleared() can only be used on a RepeatedPtrField not on an arena."; + GOOGLE_DCHECK(TypeHandler::GetOwningArena(value) == nullptr) + << "AddCleared() can only accept values not on an arena."; + if (!rep_ || rep_->allocated_size == total_size_) { + Reserve(total_size_ + 1); + } + rep_->elements[rep_->allocated_size++] = value; +} + +template <typename TypeHandler> +inline typename TypeHandler::Type* RepeatedPtrFieldBase::ReleaseCleared() { + GOOGLE_DCHECK(GetArena() == nullptr) + << "ReleaseCleared() can only be used on a RepeatedPtrField not on " + << "an arena."; + GOOGLE_DCHECK(GetArena() == nullptr); + GOOGLE_DCHECK(rep_ != nullptr); + GOOGLE_DCHECK_GT(rep_->allocated_size, current_size_); + return cast<TypeHandler>(rep_->elements[--rep_->allocated_size]); +} + +} // namespace internal + +// ------------------------------------------------------------------- + +template <typename Element> +class RepeatedPtrField<Element>::TypeHandler + : public internal::GenericTypeHandler<Element> {}; + +template <> +class RepeatedPtrField<TProtoStringType>::TypeHandler + : public internal::StringTypeHandler {}; + +template <typename Element> +constexpr RepeatedPtrField<Element>::RepeatedPtrField() + : RepeatedPtrFieldBase() {} + +template <typename Element> +inline RepeatedPtrField<Element>::RepeatedPtrField(Arena* arena) + : RepeatedPtrFieldBase(arena) {} + +template <typename Element> +inline RepeatedPtrField<Element>::RepeatedPtrField( + const RepeatedPtrField& other) + : RepeatedPtrFieldBase() { + MergeFrom(other); +} + +template <typename Element> +template <typename Iter, typename> +inline RepeatedPtrField<Element>::RepeatedPtrField(Iter begin, Iter end) { + Add(begin, end); +} + +template <typename Element> +RepeatedPtrField<Element>::~RepeatedPtrField() { +#ifdef __cpp_if_constexpr + if constexpr (std::is_base_of<MessageLite, Element>::value) { +#else + if (std::is_base_of<MessageLite, Element>::value) { +#endif + if (NeedsDestroy()) DestroyProtos(); + } else { + Destroy<TypeHandler>(); + } +} + +template <typename Element> +inline RepeatedPtrField<Element>& RepeatedPtrField<Element>::operator=( + const RepeatedPtrField& other) { + if (this != &other) CopyFrom(other); + return *this; +} + +template <typename Element> +inline RepeatedPtrField<Element>::RepeatedPtrField( + RepeatedPtrField&& other) noexcept + : RepeatedPtrField() { +#ifdef PROTOBUF_FORCE_COPY_IN_MOVE + CopyFrom(other); +#else // PROTOBUF_FORCE_COPY_IN_MOVE + // We don't just call Swap(&other) here because it would perform 3 copies if + // other is on an arena. This field can't be on an arena because arena + // construction always uses the Arena* accepting constructor. + if (other.GetArena()) { + CopyFrom(other); + } else { + InternalSwap(&other); + } +#endif // !PROTOBUF_FORCE_COPY_IN_MOVE +} + +template <typename Element> +inline RepeatedPtrField<Element>& RepeatedPtrField<Element>::operator=( + RepeatedPtrField&& other) noexcept { + // We don't just call Swap(&other) here because it would perform 3 copies if + // the two fields are on different arenas. + if (this != &other) { + if (GetArena() != other.GetArena() +#ifdef PROTOBUF_FORCE_COPY_IN_MOVE + || GetArena() == nullptr +#endif // !PROTOBUF_FORCE_COPY_IN_MOVE + ) { + CopyFrom(other); + } else { + InternalSwap(&other); + } + } + return *this; +} + +template <typename Element> +inline bool RepeatedPtrField<Element>::empty() const { + return RepeatedPtrFieldBase::empty(); +} + +template <typename Element> +inline int RepeatedPtrField<Element>::size() const { + return RepeatedPtrFieldBase::size(); +} + +template <typename Element> +inline const Element& RepeatedPtrField<Element>::Get(int index) const { + return RepeatedPtrFieldBase::Get<TypeHandler>(index); +} + +template <typename Element> +inline const Element& RepeatedPtrField<Element>::at(int index) const { + return RepeatedPtrFieldBase::at<TypeHandler>(index); +} + +template <typename Element> +inline Element& RepeatedPtrField<Element>::at(int index) { + return RepeatedPtrFieldBase::at<TypeHandler>(index); +} + + +template <typename Element> +inline Element* RepeatedPtrField<Element>::Mutable(int index) { + return RepeatedPtrFieldBase::Mutable<TypeHandler>(index); +} + +template <typename Element> +inline Element* RepeatedPtrField<Element>::Add() { + return RepeatedPtrFieldBase::Add<TypeHandler>(); +} + +template <typename Element> +inline void RepeatedPtrField<Element>::Add(Element&& value) { + RepeatedPtrFieldBase::Add<TypeHandler>(std::move(value)); +} + +template <typename Element> +template <typename Iter> +inline void RepeatedPtrField<Element>::Add(Iter begin, Iter end) { + if (std::is_base_of< + std::forward_iterator_tag, + typename std::iterator_traits<Iter>::iterator_category>::value) { + int reserve = std::distance(begin, end); + Reserve(size() + reserve); + } + for (; begin != end; ++begin) { + *Add() = *begin; + } +} + +template <typename Element> +inline void RepeatedPtrField<Element>::RemoveLast() { + RepeatedPtrFieldBase::RemoveLast<TypeHandler>(); +} + +template <typename Element> +inline void RepeatedPtrField<Element>::DeleteSubrange(int start, int num) { + GOOGLE_DCHECK_GE(start, 0); + GOOGLE_DCHECK_GE(num, 0); + GOOGLE_DCHECK_LE(start + num, size()); + for (int i = 0; i < num; ++i) { + RepeatedPtrFieldBase::Delete<TypeHandler>(start + i); + } + UnsafeArenaExtractSubrange(start, num, nullptr); +} + +template <typename Element> +inline void RepeatedPtrField<Element>::ExtractSubrange(int start, int num, + Element** elements) { + typename internal::TypeImplementsMergeBehavior< + typename TypeHandler::Type>::type t; + ExtractSubrangeInternal(start, num, elements, t); +} + +// ExtractSubrange() implementation for types that implement merge/copy +// behavior. +template <typename Element> +inline void RepeatedPtrField<Element>::ExtractSubrangeInternal( + int start, int num, Element** elements, std::true_type) { + GOOGLE_DCHECK_GE(start, 0); + GOOGLE_DCHECK_GE(num, 0); + GOOGLE_DCHECK_LE(start + num, size()); + + if (num == 0) return; + + GOOGLE_DCHECK_NE(elements, nullptr) + << "Releasing elements without transferring ownership is an unsafe " + "operation. Use UnsafeArenaExtractSubrange."; + if (elements == nullptr) { + CloseGap(start, num); + return; + } + + Arena* arena = GetArena(); +#ifdef PROTOBUF_FORCE_COPY_IN_RELEASE + // Always copy. + for (int i = 0; i < num; ++i) { + elements[i] = copy<TypeHandler>( + RepeatedPtrFieldBase::Mutable<TypeHandler>(i + start)); + } + if (arena == nullptr) { + for (int i = 0; i < num; ++i) { + delete RepeatedPtrFieldBase::Mutable<TypeHandler>(i + start); + } + } +#else // PROTOBUF_FORCE_COPY_IN_RELEASE + // If we're on an arena, we perform a copy for each element so that the + // returned elements are heap-allocated. Otherwise, just forward it. + if (arena != nullptr) { + for (int i = 0; i < num; ++i) { + elements[i] = copy<TypeHandler>( + RepeatedPtrFieldBase::Mutable<TypeHandler>(i + start)); + } + } else { + for (int i = 0; i < num; ++i) { + elements[i] = RepeatedPtrFieldBase::Mutable<TypeHandler>(i + start); + } + } +#endif // !PROTOBUF_FORCE_COPY_IN_RELEASE + CloseGap(start, num); +} + +// ExtractSubrange() implementation for types that do not implement merge/copy +// behavior. +template <typename Element> +inline void RepeatedPtrField<Element>::ExtractSubrangeInternal( + int start, int num, Element** elements, std::false_type) { + // This case is identical to UnsafeArenaExtractSubrange(). However, since + // ExtractSubrange() must return heap-allocated objects by contract, and we + // cannot fulfill this contract if we are an on arena, we must GOOGLE_DCHECK() that + // we are not on an arena. + GOOGLE_DCHECK(GetArena() == nullptr) + << "ExtractSubrange() when arena is non-nullptr is only supported when " + << "the Element type supplies a MergeFrom() operation to make copies."; + UnsafeArenaExtractSubrange(start, num, elements); +} + +template <typename Element> +inline void RepeatedPtrField<Element>::UnsafeArenaExtractSubrange( + int start, int num, Element** elements) { + GOOGLE_DCHECK_GE(start, 0); + GOOGLE_DCHECK_GE(num, 0); + GOOGLE_DCHECK_LE(start + num, size()); + + if (num > 0) { + // Save the values of the removed elements if requested. + if (elements != nullptr) { + for (int i = 0; i < num; ++i) { + elements[i] = RepeatedPtrFieldBase::Mutable<TypeHandler>(i + start); + } + } + CloseGap(start, num); + } +} + +template <typename Element> +inline void RepeatedPtrField<Element>::Clear() { + RepeatedPtrFieldBase::Clear<TypeHandler>(); +} + +template <typename Element> +inline void RepeatedPtrField<Element>::MergeFrom( + const RepeatedPtrField& other) { + RepeatedPtrFieldBase::MergeFrom<TypeHandler>(other); +} + +template <typename Element> +inline void RepeatedPtrField<Element>::CopyFrom(const RepeatedPtrField& other) { + RepeatedPtrFieldBase::CopyFrom<TypeHandler>(other); +} + +template <typename Element> +template <typename Iter> +inline void RepeatedPtrField<Element>::Assign(Iter begin, Iter end) { + Clear(); + Add(begin, end); +} + +template <typename Element> +inline typename RepeatedPtrField<Element>::iterator +RepeatedPtrField<Element>::erase(const_iterator position) { + return erase(position, position + 1); +} + +template <typename Element> +inline typename RepeatedPtrField<Element>::iterator +RepeatedPtrField<Element>::erase(const_iterator first, const_iterator last) { + size_type pos_offset = std::distance(cbegin(), first); + size_type last_offset = std::distance(cbegin(), last); + DeleteSubrange(pos_offset, last_offset - pos_offset); + return begin() + pos_offset; +} + +template <typename Element> +inline Element** RepeatedPtrField<Element>::mutable_data() { + return RepeatedPtrFieldBase::mutable_data<TypeHandler>(); +} + +template <typename Element> +inline const Element* const* RepeatedPtrField<Element>::data() const { + return RepeatedPtrFieldBase::data<TypeHandler>(); +} + +template <typename Element> +inline void RepeatedPtrField<Element>::Swap(RepeatedPtrField* other) { + if (this == other) return; + RepeatedPtrFieldBase::Swap<TypeHandler>(other); +} + +template <typename Element> +inline void RepeatedPtrField<Element>::UnsafeArenaSwap( + RepeatedPtrField* other) { + if (this == other) return; + RepeatedPtrFieldBase::InternalSwap(other); +} + +template <typename Element> +inline void RepeatedPtrField<Element>::SwapElements(int index1, int index2) { + RepeatedPtrFieldBase::SwapElements(index1, index2); +} + +template <typename Element> +inline Arena* RepeatedPtrField<Element>::GetArena() const { + return RepeatedPtrFieldBase::GetArena(); +} + +template <typename Element> +inline size_t RepeatedPtrField<Element>::SpaceUsedExcludingSelfLong() const { + return RepeatedPtrFieldBase::SpaceUsedExcludingSelfLong<TypeHandler>(); +} + +template <typename Element> +inline void RepeatedPtrField<Element>::AddAllocated(Element* value) { + RepeatedPtrFieldBase::AddAllocated<TypeHandler>(value); +} + +template <typename Element> +inline void RepeatedPtrField<Element>::UnsafeArenaAddAllocated(Element* value) { + RepeatedPtrFieldBase::UnsafeArenaAddAllocated<TypeHandler>(value); +} + +template <typename Element> +inline Element* RepeatedPtrField<Element>::ReleaseLast() { + return RepeatedPtrFieldBase::ReleaseLast<TypeHandler>(); +} + +template <typename Element> +inline Element* RepeatedPtrField<Element>::UnsafeArenaReleaseLast() { + return RepeatedPtrFieldBase::UnsafeArenaReleaseLast<TypeHandler>(); +} + +template <typename Element> +inline int RepeatedPtrField<Element>::ClearedCount() const { + return RepeatedPtrFieldBase::ClearedCount(); +} + +#ifndef PROTOBUF_FUTURE_BREAKING_CHANGES +template <typename Element> +inline void RepeatedPtrField<Element>::AddCleared(Element* value) { + return RepeatedPtrFieldBase::AddCleared<TypeHandler>(value); +} + +template <typename Element> +inline Element* RepeatedPtrField<Element>::ReleaseCleared() { + return RepeatedPtrFieldBase::ReleaseCleared<TypeHandler>(); +} +#endif // !PROTOBUF_FUTURE_BREAKING_CHANGES + +template <typename Element> +inline void RepeatedPtrField<Element>::Reserve(int new_size) { + return RepeatedPtrFieldBase::Reserve(new_size); +} + +template <typename Element> +inline int RepeatedPtrField<Element>::Capacity() const { + return RepeatedPtrFieldBase::Capacity(); +} + +// ------------------------------------------------------------------- + +namespace internal { + +// STL-like iterator implementation for RepeatedPtrField. You should not +// refer to this class directly; use RepeatedPtrField<T>::iterator instead. +// +// The iterator for RepeatedPtrField<T>, RepeatedPtrIterator<T>, is +// very similar to iterator_ptr<T**> in util/gtl/iterator_adaptors.h, +// but adds random-access operators and is modified to wrap a void** base +// iterator (since RepeatedPtrField stores its array as a void* array and +// casting void** to T** would violate C++ aliasing rules). +// +// This code based on net/proto/proto-array-internal.h by Jeffrey Yasskin +// (jyasskin@google.com). +template <typename Element> +class RepeatedPtrIterator { + public: + using iterator = RepeatedPtrIterator<Element>; + using iterator_category = std::random_access_iterator_tag; + using value_type = typename std::remove_const<Element>::type; + using difference_type = std::ptrdiff_t; + using pointer = Element*; + using reference = Element&; + + RepeatedPtrIterator() : it_(nullptr) {} + explicit RepeatedPtrIterator(void* const* it) : it_(it) {} + + // Allow "upcasting" from RepeatedPtrIterator<T**> to + // RepeatedPtrIterator<const T*const*>. + template <typename OtherElement> + RepeatedPtrIterator(const RepeatedPtrIterator<OtherElement>& other) + : it_(other.it_) { + // Force a compiler error if the other type is not convertible to ours. + if (false) { + static_cast<void>([](OtherElement* from) -> Element* { return from; }); + } + } + + // dereferenceable + reference operator*() const { return *reinterpret_cast<Element*>(*it_); } + pointer operator->() const { return &(operator*()); } + + // {inc,dec}rementable + iterator& operator++() { + ++it_; + return *this; + } + iterator operator++(int) { return iterator(it_++); } + iterator& operator--() { + --it_; + return *this; + } + iterator operator--(int) { return iterator(it_--); } + + // equality_comparable + bool operator==(const iterator& x) const { return it_ == x.it_; } + bool operator!=(const iterator& x) const { return it_ != x.it_; } + + // less_than_comparable + bool operator<(const iterator& x) const { return it_ < x.it_; } + bool operator<=(const iterator& x) const { return it_ <= x.it_; } + bool operator>(const iterator& x) const { return it_ > x.it_; } + bool operator>=(const iterator& x) const { return it_ >= x.it_; } + + // addable, subtractable + iterator& operator+=(difference_type d) { + it_ += d; + return *this; + } + friend iterator operator+(iterator it, const difference_type d) { + it += d; + return it; + } + friend iterator operator+(const difference_type d, iterator it) { + it += d; + return it; + } + iterator& operator-=(difference_type d) { + it_ -= d; + return *this; + } + friend iterator operator-(iterator it, difference_type d) { + it -= d; + return it; + } + + // indexable + reference operator[](difference_type d) const { return *(*this + d); } + + // random access iterator + difference_type operator-(const iterator& x) const { return it_ - x.it_; } + + private: + template <typename OtherElement> + friend class RepeatedPtrIterator; + + // The internal iterator. + void* const* it_; +}; + +// Provide an iterator that operates on pointers to the underlying objects +// rather than the objects themselves as RepeatedPtrIterator does. +// Consider using this when working with stl algorithms that change +// the array. +// The VoidPtr template parameter holds the type-agnostic pointer value +// referenced by the iterator. It should either be "void *" for a mutable +// iterator, or "const void* const" for a constant iterator. +template <typename Element, typename VoidPtr> +class RepeatedPtrOverPtrsIterator { + public: + using iterator = RepeatedPtrOverPtrsIterator<Element, VoidPtr>; + using iterator_category = std::random_access_iterator_tag; + using value_type = typename std::remove_const<Element>::type; + using difference_type = std::ptrdiff_t; + using pointer = Element*; + using reference = Element&; + + RepeatedPtrOverPtrsIterator() : it_(nullptr) {} + explicit RepeatedPtrOverPtrsIterator(VoidPtr* it) : it_(it) {} + + // dereferenceable + reference operator*() const { return *reinterpret_cast<Element*>(it_); } + pointer operator->() const { return &(operator*()); } + + // {inc,dec}rementable + iterator& operator++() { + ++it_; + return *this; + } + iterator operator++(int) { return iterator(it_++); } + iterator& operator--() { + --it_; + return *this; + } + iterator operator--(int) { return iterator(it_--); } + + // equality_comparable + bool operator==(const iterator& x) const { return it_ == x.it_; } + bool operator!=(const iterator& x) const { return it_ != x.it_; } + + // less_than_comparable + bool operator<(const iterator& x) const { return it_ < x.it_; } + bool operator<=(const iterator& x) const { return it_ <= x.it_; } + bool operator>(const iterator& x) const { return it_ > x.it_; } + bool operator>=(const iterator& x) const { return it_ >= x.it_; } + + // addable, subtractable + iterator& operator+=(difference_type d) { + it_ += d; + return *this; + } + friend iterator operator+(iterator it, difference_type d) { + it += d; + return it; + } + friend iterator operator+(difference_type d, iterator it) { + it += d; + return it; + } + iterator& operator-=(difference_type d) { + it_ -= d; + return *this; + } + friend iterator operator-(iterator it, difference_type d) { + it -= d; + return it; + } + + // indexable + reference operator[](difference_type d) const { return *(*this + d); } + + // random access iterator + difference_type operator-(const iterator& x) const { return it_ - x.it_; } + + private: + template <typename OtherElement> + friend class RepeatedPtrIterator; + + // The internal iterator. + VoidPtr* it_; +}; + +void RepeatedPtrFieldBase::InternalSwap(RepeatedPtrFieldBase* rhs) { + GOOGLE_DCHECK(this != rhs); + + // Swap all fields at once. + auto temp = std::make_tuple(rhs->arena_, rhs->current_size_, rhs->total_size_, + rhs->rep_); + std::tie(rhs->arena_, rhs->current_size_, rhs->total_size_, rhs->rep_) = + std::make_tuple(arena_, current_size_, total_size_, rep_); + std::tie(arena_, current_size_, total_size_, rep_) = temp; +} + +} // namespace internal + +template <typename Element> +inline typename RepeatedPtrField<Element>::iterator +RepeatedPtrField<Element>::begin() { + return iterator(raw_data()); +} +template <typename Element> +inline typename RepeatedPtrField<Element>::const_iterator +RepeatedPtrField<Element>::begin() const { + return iterator(raw_data()); +} +template <typename Element> +inline typename RepeatedPtrField<Element>::const_iterator +RepeatedPtrField<Element>::cbegin() const { + return begin(); +} +template <typename Element> +inline typename RepeatedPtrField<Element>::iterator +RepeatedPtrField<Element>::end() { + return iterator(raw_data() + size()); +} +template <typename Element> +inline typename RepeatedPtrField<Element>::const_iterator +RepeatedPtrField<Element>::end() const { + return iterator(raw_data() + size()); +} +template <typename Element> +inline typename RepeatedPtrField<Element>::const_iterator +RepeatedPtrField<Element>::cend() const { + return end(); +} + +template <typename Element> +inline typename RepeatedPtrField<Element>::pointer_iterator +RepeatedPtrField<Element>::pointer_begin() { + return pointer_iterator(raw_mutable_data()); +} +template <typename Element> +inline typename RepeatedPtrField<Element>::const_pointer_iterator +RepeatedPtrField<Element>::pointer_begin() const { + return const_pointer_iterator(const_cast<const void* const*>(raw_data())); +} +template <typename Element> +inline typename RepeatedPtrField<Element>::pointer_iterator +RepeatedPtrField<Element>::pointer_end() { + return pointer_iterator(raw_mutable_data() + size()); +} +template <typename Element> +inline typename RepeatedPtrField<Element>::const_pointer_iterator +RepeatedPtrField<Element>::pointer_end() const { + return const_pointer_iterator( + const_cast<const void* const*>(raw_data() + size())); +} + +// Iterators and helper functions that follow the spirit of the STL +// std::back_insert_iterator and std::back_inserter but are tailor-made +// for RepeatedField and RepeatedPtrField. Typical usage would be: +// +// std::copy(some_sequence.begin(), some_sequence.end(), +// RepeatedFieldBackInserter(proto.mutable_sequence())); +// +// Ported by johannes from util/gtl/proto-array-iterators.h + +namespace internal { + +// A back inserter for RepeatedPtrField objects. +template <typename T> +class RepeatedPtrFieldBackInsertIterator { + public: + using iterator_category = std::output_iterator_tag; + using value_type = T; + using pointer = void; + using reference = void; + using difference_type = std::ptrdiff_t; + + RepeatedPtrFieldBackInsertIterator(RepeatedPtrField<T>* const mutable_field) + : field_(mutable_field) {} + RepeatedPtrFieldBackInsertIterator<T>& operator=(const T& value) { + *field_->Add() = value; + return *this; + } + RepeatedPtrFieldBackInsertIterator<T>& operator=( + const T* const ptr_to_value) { + *field_->Add() = *ptr_to_value; + return *this; + } + RepeatedPtrFieldBackInsertIterator<T>& operator=(T&& value) { + *field_->Add() = std::move(value); + return *this; + } + RepeatedPtrFieldBackInsertIterator<T>& operator*() { return *this; } + RepeatedPtrFieldBackInsertIterator<T>& operator++() { return *this; } + RepeatedPtrFieldBackInsertIterator<T>& operator++(int /* unused */) { + return *this; + } + + private: + RepeatedPtrField<T>* field_; +}; + +// A back inserter for RepeatedPtrFields that inserts by transferring ownership +// of a pointer. +template <typename T> +class AllocatedRepeatedPtrFieldBackInsertIterator { + public: + using iterator_category = std::output_iterator_tag; + using value_type = T; + using pointer = void; + using reference = void; + using difference_type = std::ptrdiff_t; + + explicit AllocatedRepeatedPtrFieldBackInsertIterator( + RepeatedPtrField<T>* const mutable_field) + : field_(mutable_field) {} + AllocatedRepeatedPtrFieldBackInsertIterator<T>& operator=( + T* const ptr_to_value) { + field_->AddAllocated(ptr_to_value); + return *this; + } + AllocatedRepeatedPtrFieldBackInsertIterator<T>& operator*() { return *this; } + AllocatedRepeatedPtrFieldBackInsertIterator<T>& operator++() { return *this; } + AllocatedRepeatedPtrFieldBackInsertIterator<T>& operator++(int /* unused */) { + return *this; + } + + private: + RepeatedPtrField<T>* field_; +}; + +// Almost identical to AllocatedRepeatedPtrFieldBackInsertIterator. This one +// uses the UnsafeArenaAddAllocated instead. +template <typename T> +class UnsafeArenaAllocatedRepeatedPtrFieldBackInsertIterator { + public: + using iterator_category = std::output_iterator_tag; + using value_type = T; + using pointer = void; + using reference = void; + using difference_type = std::ptrdiff_t; + + explicit UnsafeArenaAllocatedRepeatedPtrFieldBackInsertIterator( + RepeatedPtrField<T>* const mutable_field) + : field_(mutable_field) {} + UnsafeArenaAllocatedRepeatedPtrFieldBackInsertIterator<T>& operator=( + T const* const ptr_to_value) { + field_->UnsafeArenaAddAllocated(const_cast<T*>(ptr_to_value)); + return *this; + } + UnsafeArenaAllocatedRepeatedPtrFieldBackInsertIterator<T>& operator*() { + return *this; + } + UnsafeArenaAllocatedRepeatedPtrFieldBackInsertIterator<T>& operator++() { + return *this; + } + UnsafeArenaAllocatedRepeatedPtrFieldBackInsertIterator<T>& operator++( + int /* unused */) { + return *this; + } + + private: + RepeatedPtrField<T>* field_; +}; + +} // namespace internal + +// Provides a back insert iterator for RepeatedPtrField instances, +// similar to std::back_inserter(). +template <typename T> +internal::RepeatedPtrFieldBackInsertIterator<T> RepeatedPtrFieldBackInserter( + RepeatedPtrField<T>* const mutable_field) { + return internal::RepeatedPtrFieldBackInsertIterator<T>(mutable_field); +} + +// Special back insert iterator for RepeatedPtrField instances, just in +// case someone wants to write generic template code that can access both +// RepeatedFields and RepeatedPtrFields using a common name. +template <typename T> +internal::RepeatedPtrFieldBackInsertIterator<T> RepeatedFieldBackInserter( + RepeatedPtrField<T>* const mutable_field) { + return internal::RepeatedPtrFieldBackInsertIterator<T>(mutable_field); +} + +// Provides a back insert iterator for RepeatedPtrField instances +// similar to std::back_inserter() which transfers the ownership while +// copying elements. +template <typename T> +internal::AllocatedRepeatedPtrFieldBackInsertIterator<T> +AllocatedRepeatedPtrFieldBackInserter( + RepeatedPtrField<T>* const mutable_field) { + return internal::AllocatedRepeatedPtrFieldBackInsertIterator<T>( + mutable_field); +} + +// Similar to AllocatedRepeatedPtrFieldBackInserter, using +// UnsafeArenaAddAllocated instead of AddAllocated. +// This is slightly faster if that matters. It is also useful in legacy code +// that uses temporary ownership to avoid copies. Example: +// RepeatedPtrField<T> temp_field; +// temp_field.UnsafeArenaAddAllocated(new T); +// ... // Do something with temp_field +// temp_field.UnsafeArenaExtractSubrange(0, temp_field.size(), nullptr); +// If you put temp_field on the arena this fails, because the ownership +// transfers to the arena at the "AddAllocated" call and is not released anymore +// causing a double delete. Using UnsafeArenaAddAllocated prevents this. +template <typename T> +internal::UnsafeArenaAllocatedRepeatedPtrFieldBackInsertIterator<T> +UnsafeArenaAllocatedRepeatedPtrFieldBackInserter( + RepeatedPtrField<T>* const mutable_field) { + return internal::UnsafeArenaAllocatedRepeatedPtrFieldBackInsertIterator<T>( + mutable_field); +} + +extern template class PROTOBUF_EXPORT_TEMPLATE_DECLARE + RepeatedPtrField<TProtoStringType>; + +} // namespace protobuf +} // namespace google + +#include <google/protobuf/port_undef.inc> + +#endif // GOOGLE_PROTOBUF_REPEATED_PTR_FIELD_H__ diff --git a/contrib/libs/protobuf_old/src/google/protobuf/service.cc b/contrib/libs/protobuf_old/src/google/protobuf/service.cc new file mode 100644 index 0000000000..53945684cb --- /dev/null +++ b/contrib/libs/protobuf_old/src/google/protobuf/service.cc @@ -0,0 +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. + +// Author: kenton@google.com (Kenton Varda) +// Based on original Protocol Buffers design by +// Sanjay Ghemawat, Jeff Dean, and others. + +#include <google/protobuf/service.h> + +namespace google { +namespace protobuf { + +Service::~Service() {} +RpcChannel::~RpcChannel() {} +RpcController::~RpcController() {} + +} // namespace protobuf +} // namespace google diff --git a/contrib/libs/protobuf_old/src/google/protobuf/service.h b/contrib/libs/protobuf_old/src/google/protobuf/service.h new file mode 100644 index 0000000000..b385bc15ee --- /dev/null +++ b/contrib/libs/protobuf_old/src/google/protobuf/service.h @@ -0,0 +1,293 @@ +// 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: kenton@google.com (Kenton Varda) +// Based on original Protocol Buffers design by +// Sanjay Ghemawat, Jeff Dean, and others. +// +// DEPRECATED: This module declares the abstract interfaces underlying proto2 +// RPC services. These are intended to be independent of any particular RPC +// implementation, so that proto2 services can be used on top of a variety +// of implementations. Starting with version 2.3.0, RPC implementations should +// not try to build on these, but should instead provide code generator plugins +// which generate code specific to the particular RPC implementation. This way +// the generated code can be more appropriate for the implementation in use +// and can avoid unnecessary layers of indirection. +// +// +// When you use the protocol compiler to compile a service definition, it +// generates two classes: An abstract interface for the service (with +// methods matching the service definition) and a "stub" implementation. +// A stub is just a type-safe wrapper around an RpcChannel which emulates a +// local implementation of the service. +// +// For example, the service definition: +// service MyService { +// rpc Foo(MyRequest) returns(MyResponse); +// } +// will generate abstract interface "MyService" and class "MyService::Stub". +// You could implement a MyService as follows: +// class MyServiceImpl : public MyService { +// public: +// MyServiceImpl() {} +// ~MyServiceImpl() {} +// +// // implements MyService --------------------------------------- +// +// void Foo(google::protobuf::RpcController* controller, +// const MyRequest* request, +// MyResponse* response, +// Closure* done) { +// // ... read request and fill in response ... +// done->Run(); +// } +// }; +// You would then register an instance of MyServiceImpl with your RPC server +// implementation. (How to do that depends on the implementation.) +// +// To call a remote MyServiceImpl, first you need an RpcChannel connected to it. +// How to construct a channel depends, again, on your RPC implementation. +// Here we use a hypothetical "MyRpcChannel" as an example: +// MyRpcChannel channel("rpc:hostname:1234/myservice"); +// MyRpcController controller; +// MyServiceImpl::Stub stub(&channel); +// FooRequest request; +// FooResponse response; +// +// // ... fill in request ... +// +// stub.Foo(&controller, request, &response, NewCallback(HandleResponse)); +// +// On Thread-Safety: +// +// Different RPC implementations may make different guarantees about what +// threads they may run callbacks on, and what threads the application is +// allowed to use to call the RPC system. Portable software should be ready +// for callbacks to be called on any thread, but should not try to call the +// RPC system from any thread except for the ones on which it received the +// callbacks. Realistically, though, simple software will probably want to +// use a single-threaded RPC system while high-end software will want to +// use multiple threads. RPC implementations should provide multiple +// choices. + +#ifndef GOOGLE_PROTOBUF_SERVICE_H__ +#define GOOGLE_PROTOBUF_SERVICE_H__ + +#include <string> +#include <google/protobuf/stubs/callback.h> +#include <google/protobuf/stubs/common.h> + +#ifdef SWIG +#error "You cannot SWIG proto headers" +#endif + +#include <google/protobuf/port_def.inc> + +namespace google { +namespace protobuf { + +// Defined in this file. +class Service; +class RpcController; +class RpcChannel; + +// Defined in other files. +class Descriptor; // descriptor.h +class ServiceDescriptor; // descriptor.h +class MethodDescriptor; // descriptor.h +class Message; // message.h + +// Abstract base interface for protocol-buffer-based RPC services. Services +// themselves are abstract interfaces (implemented either by servers or as +// stubs), but they subclass this base interface. The methods of this +// interface can be used to call the methods of the Service without knowing +// its exact type at compile time (analogous to Reflection). +class PROTOBUF_EXPORT Service { + public: + inline Service() {} + virtual ~Service(); + + // When constructing a stub, you may pass STUB_OWNS_CHANNEL as the second + // parameter to the constructor to tell it to delete its RpcChannel when + // destroyed. + enum ChannelOwnership { STUB_OWNS_CHANNEL, STUB_DOESNT_OWN_CHANNEL }; + + // Get the ServiceDescriptor describing this service and its methods. + virtual const ServiceDescriptor* GetDescriptor() = 0; + + // Call a method of the service specified by MethodDescriptor. This is + // normally implemented as a simple switch() that calls the standard + // definitions of the service's methods. + // + // Preconditions: + // * method->service() == GetDescriptor() + // * request and response are of the exact same classes as the objects + // returned by GetRequestPrototype(method) and + // GetResponsePrototype(method). + // * After the call has started, the request must not be modified and the + // response must not be accessed at all until "done" is called. + // * "controller" is of the correct type for the RPC implementation being + // used by this Service. For stubs, the "correct type" depends on the + // RpcChannel which the stub is using. Server-side Service + // implementations are expected to accept whatever type of RpcController + // the server-side RPC implementation uses. + // + // Postconditions: + // * "done" will be called when the method is complete. This may be + // before CallMethod() returns or it may be at some point in the future. + // * If the RPC succeeded, "response" contains the response returned by + // the server. + // * If the RPC failed, "response"'s contents are undefined. The + // RpcController can be queried to determine if an error occurred and + // possibly to get more information about the error. + virtual void CallMethod(const MethodDescriptor* method, + RpcController* controller, const Message* request, + Message* response, Closure* done) = 0; + + // CallMethod() requires that the request and response passed in are of a + // particular subclass of Message. GetRequestPrototype() and + // GetResponsePrototype() get the default instances of these required types. + // You can then call Message::New() on these instances to construct mutable + // objects which you can then pass to CallMethod(). + // + // Example: + // const MethodDescriptor* method = + // service->GetDescriptor()->FindMethodByName("Foo"); + // Message* request = stub->GetRequestPrototype (method)->New(); + // Message* response = stub->GetResponsePrototype(method)->New(); + // request->ParseFromString(input); + // service->CallMethod(method, *request, response, callback); + virtual const Message& GetRequestPrototype( + const MethodDescriptor* method) const = 0; + virtual const Message& GetResponsePrototype( + const MethodDescriptor* method) const = 0; + + private: + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(Service); +}; + +// An RpcController mediates a single method call. The primary purpose of +// the controller is to provide a way to manipulate settings specific to the +// RPC implementation and to find out about RPC-level errors. +// +// The methods provided by the RpcController interface are intended to be a +// "least common denominator" set of features which we expect all +// implementations to support. Specific implementations may provide more +// advanced features (e.g. deadline propagation). +class PROTOBUF_EXPORT RpcController { + public: + inline RpcController() {} + virtual ~RpcController(); + + // Client-side methods --------------------------------------------- + // These calls may be made from the client side only. Their results + // are undefined on the server side (may crash). + + // Resets the RpcController to its initial state so that it may be reused in + // a new call. Must not be called while an RPC is in progress. + virtual void Reset() = 0; + + // After a call has finished, returns true if the call failed. The possible + // reasons for failure depend on the RPC implementation. Failed() must not + // be called before a call has finished. If Failed() returns true, the + // contents of the response message are undefined. + virtual bool Failed() const = 0; + + // If Failed() is true, returns a human-readable description of the error. + virtual TProtoStringType ErrorText() const = 0; + + // Advises the RPC system that the caller desires that the RPC call be + // canceled. The RPC system may cancel it immediately, may wait awhile and + // then cancel it, or may not even cancel the call at all. If the call is + // canceled, the "done" callback will still be called and the RpcController + // will indicate that the call failed at that time. + virtual void StartCancel() = 0; + + // Server-side methods --------------------------------------------- + // These calls may be made from the server side only. Their results + // are undefined on the client side (may crash). + + // Causes Failed() to return true on the client side. "reason" will be + // incorporated into the message returned by ErrorText(). If you find + // you need to return machine-readable information about failures, you + // should incorporate it into your response protocol buffer and should + // NOT call SetFailed(). + virtual void SetFailed(const TProtoStringType& reason) = 0; + + // If true, indicates that the client canceled the RPC, so the server may + // as well give up on replying to it. The server should still call the + // final "done" callback. + virtual bool IsCanceled() const = 0; + + // Asks that the given callback be called when the RPC is canceled. The + // callback will always be called exactly once. If the RPC completes without + // being canceled, the callback will be called after completion. If the RPC + // has already been canceled when NotifyOnCancel() is called, the callback + // will be called immediately. + // + // NotifyOnCancel() must be called no more than once per request. + virtual void NotifyOnCancel(Closure* callback) = 0; + + private: + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(RpcController); +}; + +// Abstract interface for an RPC channel. An RpcChannel represents a +// communication line to a Service which can be used to call that Service's +// methods. The Service may be running on another machine. Normally, you +// should not call an RpcChannel directly, but instead construct a stub Service +// wrapping it. Example: +// RpcChannel* channel = new MyRpcChannel("remotehost.example.com:1234"); +// MyService* service = new MyService::Stub(channel); +// service->MyMethod(request, &response, callback); +class PROTOBUF_EXPORT RpcChannel { + public: + inline RpcChannel() {} + virtual ~RpcChannel(); + + // Call the given method of the remote service. The signature of this + // procedure looks the same as Service::CallMethod(), but the requirements + // are less strict in one important way: the request and response objects + // need not be of any specific class as long as their descriptors are + // method->input_type() and method->output_type(). + virtual void CallMethod(const MethodDescriptor* method, + RpcController* controller, const Message* request, + Message* response, Closure* done) = 0; + + private: + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(RpcChannel); +}; + +} // namespace protobuf +} // namespace google + +#include <google/protobuf/port_undef.inc> + +#endif // GOOGLE_PROTOBUF_SERVICE_H__ diff --git a/contrib/libs/protobuf_old/src/google/protobuf/source_context.pb.cc b/contrib/libs/protobuf_old/src/google/protobuf/source_context.pb.cc new file mode 100644 index 0000000000..15dd5494e8 --- /dev/null +++ b/contrib/libs/protobuf_old/src/google/protobuf/source_context.pb.cc @@ -0,0 +1,289 @@ +// Generated by the protocol buffer compiler. DO NOT EDIT! +// source: google/protobuf/source_context.proto + +#include <google/protobuf/source_context.pb.h> + +#include <algorithm> + +#include <google/protobuf/io/coded_stream.h> +#include <google/protobuf/extension_set.h> +#include <google/protobuf/wire_format_lite.h> +#include <google/protobuf/descriptor.h> +#include <google/protobuf/generated_message_reflection.h> +#include <google/protobuf/reflection_ops.h> +#include <google/protobuf/wire_format.h> +// @@protoc_insertion_point(includes) +#include <google/protobuf/port_def.inc> + +PROTOBUF_PRAGMA_INIT_SEG +PROTOBUF_NAMESPACE_OPEN +constexpr SourceContext::SourceContext( + ::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized) + : file_name_(&::PROTOBUF_NAMESPACE_ID::internal::fixed_address_empty_string){} +struct SourceContextDefaultTypeInternal { + constexpr SourceContextDefaultTypeInternal() + : _instance(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized{}) {} + ~SourceContextDefaultTypeInternal() {} + union { + SourceContext _instance; + }; +}; +PROTOBUF_ATTRIBUTE_NO_DESTROY PROTOBUF_CONSTINIT SourceContextDefaultTypeInternal _SourceContext_default_instance_; +PROTOBUF_NAMESPACE_CLOSE +static ::PROTOBUF_NAMESPACE_ID::Metadata file_level_metadata_google_2fprotobuf_2fsource_5fcontext_2eproto[1]; +static constexpr ::PROTOBUF_NAMESPACE_ID::EnumDescriptor const** file_level_enum_descriptors_google_2fprotobuf_2fsource_5fcontext_2eproto = nullptr; +static constexpr ::PROTOBUF_NAMESPACE_ID::ServiceDescriptor const** file_level_service_descriptors_google_2fprotobuf_2fsource_5fcontext_2eproto = nullptr; + +const arc_ui32 TableStruct_google_2fprotobuf_2fsource_5fcontext_2eproto::offsets[] PROTOBUF_SECTION_VARIABLE(protodesc_cold) = { + ~0u, // no _has_bits_ + PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::SourceContext, _internal_metadata_), + ~0u, // no _extensions_ + ~0u, // no _oneof_case_ + ~0u, // no _weak_field_map_ + ~0u, // no _inlined_string_donated_ + PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::SourceContext, file_name_), +}; +static const ::PROTOBUF_NAMESPACE_ID::internal::MigrationSchema schemas[] PROTOBUF_SECTION_VARIABLE(protodesc_cold) = { + { 0, -1, -1, sizeof(::PROTOBUF_NAMESPACE_ID::SourceContext)}, +}; + +static ::PROTOBUF_NAMESPACE_ID::Message const * const file_default_instances[] = { + reinterpret_cast<const ::PROTOBUF_NAMESPACE_ID::Message*>(&::PROTOBUF_NAMESPACE_ID::_SourceContext_default_instance_), +}; + +const char descriptor_table_protodef_google_2fprotobuf_2fsource_5fcontext_2eproto[] PROTOBUF_SECTION_VARIABLE(protodesc_cold) = + "\n$google/protobuf/source_context.proto\022\017" + "google.protobuf\"\"\n\rSourceContext\022\021\n\tfile" + "_name\030\001 \001(\tB\212\001\n\023com.google.protobufB\022Sou" + "rceContextProtoP\001Z6google.golang.org/pro" + "tobuf/types/known/sourcecontextpb\242\002\003GPB\252" + "\002\036Google.Protobuf.WellKnownTypesb\006proto3" + ; +static ::PROTOBUF_NAMESPACE_ID::internal::once_flag descriptor_table_google_2fprotobuf_2fsource_5fcontext_2eproto_once; +const ::PROTOBUF_NAMESPACE_ID::internal::DescriptorTable descriptor_table_google_2fprotobuf_2fsource_5fcontext_2eproto = { + false, false, 240, descriptor_table_protodef_google_2fprotobuf_2fsource_5fcontext_2eproto, "google/protobuf/source_context.proto", + &descriptor_table_google_2fprotobuf_2fsource_5fcontext_2eproto_once, nullptr, 0, 1, + schemas, file_default_instances, TableStruct_google_2fprotobuf_2fsource_5fcontext_2eproto::offsets, + file_level_metadata_google_2fprotobuf_2fsource_5fcontext_2eproto, file_level_enum_descriptors_google_2fprotobuf_2fsource_5fcontext_2eproto, file_level_service_descriptors_google_2fprotobuf_2fsource_5fcontext_2eproto, +}; +PROTOBUF_ATTRIBUTE_WEAK const ::PROTOBUF_NAMESPACE_ID::internal::DescriptorTable* descriptor_table_google_2fprotobuf_2fsource_5fcontext_2eproto_getter() { + return &descriptor_table_google_2fprotobuf_2fsource_5fcontext_2eproto; +} + +// Force running AddDescriptors() at dynamic initialization time. +PROTOBUF_ATTRIBUTE_INIT_PRIORITY static ::PROTOBUF_NAMESPACE_ID::internal::AddDescriptorsRunner dynamic_init_dummy_google_2fprotobuf_2fsource_5fcontext_2eproto(&descriptor_table_google_2fprotobuf_2fsource_5fcontext_2eproto); +PROTOBUF_NAMESPACE_OPEN + +// =================================================================== + +class SourceContext::_Internal { + public: +}; + +SourceContext::SourceContext(::PROTOBUF_NAMESPACE_ID::Arena* arena, + bool is_message_owned) + : ::PROTOBUF_NAMESPACE_ID::Message(arena, is_message_owned) { + SharedCtor(); + if (!is_message_owned) { + RegisterArenaDtor(arena); + } + // @@protoc_insertion_point(arena_constructor:google.protobuf.SourceContext) +} +SourceContext::SourceContext(const SourceContext& from) + : ::PROTOBUF_NAMESPACE_ID::Message() { + _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_); + file_name_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); + #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING + file_name_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation()); + #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING + if (!from._internal_file_name().empty()) { + file_name_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, from._internal_file_name(), + GetArenaForAllocation()); + } + // @@protoc_insertion_point(copy_constructor:google.protobuf.SourceContext) +} + +inline void SourceContext::SharedCtor() { +file_name_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); +#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING + file_name_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation()); +#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING +} + +SourceContext::~SourceContext() { + // @@protoc_insertion_point(destructor:google.protobuf.SourceContext) + if (GetArenaForAllocation() != nullptr) return; + SharedDtor(); + _internal_metadata_.Delete<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(); +} + +inline void SourceContext::SharedDtor() { + GOOGLE_DCHECK(GetArenaForAllocation() == nullptr); + file_name_.DestroyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); +} + +void SourceContext::ArenaDtor(void* object) { + SourceContext* _this = reinterpret_cast< SourceContext* >(object); + (void)_this; +} +void SourceContext::RegisterArenaDtor(::PROTOBUF_NAMESPACE_ID::Arena*) { +} +void SourceContext::SetCachedSize(int size) const { + _cached_size_.Set(size); +} + +void SourceContext::Clear() { +// @@protoc_insertion_point(message_clear_start:google.protobuf.SourceContext) + arc_ui32 cached_has_bits = 0; + // Prevent compiler warnings about cached_has_bits being unused + (void) cached_has_bits; + + file_name_.ClearToEmpty(); + _internal_metadata_.Clear<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(); +} + +const char* SourceContext::_InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) { +#define CHK_(x) if (PROTOBUF_PREDICT_FALSE(!(x))) goto failure + while (!ctx->Done(&ptr)) { + arc_ui32 tag; + ptr = ::PROTOBUF_NAMESPACE_ID::internal::ReadTag(ptr, &tag); + switch (tag >> 3) { + // string file_name = 1; + case 1: + if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 10)) { + auto str = _internal_mutable_file_name(); + ptr = ::PROTOBUF_NAMESPACE_ID::internal::InlineGreedyStringParser(str, ptr, ctx); + CHK_(::PROTOBUF_NAMESPACE_ID::internal::VerifyUTF8(str, "google.protobuf.SourceContext.file_name")); + CHK_(ptr); + } else + goto handle_unusual; + continue; + default: + goto handle_unusual; + } // switch + handle_unusual: + if ((tag == 0) || ((tag & 7) == 4)) { + CHK_(ptr); + ctx->SetLastTag(tag); + goto message_done; + } + ptr = UnknownFieldParse( + tag, + _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(), + ptr, ctx); + CHK_(ptr != nullptr); + } // while +message_done: + return ptr; +failure: + ptr = nullptr; + goto message_done; +#undef CHK_ +} + +uint8_t* SourceContext::_InternalSerialize( + uint8_t* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const { + // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.SourceContext) + arc_ui32 cached_has_bits = 0; + (void) cached_has_bits; + + // string file_name = 1; + if (!this->_internal_file_name().empty()) { + ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::VerifyUtf8String( + this->_internal_file_name().data(), static_cast<int>(this->_internal_file_name().length()), + ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::SERIALIZE, + "google.protobuf.SourceContext.file_name"); + target = stream->WriteStringMaybeAliased( + 1, this->_internal_file_name(), target); + } + + if (PROTOBUF_PREDICT_FALSE(_internal_metadata_.have_unknown_fields())) { + target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::InternalSerializeUnknownFieldsToArray( + _internal_metadata_.unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(::PROTOBUF_NAMESPACE_ID::UnknownFieldSet::default_instance), target, stream); + } + // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.SourceContext) + return target; +} + +size_t SourceContext::ByteSizeLong() const { +// @@protoc_insertion_point(message_byte_size_start:google.protobuf.SourceContext) + size_t total_size = 0; + + arc_ui32 cached_has_bits = 0; + // Prevent compiler warnings about cached_has_bits being unused + (void) cached_has_bits; + + // string file_name = 1; + if (!this->_internal_file_name().empty()) { + total_size += 1 + + ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::StringSize( + this->_internal_file_name()); + } + + return MaybeComputeUnknownFieldsSize(total_size, &_cached_size_); +} + +const ::PROTOBUF_NAMESPACE_ID::Message::ClassData SourceContext::_class_data_ = { + ::PROTOBUF_NAMESPACE_ID::Message::CopyWithSizeCheck, + SourceContext::MergeImpl +}; +const ::PROTOBUF_NAMESPACE_ID::Message::ClassData*SourceContext::GetClassData() const { return &_class_data_; } + +void SourceContext::MergeImpl(::PROTOBUF_NAMESPACE_ID::Message* to, + const ::PROTOBUF_NAMESPACE_ID::Message& from) { + static_cast<SourceContext *>(to)->MergeFrom( + static_cast<const SourceContext &>(from)); +} + + +void SourceContext::MergeFrom(const SourceContext& from) { +// @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.SourceContext) + GOOGLE_DCHECK_NE(&from, this); + arc_ui32 cached_has_bits = 0; + (void) cached_has_bits; + + if (!from._internal_file_name().empty()) { + _internal_set_file_name(from._internal_file_name()); + } + _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_); +} + +void SourceContext::CopyFrom(const SourceContext& from) { +// @@protoc_insertion_point(class_specific_copy_from_start:google.protobuf.SourceContext) + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool SourceContext::IsInitialized() const { + return true; +} + +void SourceContext::InternalSwap(SourceContext* other) { + using std::swap; + auto* lhs_arena = GetArenaForAllocation(); + auto* rhs_arena = other->GetArenaForAllocation(); + _internal_metadata_.InternalSwap(&other->_internal_metadata_); + ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::InternalSwap( + &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), + &file_name_, lhs_arena, + &other->file_name_, rhs_arena + ); +} + +::PROTOBUF_NAMESPACE_ID::Metadata SourceContext::GetMetadata() const { + return ::PROTOBUF_NAMESPACE_ID::internal::AssignDescriptors( + &descriptor_table_google_2fprotobuf_2fsource_5fcontext_2eproto_getter, &descriptor_table_google_2fprotobuf_2fsource_5fcontext_2eproto_once, + file_level_metadata_google_2fprotobuf_2fsource_5fcontext_2eproto[0]); +} + +// @@protoc_insertion_point(namespace_scope) +PROTOBUF_NAMESPACE_CLOSE +PROTOBUF_NAMESPACE_OPEN +template<> PROTOBUF_NOINLINE ::PROTOBUF_NAMESPACE_ID::SourceContext* Arena::CreateMaybeMessage< ::PROTOBUF_NAMESPACE_ID::SourceContext >(Arena* arena) { + return Arena::CreateMessageInternal< ::PROTOBUF_NAMESPACE_ID::SourceContext >(arena); +} +PROTOBUF_NAMESPACE_CLOSE + +// @@protoc_insertion_point(global_scope) +#include <google/protobuf/port_undef.inc> diff --git a/contrib/libs/protobuf_old/src/google/protobuf/source_context.pb.h b/contrib/libs/protobuf_old/src/google/protobuf/source_context.pb.h new file mode 100644 index 0000000000..408200d2bf --- /dev/null +++ b/contrib/libs/protobuf_old/src/google/protobuf/source_context.pb.h @@ -0,0 +1,290 @@ +// Generated by the protocol buffer compiler. DO NOT EDIT! +// source: google/protobuf/source_context.proto + +#ifndef GOOGLE_PROTOBUF_INCLUDED_google_2fprotobuf_2fsource_5fcontext_2eproto +#define GOOGLE_PROTOBUF_INCLUDED_google_2fprotobuf_2fsource_5fcontext_2eproto + +#include <limits> +#include <string> + +#include <google/protobuf/port_def.inc> +#if PROTOBUF_VERSION < 3019000 +#error This file was generated by a newer version of protoc which is +#error incompatible with your Protocol Buffer headers. Please update +#error your headers. +#endif +#if 3019000 < PROTOBUF_MIN_PROTOC_VERSION +#error This file was generated by an older version of protoc which is +#error incompatible with your Protocol Buffer headers. Please +#error regenerate this file with a newer version of protoc. +#endif + +#include <google/protobuf/port_undef.inc> +#include <google/protobuf/io/coded_stream.h> +#include <google/protobuf/arena.h> +#include <google/protobuf/arenastring.h> +#include <google/protobuf/generated_message_table_driven.h> +#include <google/protobuf/generated_message_util.h> +#include <google/protobuf/metadata_lite.h> +#include <google/protobuf/generated_message_reflection.h> +#include <google/protobuf/message.h> +#include <google/protobuf/repeated_field.h> // IWYU pragma: export +#include <google/protobuf/extension_set.h> // IWYU pragma: export +#include <google/protobuf/unknown_field_set.h> +// @@protoc_insertion_point(includes) +#include <google/protobuf/port_def.inc> +#define PROTOBUF_INTERNAL_EXPORT_google_2fprotobuf_2fsource_5fcontext_2eproto PROTOBUF_EXPORT +PROTOBUF_NAMESPACE_OPEN +namespace internal { +class AnyMetadata; +} // namespace internal +PROTOBUF_NAMESPACE_CLOSE + +// Internal implementation detail -- do not use these members. +struct PROTOBUF_EXPORT TableStruct_google_2fprotobuf_2fsource_5fcontext_2eproto { + static const ::PROTOBUF_NAMESPACE_ID::internal::ParseTableField entries[] + PROTOBUF_SECTION_VARIABLE(protodesc_cold); + static const ::PROTOBUF_NAMESPACE_ID::internal::AuxiliaryParseTableField aux[] + PROTOBUF_SECTION_VARIABLE(protodesc_cold); + static const ::PROTOBUF_NAMESPACE_ID::internal::ParseTable schema[1] + PROTOBUF_SECTION_VARIABLE(protodesc_cold); + static const ::PROTOBUF_NAMESPACE_ID::internal::FieldMetadata field_metadata[]; + static const ::PROTOBUF_NAMESPACE_ID::internal::SerializationTable serialization_table[]; + static const arc_ui32 offsets[]; +}; +PROTOBUF_EXPORT extern const ::PROTOBUF_NAMESPACE_ID::internal::DescriptorTable descriptor_table_google_2fprotobuf_2fsource_5fcontext_2eproto; +PROTOBUF_NAMESPACE_OPEN +class SourceContext; +struct SourceContextDefaultTypeInternal; +PROTOBUF_EXPORT extern SourceContextDefaultTypeInternal _SourceContext_default_instance_; +PROTOBUF_NAMESPACE_CLOSE +PROTOBUF_NAMESPACE_OPEN +template<> PROTOBUF_EXPORT ::PROTOBUF_NAMESPACE_ID::SourceContext* Arena::CreateMaybeMessage<::PROTOBUF_NAMESPACE_ID::SourceContext>(Arena*); +PROTOBUF_NAMESPACE_CLOSE +PROTOBUF_NAMESPACE_OPEN + +// =================================================================== + +class PROTOBUF_EXPORT SourceContext final : + public ::PROTOBUF_NAMESPACE_ID::Message /* @@protoc_insertion_point(class_definition:google.protobuf.SourceContext) */ { + public: + inline SourceContext() : SourceContext(nullptr) {} + ~SourceContext() override; + explicit constexpr SourceContext(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized); + + SourceContext(const SourceContext& from); + SourceContext(SourceContext&& from) noexcept + : SourceContext() { + *this = ::std::move(from); + } + + inline SourceContext& operator=(const SourceContext& from) { + CopyFrom(from); + return *this; + } + inline SourceContext& operator=(SourceContext&& from) noexcept { + if (this == &from) return *this; + if (GetOwningArena() == from.GetOwningArena() + #ifdef PROTOBUF_FORCE_COPY_IN_MOVE + && GetOwningArena() != nullptr + #endif // !PROTOBUF_FORCE_COPY_IN_MOVE + ) { + InternalSwap(&from); + } else { + CopyFrom(from); + } + return *this; + } + + static const ::PROTOBUF_NAMESPACE_ID::Descriptor* descriptor() { + return GetDescriptor(); + } + static const ::PROTOBUF_NAMESPACE_ID::Descriptor* GetDescriptor() { + return default_instance().GetMetadata().descriptor; + } + static const ::PROTOBUF_NAMESPACE_ID::Reflection* GetReflection() { + return default_instance().GetMetadata().reflection; + } + static const SourceContext& default_instance() { + return *internal_default_instance(); + } + static inline const SourceContext* internal_default_instance() { + return reinterpret_cast<const SourceContext*>( + &_SourceContext_default_instance_); + } + static constexpr int kIndexInFileMessages = + 0; + + friend void swap(SourceContext& a, SourceContext& b) { + a.Swap(&b); + } + inline void Swap(SourceContext* other) { + if (other == this) return; + #ifdef PROTOBUF_FORCE_COPY_IN_SWAP + if (GetOwningArena() != nullptr && + GetOwningArena() == other->GetOwningArena()) { + #else // PROTOBUF_FORCE_COPY_IN_SWAP + if (GetOwningArena() == other->GetOwningArena()) { + #endif // !PROTOBUF_FORCE_COPY_IN_SWAP + InternalSwap(other); + } else { + ::PROTOBUF_NAMESPACE_ID::internal::GenericSwap(this, other); + } + } + void UnsafeArenaSwap(SourceContext* other) { + if (other == this) return; + GOOGLE_DCHECK(GetOwningArena() == other->GetOwningArena()); + InternalSwap(other); + } + + // implements Message ---------------------------------------------- + + SourceContext* New(::PROTOBUF_NAMESPACE_ID::Arena* arena = nullptr) const final { + return CreateMaybeMessage<SourceContext>(arena); + } + using ::PROTOBUF_NAMESPACE_ID::Message::CopyFrom; + void CopyFrom(const SourceContext& from); + using ::PROTOBUF_NAMESPACE_ID::Message::MergeFrom; + void MergeFrom(const SourceContext& 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; + + size_t ByteSizeLong() const final; + const char* _InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) final; + uint8_t* _InternalSerialize( + uint8_t* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const final; + int GetCachedSize() const final { return _cached_size_.Get(); } + + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const final; + void InternalSwap(SourceContext* other); + + private: + friend class ::PROTOBUF_NAMESPACE_ID::internal::AnyMetadata; + static ::PROTOBUF_NAMESPACE_ID::StringPiece FullMessageName() { + return "google.protobuf.SourceContext"; + } + protected: + explicit SourceContext(::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 ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + enum : int { + kFileNameFieldNumber = 1, + }; + // string file_name = 1; + void clear_file_name(); + const TProtoStringType& file_name() const; + template <typename ArgT0 = const TProtoStringType&, typename... ArgT> + void set_file_name(ArgT0&& arg0, ArgT... args); + TProtoStringType* mutable_file_name(); + PROTOBUF_NODISCARD TProtoStringType* release_file_name(); + void set_allocated_file_name(TProtoStringType* file_name); + private: + const TProtoStringType& _internal_file_name() const; + inline PROTOBUF_ALWAYS_INLINE void _internal_set_file_name(const TProtoStringType& value); + TProtoStringType* _internal_mutable_file_name(); + public: + + // @@protoc_insertion_point(class_scope:google.protobuf.SourceContext) + private: + class _Internal; + + template <typename T> friend class ::PROTOBUF_NAMESPACE_ID::Arena::InternalHelper; + typedef void InternalArenaConstructable_; + typedef void DestructorSkippable_; + ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr file_name_; + mutable ::PROTOBUF_NAMESPACE_ID::internal::CachedSize _cached_size_; + friend struct ::TableStruct_google_2fprotobuf_2fsource_5fcontext_2eproto; +}; +// =================================================================== + + +// =================================================================== + +#ifdef __GNUC__ + #pragma GCC diagnostic push + #pragma GCC diagnostic ignored "-Wstrict-aliasing" +#endif // __GNUC__ +// SourceContext + +// string file_name = 1; +inline void SourceContext::clear_file_name() { + file_name_.ClearToEmpty(); +} +inline const TProtoStringType& SourceContext::file_name() const { + // @@protoc_insertion_point(field_get:google.protobuf.SourceContext.file_name) + return _internal_file_name(); +} +template <typename ArgT0, typename... ArgT> +inline PROTOBUF_ALWAYS_INLINE +void SourceContext::set_file_name(ArgT0&& arg0, ArgT... args) { + + file_name_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, static_cast<ArgT0 &&>(arg0), args..., GetArenaForAllocation()); + // @@protoc_insertion_point(field_set:google.protobuf.SourceContext.file_name) +} +inline TProtoStringType* SourceContext::mutable_file_name() { + TProtoStringType* _s = _internal_mutable_file_name(); + // @@protoc_insertion_point(field_mutable:google.protobuf.SourceContext.file_name) + return _s; +} +inline const TProtoStringType& SourceContext::_internal_file_name() const { + return file_name_.Get(); +} +inline void SourceContext::_internal_set_file_name(const TProtoStringType& value) { + + file_name_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, value, GetArenaForAllocation()); +} +inline TProtoStringType* SourceContext::_internal_mutable_file_name() { + + return file_name_.Mutable(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, GetArenaForAllocation()); +} +inline TProtoStringType* SourceContext::release_file_name() { + // @@protoc_insertion_point(field_release:google.protobuf.SourceContext.file_name) + return file_name_.Release(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArenaForAllocation()); +} +inline void SourceContext::set_allocated_file_name(TProtoStringType* file_name) { + if (file_name != nullptr) { + + } else { + + } + file_name_.SetAllocated(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), file_name, + GetArenaForAllocation()); +#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING + if (file_name_.IsDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited())) { + file_name_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation()); + } +#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING + // @@protoc_insertion_point(field_set_allocated:google.protobuf.SourceContext.file_name) +} + +#ifdef __GNUC__ + #pragma GCC diagnostic pop +#endif // __GNUC__ + +// @@protoc_insertion_point(namespace_scope) + +PROTOBUF_NAMESPACE_CLOSE + +// @@protoc_insertion_point(global_scope) + +#include <google/protobuf/port_undef.inc> +#endif // GOOGLE_PROTOBUF_INCLUDED_GOOGLE_PROTOBUF_INCLUDED_google_2fprotobuf_2fsource_5fcontext_2eproto diff --git a/contrib/libs/protobuf_old/src/google/protobuf/source_context.proto b/contrib/libs/protobuf_old/src/google/protobuf/source_context.proto new file mode 100644 index 0000000000..06bfc43a78 --- /dev/null +++ b/contrib/libs/protobuf_old/src/google/protobuf/source_context.proto @@ -0,0 +1,48 @@ +// 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 google.protobuf; + +option csharp_namespace = "Google.Protobuf.WellKnownTypes"; +option java_package = "com.google.protobuf"; +option java_outer_classname = "SourceContextProto"; +option java_multiple_files = true; +option objc_class_prefix = "GPB"; +option go_package = "google.golang.org/protobuf/types/known/sourcecontextpb"; + +// `SourceContext` represents information about the source of a +// protobuf element, like the file in which it is defined. +message SourceContext { + // The path-qualified name of the .proto file that contained the associated + // protobuf element. For example: `"google/protobuf/source_context.proto"`. + string file_name = 1; +} diff --git a/contrib/libs/protobuf_old/src/google/protobuf/struct.pb.cc b/contrib/libs/protobuf_old/src/google/protobuf/struct.pb.cc new file mode 100644 index 0000000000..4596e7b2a5 --- /dev/null +++ b/contrib/libs/protobuf_old/src/google/protobuf/struct.pb.cc @@ -0,0 +1,1048 @@ +// Generated by the protocol buffer compiler. DO NOT EDIT! +// source: google/protobuf/struct.proto + +#include <google/protobuf/struct.pb.h> + +#include <algorithm> + +#include <google/protobuf/io/coded_stream.h> +#include <google/protobuf/extension_set.h> +#include <google/protobuf/wire_format_lite.h> +#include <google/protobuf/descriptor.h> +#include <google/protobuf/generated_message_reflection.h> +#include <google/protobuf/reflection_ops.h> +#include <google/protobuf/wire_format.h> +// @@protoc_insertion_point(includes) +#include <google/protobuf/port_def.inc> + +PROTOBUF_PRAGMA_INIT_SEG +PROTOBUF_NAMESPACE_OPEN +constexpr Struct_FieldsEntry_DoNotUse::Struct_FieldsEntry_DoNotUse( + ::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized){} +struct Struct_FieldsEntry_DoNotUseDefaultTypeInternal { + constexpr Struct_FieldsEntry_DoNotUseDefaultTypeInternal() + : _instance(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized{}) {} + ~Struct_FieldsEntry_DoNotUseDefaultTypeInternal() {} + union { + Struct_FieldsEntry_DoNotUse _instance; + }; +}; +PROTOBUF_ATTRIBUTE_NO_DESTROY PROTOBUF_CONSTINIT Struct_FieldsEntry_DoNotUseDefaultTypeInternal _Struct_FieldsEntry_DoNotUse_default_instance_; +constexpr Struct::Struct( + ::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized) + : fields_(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized{}){} +struct StructDefaultTypeInternal { + constexpr StructDefaultTypeInternal() + : _instance(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized{}) {} + ~StructDefaultTypeInternal() {} + union { + Struct _instance; + }; +}; +PROTOBUF_ATTRIBUTE_NO_DESTROY PROTOBUF_CONSTINIT StructDefaultTypeInternal _Struct_default_instance_; +constexpr Value::Value( + ::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized) + : _oneof_case_{}{} +struct ValueDefaultTypeInternal { + constexpr ValueDefaultTypeInternal() + : _instance(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized{}) {} + ~ValueDefaultTypeInternal() {} + union { + Value _instance; + }; +}; +PROTOBUF_ATTRIBUTE_NO_DESTROY PROTOBUF_CONSTINIT ValueDefaultTypeInternal _Value_default_instance_; +constexpr ListValue::ListValue( + ::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized) + : values_(){} +struct ListValueDefaultTypeInternal { + constexpr ListValueDefaultTypeInternal() + : _instance(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized{}) {} + ~ListValueDefaultTypeInternal() {} + union { + ListValue _instance; + }; +}; +PROTOBUF_ATTRIBUTE_NO_DESTROY PROTOBUF_CONSTINIT ListValueDefaultTypeInternal _ListValue_default_instance_; +PROTOBUF_NAMESPACE_CLOSE +static ::PROTOBUF_NAMESPACE_ID::Metadata file_level_metadata_google_2fprotobuf_2fstruct_2eproto[4]; +static const ::PROTOBUF_NAMESPACE_ID::EnumDescriptor* file_level_enum_descriptors_google_2fprotobuf_2fstruct_2eproto[1]; +static constexpr ::PROTOBUF_NAMESPACE_ID::ServiceDescriptor const** file_level_service_descriptors_google_2fprotobuf_2fstruct_2eproto = nullptr; + +const arc_ui32 TableStruct_google_2fprotobuf_2fstruct_2eproto::offsets[] PROTOBUF_SECTION_VARIABLE(protodesc_cold) = { + PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::Struct_FieldsEntry_DoNotUse, _has_bits_), + PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::Struct_FieldsEntry_DoNotUse, _internal_metadata_), + ~0u, // no _extensions_ + ~0u, // no _oneof_case_ + ~0u, // no _weak_field_map_ + ~0u, // no _inlined_string_donated_ + PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::Struct_FieldsEntry_DoNotUse, key_), + PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::Struct_FieldsEntry_DoNotUse, value_), + 0, + 1, + ~0u, // no _has_bits_ + PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::Struct, _internal_metadata_), + ~0u, // no _extensions_ + ~0u, // no _oneof_case_ + ~0u, // no _weak_field_map_ + ~0u, // no _inlined_string_donated_ + PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::Struct, fields_), + ~0u, // no _has_bits_ + PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::Value, _internal_metadata_), + ~0u, // no _extensions_ + PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::Value, _oneof_case_[0]), + ~0u, // no _weak_field_map_ + ~0u, // no _inlined_string_donated_ + ::PROTOBUF_NAMESPACE_ID::internal::kInvalidFieldOffsetTag, + ::PROTOBUF_NAMESPACE_ID::internal::kInvalidFieldOffsetTag, + ::PROTOBUF_NAMESPACE_ID::internal::kInvalidFieldOffsetTag, + ::PROTOBUF_NAMESPACE_ID::internal::kInvalidFieldOffsetTag, + ::PROTOBUF_NAMESPACE_ID::internal::kInvalidFieldOffsetTag, + ::PROTOBUF_NAMESPACE_ID::internal::kInvalidFieldOffsetTag, + PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::Value, kind_), + ~0u, // no _has_bits_ + PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::ListValue, _internal_metadata_), + ~0u, // no _extensions_ + ~0u, // no _oneof_case_ + ~0u, // no _weak_field_map_ + ~0u, // no _inlined_string_donated_ + PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::ListValue, values_), +}; +static const ::PROTOBUF_NAMESPACE_ID::internal::MigrationSchema schemas[] PROTOBUF_SECTION_VARIABLE(protodesc_cold) = { + { 0, 8, -1, sizeof(::PROTOBUF_NAMESPACE_ID::Struct_FieldsEntry_DoNotUse)}, + { 10, -1, -1, sizeof(::PROTOBUF_NAMESPACE_ID::Struct)}, + { 17, -1, -1, sizeof(::PROTOBUF_NAMESPACE_ID::Value)}, + { 30, -1, -1, sizeof(::PROTOBUF_NAMESPACE_ID::ListValue)}, +}; + +static ::PROTOBUF_NAMESPACE_ID::Message const * const file_default_instances[] = { + reinterpret_cast<const ::PROTOBUF_NAMESPACE_ID::Message*>(&::PROTOBUF_NAMESPACE_ID::_Struct_FieldsEntry_DoNotUse_default_instance_), + reinterpret_cast<const ::PROTOBUF_NAMESPACE_ID::Message*>(&::PROTOBUF_NAMESPACE_ID::_Struct_default_instance_), + reinterpret_cast<const ::PROTOBUF_NAMESPACE_ID::Message*>(&::PROTOBUF_NAMESPACE_ID::_Value_default_instance_), + reinterpret_cast<const ::PROTOBUF_NAMESPACE_ID::Message*>(&::PROTOBUF_NAMESPACE_ID::_ListValue_default_instance_), +}; + +const char descriptor_table_protodef_google_2fprotobuf_2fstruct_2eproto[] PROTOBUF_SECTION_VARIABLE(protodesc_cold) = + "\n\034google/protobuf/struct.proto\022\017google.p" + "rotobuf\"\204\001\n\006Struct\0223\n\006fields\030\001 \003(\0132#.goo" + "gle.protobuf.Struct.FieldsEntry\032E\n\013Field" + "sEntry\022\013\n\003key\030\001 \001(\t\022%\n\005value\030\002 \001(\0132\026.goo" + "gle.protobuf.Value:\0028\001\"\352\001\n\005Value\0220\n\nnull" + "_value\030\001 \001(\0162\032.google.protobuf.NullValue" + "H\000\022\026\n\014number_value\030\002 \001(\001H\000\022\026\n\014string_val" + "ue\030\003 \001(\tH\000\022\024\n\nbool_value\030\004 \001(\010H\000\022/\n\014stru" + "ct_value\030\005 \001(\0132\027.google.protobuf.StructH" + "\000\0220\n\nlist_value\030\006 \001(\0132\032.google.protobuf." + "ListValueH\000B\006\n\004kind\"3\n\tListValue\022&\n\006valu" + "es\030\001 \003(\0132\026.google.protobuf.Value*\033\n\tNull" + "Value\022\016\n\nNULL_VALUE\020\000B\177\n\023com.google.prot" + "obufB\013StructProtoP\001Z/google.golang.org/p" + "rotobuf/types/known/structpb\370\001\001\242\002\003GPB\252\002\036" + "Google.Protobuf.WellKnownTypesb\006proto3" + ; +static ::PROTOBUF_NAMESPACE_ID::internal::once_flag descriptor_table_google_2fprotobuf_2fstruct_2eproto_once; +const ::PROTOBUF_NAMESPACE_ID::internal::DescriptorTable descriptor_table_google_2fprotobuf_2fstruct_2eproto = { + false, false, 638, descriptor_table_protodef_google_2fprotobuf_2fstruct_2eproto, "google/protobuf/struct.proto", + &descriptor_table_google_2fprotobuf_2fstruct_2eproto_once, nullptr, 0, 4, + schemas, file_default_instances, TableStruct_google_2fprotobuf_2fstruct_2eproto::offsets, + file_level_metadata_google_2fprotobuf_2fstruct_2eproto, file_level_enum_descriptors_google_2fprotobuf_2fstruct_2eproto, file_level_service_descriptors_google_2fprotobuf_2fstruct_2eproto, +}; +PROTOBUF_ATTRIBUTE_WEAK const ::PROTOBUF_NAMESPACE_ID::internal::DescriptorTable* descriptor_table_google_2fprotobuf_2fstruct_2eproto_getter() { + return &descriptor_table_google_2fprotobuf_2fstruct_2eproto; +} + +// Force running AddDescriptors() at dynamic initialization time. +PROTOBUF_ATTRIBUTE_INIT_PRIORITY static ::PROTOBUF_NAMESPACE_ID::internal::AddDescriptorsRunner dynamic_init_dummy_google_2fprotobuf_2fstruct_2eproto(&descriptor_table_google_2fprotobuf_2fstruct_2eproto); +PROTOBUF_NAMESPACE_OPEN +const ::PROTOBUF_NAMESPACE_ID::EnumDescriptor* NullValue_descriptor() { + ::PROTOBUF_NAMESPACE_ID::internal::AssignDescriptors(&descriptor_table_google_2fprotobuf_2fstruct_2eproto); + return file_level_enum_descriptors_google_2fprotobuf_2fstruct_2eproto[0]; +} +bool NullValue_IsValid(int value) { + switch (value) { + case 0: + return true; + default: + return false; + } +} + + +// =================================================================== + +Struct_FieldsEntry_DoNotUse::Struct_FieldsEntry_DoNotUse() {} +Struct_FieldsEntry_DoNotUse::Struct_FieldsEntry_DoNotUse(::PROTOBUF_NAMESPACE_ID::Arena* arena) + : SuperType(arena) {} +void Struct_FieldsEntry_DoNotUse::MergeFrom(const Struct_FieldsEntry_DoNotUse& other) { + MergeFromInternal(other); +} +::PROTOBUF_NAMESPACE_ID::Metadata Struct_FieldsEntry_DoNotUse::GetMetadata() const { + return ::PROTOBUF_NAMESPACE_ID::internal::AssignDescriptors( + &descriptor_table_google_2fprotobuf_2fstruct_2eproto_getter, &descriptor_table_google_2fprotobuf_2fstruct_2eproto_once, + file_level_metadata_google_2fprotobuf_2fstruct_2eproto[0]); +} + +// =================================================================== + +class Struct::_Internal { + public: +}; + +Struct::Struct(::PROTOBUF_NAMESPACE_ID::Arena* arena, + bool is_message_owned) + : ::PROTOBUF_NAMESPACE_ID::Message(arena, is_message_owned), + fields_(arena) { + SharedCtor(); + if (!is_message_owned) { + RegisterArenaDtor(arena); + } + // @@protoc_insertion_point(arena_constructor:google.protobuf.Struct) +} +Struct::Struct(const Struct& from) + : ::PROTOBUF_NAMESPACE_ID::Message() { + _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_); + fields_.MergeFrom(from.fields_); + // @@protoc_insertion_point(copy_constructor:google.protobuf.Struct) +} + +inline void Struct::SharedCtor() { +} + +Struct::~Struct() { + // @@protoc_insertion_point(destructor:google.protobuf.Struct) + if (GetArenaForAllocation() != nullptr) return; + SharedDtor(); + _internal_metadata_.Delete<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(); +} + +inline void Struct::SharedDtor() { + GOOGLE_DCHECK(GetArenaForAllocation() == nullptr); +} + +void Struct::ArenaDtor(void* object) { + Struct* _this = reinterpret_cast< Struct* >(object); + (void)_this; + _this->fields_. ~MapField(); +} +inline void Struct::RegisterArenaDtor(::PROTOBUF_NAMESPACE_ID::Arena* arena) { + if (arena != nullptr) { + arena->OwnCustomDestructor(this, &Struct::ArenaDtor); + } +} +void Struct::SetCachedSize(int size) const { + _cached_size_.Set(size); +} + +void Struct::Clear() { +// @@protoc_insertion_point(message_clear_start:google.protobuf.Struct) + arc_ui32 cached_has_bits = 0; + // Prevent compiler warnings about cached_has_bits being unused + (void) cached_has_bits; + + fields_.Clear(); + _internal_metadata_.Clear<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(); +} + +const char* Struct::_InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) { +#define CHK_(x) if (PROTOBUF_PREDICT_FALSE(!(x))) goto failure + while (!ctx->Done(&ptr)) { + arc_ui32 tag; + ptr = ::PROTOBUF_NAMESPACE_ID::internal::ReadTag(ptr, &tag); + switch (tag >> 3) { + // map<string, .google.protobuf.Value> fields = 1; + case 1: + if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 10)) { + ptr -= 1; + do { + ptr += 1; + ptr = ctx->ParseMessage(&fields_, ptr); + CHK_(ptr); + if (!ctx->DataAvailable(ptr)) break; + } while (::PROTOBUF_NAMESPACE_ID::internal::ExpectTag<10>(ptr)); + } else + goto handle_unusual; + continue; + default: + goto handle_unusual; + } // switch + handle_unusual: + if ((tag == 0) || ((tag & 7) == 4)) { + CHK_(ptr); + ctx->SetLastTag(tag); + goto message_done; + } + ptr = UnknownFieldParse( + tag, + _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(), + ptr, ctx); + CHK_(ptr != nullptr); + } // while +message_done: + return ptr; +failure: + ptr = nullptr; + goto message_done; +#undef CHK_ +} + +uint8_t* Struct::_InternalSerialize( + uint8_t* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const { + // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.Struct) + arc_ui32 cached_has_bits = 0; + (void) cached_has_bits; + + // map<string, .google.protobuf.Value> fields = 1; + if (!this->_internal_fields().empty()) { + typedef ::PROTOBUF_NAMESPACE_ID::Map< TProtoStringType, ::PROTOBUF_NAMESPACE_ID::Value >::const_pointer + ConstPtr; + typedef ConstPtr SortItem; + typedef ::PROTOBUF_NAMESPACE_ID::internal::CompareByDerefFirst<SortItem> Less; + struct Utf8Check { + static void Check(ConstPtr p) { + (void)p; + ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::VerifyUtf8String( + p->first.data(), static_cast<int>(p->first.length()), + ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::SERIALIZE, + "google.protobuf.Struct.FieldsEntry.key"); + } + }; + + if (stream->IsSerializationDeterministic() && + this->_internal_fields().size() > 1) { + ::std::unique_ptr<SortItem[]> items( + new SortItem[this->_internal_fields().size()]); + typedef ::PROTOBUF_NAMESPACE_ID::Map< TProtoStringType, ::PROTOBUF_NAMESPACE_ID::Value >::size_type size_type; + size_type n = 0; + for (::PROTOBUF_NAMESPACE_ID::Map< TProtoStringType, ::PROTOBUF_NAMESPACE_ID::Value >::const_iterator + it = this->_internal_fields().begin(); + it != this->_internal_fields().end(); ++it, ++n) { + items[static_cast<ptrdiff_t>(n)] = SortItem(&*it); + } + ::std::sort(&items[0], &items[static_cast<ptrdiff_t>(n)], Less()); + for (size_type i = 0; i < n; i++) { + target = Struct_FieldsEntry_DoNotUse::Funcs::InternalSerialize(1, items[static_cast<ptrdiff_t>(i)]->first, items[static_cast<ptrdiff_t>(i)]->second, target, stream); + Utf8Check::Check(&(*items[static_cast<ptrdiff_t>(i)])); + } + } else { + for (::PROTOBUF_NAMESPACE_ID::Map< TProtoStringType, ::PROTOBUF_NAMESPACE_ID::Value >::const_iterator + it = this->_internal_fields().begin(); + it != this->_internal_fields().end(); ++it) { + target = Struct_FieldsEntry_DoNotUse::Funcs::InternalSerialize(1, it->first, it->second, target, stream); + Utf8Check::Check(&(*it)); + } + } + } + + if (PROTOBUF_PREDICT_FALSE(_internal_metadata_.have_unknown_fields())) { + target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::InternalSerializeUnknownFieldsToArray( + _internal_metadata_.unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(::PROTOBUF_NAMESPACE_ID::UnknownFieldSet::default_instance), target, stream); + } + // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.Struct) + return target; +} + +size_t Struct::ByteSizeLong() const { +// @@protoc_insertion_point(message_byte_size_start:google.protobuf.Struct) + size_t total_size = 0; + + arc_ui32 cached_has_bits = 0; + // Prevent compiler warnings about cached_has_bits being unused + (void) cached_has_bits; + + // map<string, .google.protobuf.Value> fields = 1; + total_size += 1 * + ::PROTOBUF_NAMESPACE_ID::internal::FromIntSize(this->_internal_fields_size()); + for (::PROTOBUF_NAMESPACE_ID::Map< TProtoStringType, ::PROTOBUF_NAMESPACE_ID::Value >::const_iterator + it = this->_internal_fields().begin(); + it != this->_internal_fields().end(); ++it) { + total_size += Struct_FieldsEntry_DoNotUse::Funcs::ByteSizeLong(it->first, it->second); + } + + return MaybeComputeUnknownFieldsSize(total_size, &_cached_size_); +} + +const ::PROTOBUF_NAMESPACE_ID::Message::ClassData Struct::_class_data_ = { + ::PROTOBUF_NAMESPACE_ID::Message::CopyWithSizeCheck, + Struct::MergeImpl +}; +const ::PROTOBUF_NAMESPACE_ID::Message::ClassData*Struct::GetClassData() const { return &_class_data_; } + +void Struct::MergeImpl(::PROTOBUF_NAMESPACE_ID::Message* to, + const ::PROTOBUF_NAMESPACE_ID::Message& from) { + static_cast<Struct *>(to)->MergeFrom( + static_cast<const Struct &>(from)); +} + + +void Struct::MergeFrom(const Struct& from) { +// @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.Struct) + GOOGLE_DCHECK_NE(&from, this); + arc_ui32 cached_has_bits = 0; + (void) cached_has_bits; + + fields_.MergeFrom(from.fields_); + _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_); +} + +void Struct::CopyFrom(const Struct& from) { +// @@protoc_insertion_point(class_specific_copy_from_start:google.protobuf.Struct) + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool Struct::IsInitialized() const { + return true; +} + +void Struct::InternalSwap(Struct* other) { + using std::swap; + _internal_metadata_.InternalSwap(&other->_internal_metadata_); + fields_.InternalSwap(&other->fields_); +} + +::PROTOBUF_NAMESPACE_ID::Metadata Struct::GetMetadata() const { + return ::PROTOBUF_NAMESPACE_ID::internal::AssignDescriptors( + &descriptor_table_google_2fprotobuf_2fstruct_2eproto_getter, &descriptor_table_google_2fprotobuf_2fstruct_2eproto_once, + file_level_metadata_google_2fprotobuf_2fstruct_2eproto[1]); +} + +// =================================================================== + +class Value::_Internal { + public: + static const ::PROTOBUF_NAMESPACE_ID::Struct& struct_value(const Value* msg); + static const ::PROTOBUF_NAMESPACE_ID::ListValue& list_value(const Value* msg); +}; + +const ::PROTOBUF_NAMESPACE_ID::Struct& +Value::_Internal::struct_value(const Value* msg) { + return *msg->kind_.struct_value_; +} +const ::PROTOBUF_NAMESPACE_ID::ListValue& +Value::_Internal::list_value(const Value* msg) { + return *msg->kind_.list_value_; +} +void Value::set_allocated_struct_value(::PROTOBUF_NAMESPACE_ID::Struct* struct_value) { + ::PROTOBUF_NAMESPACE_ID::Arena* message_arena = GetArenaForAllocation(); + clear_kind(); + if (struct_value) { + ::PROTOBUF_NAMESPACE_ID::Arena* submessage_arena = + ::PROTOBUF_NAMESPACE_ID::Arena::InternalHelper<::PROTOBUF_NAMESPACE_ID::Struct>::GetOwningArena(struct_value); + if (message_arena != submessage_arena) { + struct_value = ::PROTOBUF_NAMESPACE_ID::internal::GetOwnedMessage( + message_arena, struct_value, submessage_arena); + } + set_has_struct_value(); + kind_.struct_value_ = struct_value; + } + // @@protoc_insertion_point(field_set_allocated:google.protobuf.Value.struct_value) +} +void Value::set_allocated_list_value(::PROTOBUF_NAMESPACE_ID::ListValue* list_value) { + ::PROTOBUF_NAMESPACE_ID::Arena* message_arena = GetArenaForAllocation(); + clear_kind(); + if (list_value) { + ::PROTOBUF_NAMESPACE_ID::Arena* submessage_arena = + ::PROTOBUF_NAMESPACE_ID::Arena::InternalHelper<::PROTOBUF_NAMESPACE_ID::ListValue>::GetOwningArena(list_value); + if (message_arena != submessage_arena) { + list_value = ::PROTOBUF_NAMESPACE_ID::internal::GetOwnedMessage( + message_arena, list_value, submessage_arena); + } + set_has_list_value(); + kind_.list_value_ = list_value; + } + // @@protoc_insertion_point(field_set_allocated:google.protobuf.Value.list_value) +} +Value::Value(::PROTOBUF_NAMESPACE_ID::Arena* arena, + bool is_message_owned) + : ::PROTOBUF_NAMESPACE_ID::Message(arena, is_message_owned) { + SharedCtor(); + if (!is_message_owned) { + RegisterArenaDtor(arena); + } + // @@protoc_insertion_point(arena_constructor:google.protobuf.Value) +} +Value::Value(const Value& from) + : ::PROTOBUF_NAMESPACE_ID::Message() { + _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_); + clear_has_kind(); + switch (from.kind_case()) { + case kNullValue: { + _internal_set_null_value(from._internal_null_value()); + break; + } + case kNumberValue: { + _internal_set_number_value(from._internal_number_value()); + break; + } + case kStringValue: { + _internal_set_string_value(from._internal_string_value()); + break; + } + case kBoolValue: { + _internal_set_bool_value(from._internal_bool_value()); + break; + } + case kStructValue: { + _internal_mutable_struct_value()->::PROTOBUF_NAMESPACE_ID::Struct::MergeFrom(from._internal_struct_value()); + break; + } + case kListValue: { + _internal_mutable_list_value()->::PROTOBUF_NAMESPACE_ID::ListValue::MergeFrom(from._internal_list_value()); + break; + } + case KIND_NOT_SET: { + break; + } + } + // @@protoc_insertion_point(copy_constructor:google.protobuf.Value) +} + +inline void Value::SharedCtor() { +clear_has_kind(); +} + +Value::~Value() { + // @@protoc_insertion_point(destructor:google.protobuf.Value) + if (GetArenaForAllocation() != nullptr) return; + SharedDtor(); + _internal_metadata_.Delete<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(); +} + +inline void Value::SharedDtor() { + GOOGLE_DCHECK(GetArenaForAllocation() == nullptr); + if (has_kind()) { + clear_kind(); + } +} + +void Value::ArenaDtor(void* object) { + Value* _this = reinterpret_cast< Value* >(object); + (void)_this; +} +void Value::RegisterArenaDtor(::PROTOBUF_NAMESPACE_ID::Arena*) { +} +void Value::SetCachedSize(int size) const { + _cached_size_.Set(size); +} + +void Value::clear_kind() { +// @@protoc_insertion_point(one_of_clear_start:google.protobuf.Value) + switch (kind_case()) { + case kNullValue: { + // No need to clear + break; + } + case kNumberValue: { + // No need to clear + break; + } + case kStringValue: { + kind_.string_value_.Destroy(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, GetArenaForAllocation()); + break; + } + case kBoolValue: { + // No need to clear + break; + } + case kStructValue: { + if (GetArenaForAllocation() == nullptr) { + delete kind_.struct_value_; + } + break; + } + case kListValue: { + if (GetArenaForAllocation() == nullptr) { + delete kind_.list_value_; + } + break; + } + case KIND_NOT_SET: { + break; + } + } + _oneof_case_[0] = KIND_NOT_SET; +} + + +void Value::Clear() { +// @@protoc_insertion_point(message_clear_start:google.protobuf.Value) + arc_ui32 cached_has_bits = 0; + // Prevent compiler warnings about cached_has_bits being unused + (void) cached_has_bits; + + clear_kind(); + _internal_metadata_.Clear<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(); +} + +const char* Value::_InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) { +#define CHK_(x) if (PROTOBUF_PREDICT_FALSE(!(x))) goto failure + while (!ctx->Done(&ptr)) { + arc_ui32 tag; + ptr = ::PROTOBUF_NAMESPACE_ID::internal::ReadTag(ptr, &tag); + switch (tag >> 3) { + // .google.protobuf.NullValue null_value = 1; + case 1: + if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 8)) { + arc_ui64 val = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint64(&ptr); + CHK_(ptr); + _internal_set_null_value(static_cast<::PROTOBUF_NAMESPACE_ID::NullValue>(val)); + } else + goto handle_unusual; + continue; + // double number_value = 2; + case 2: + if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 17)) { + _internal_set_number_value(::PROTOBUF_NAMESPACE_ID::internal::UnalignedLoad<double>(ptr)); + ptr += sizeof(double); + } else + goto handle_unusual; + continue; + // string string_value = 3; + case 3: + if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 26)) { + auto str = _internal_mutable_string_value(); + ptr = ::PROTOBUF_NAMESPACE_ID::internal::InlineGreedyStringParser(str, ptr, ctx); + CHK_(::PROTOBUF_NAMESPACE_ID::internal::VerifyUTF8(str, "google.protobuf.Value.string_value")); + CHK_(ptr); + } else + goto handle_unusual; + continue; + // bool bool_value = 4; + case 4: + if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 32)) { + _internal_set_bool_value(::PROTOBUF_NAMESPACE_ID::internal::ReadVarint64(&ptr)); + CHK_(ptr); + } else + goto handle_unusual; + continue; + // .google.protobuf.Struct struct_value = 5; + case 5: + if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 42)) { + ptr = ctx->ParseMessage(_internal_mutable_struct_value(), ptr); + CHK_(ptr); + } else + goto handle_unusual; + continue; + // .google.protobuf.ListValue list_value = 6; + case 6: + if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 50)) { + ptr = ctx->ParseMessage(_internal_mutable_list_value(), ptr); + CHK_(ptr); + } else + goto handle_unusual; + continue; + default: + goto handle_unusual; + } // switch + handle_unusual: + if ((tag == 0) || ((tag & 7) == 4)) { + CHK_(ptr); + ctx->SetLastTag(tag); + goto message_done; + } + ptr = UnknownFieldParse( + tag, + _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(), + ptr, ctx); + CHK_(ptr != nullptr); + } // while +message_done: + return ptr; +failure: + ptr = nullptr; + goto message_done; +#undef CHK_ +} + +uint8_t* Value::_InternalSerialize( + uint8_t* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const { + // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.Value) + arc_ui32 cached_has_bits = 0; + (void) cached_has_bits; + + // .google.protobuf.NullValue null_value = 1; + if (_internal_has_null_value()) { + target = stream->EnsureSpace(target); + target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteEnumToArray( + 1, this->_internal_null_value(), target); + } + + // double number_value = 2; + if (_internal_has_number_value()) { + target = stream->EnsureSpace(target); + target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteDoubleToArray(2, this->_internal_number_value(), target); + } + + // string string_value = 3; + if (_internal_has_string_value()) { + ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::VerifyUtf8String( + this->_internal_string_value().data(), static_cast<int>(this->_internal_string_value().length()), + ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::SERIALIZE, + "google.protobuf.Value.string_value"); + target = stream->WriteStringMaybeAliased( + 3, this->_internal_string_value(), target); + } + + // bool bool_value = 4; + if (_internal_has_bool_value()) { + target = stream->EnsureSpace(target); + target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteBoolToArray(4, this->_internal_bool_value(), target); + } + + // .google.protobuf.Struct struct_value = 5; + if (_internal_has_struct_value()) { + target = stream->EnsureSpace(target); + target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite:: + InternalWriteMessage( + 5, _Internal::struct_value(this), target, stream); + } + + // .google.protobuf.ListValue list_value = 6; + if (_internal_has_list_value()) { + target = stream->EnsureSpace(target); + target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite:: + InternalWriteMessage( + 6, _Internal::list_value(this), target, stream); + } + + if (PROTOBUF_PREDICT_FALSE(_internal_metadata_.have_unknown_fields())) { + target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::InternalSerializeUnknownFieldsToArray( + _internal_metadata_.unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(::PROTOBUF_NAMESPACE_ID::UnknownFieldSet::default_instance), target, stream); + } + // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.Value) + return target; +} + +size_t Value::ByteSizeLong() const { +// @@protoc_insertion_point(message_byte_size_start:google.protobuf.Value) + size_t total_size = 0; + + arc_ui32 cached_has_bits = 0; + // Prevent compiler warnings about cached_has_bits being unused + (void) cached_has_bits; + + switch (kind_case()) { + // .google.protobuf.NullValue null_value = 1; + case kNullValue: { + total_size += 1 + + ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::EnumSize(this->_internal_null_value()); + break; + } + // double number_value = 2; + case kNumberValue: { + total_size += 1 + 8; + break; + } + // string string_value = 3; + case kStringValue: { + total_size += 1 + + ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::StringSize( + this->_internal_string_value()); + break; + } + // bool bool_value = 4; + case kBoolValue: { + total_size += 1 + 1; + break; + } + // .google.protobuf.Struct struct_value = 5; + case kStructValue: { + total_size += 1 + + ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::MessageSize( + *kind_.struct_value_); + break; + } + // .google.protobuf.ListValue list_value = 6; + case kListValue: { + total_size += 1 + + ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::MessageSize( + *kind_.list_value_); + break; + } + case KIND_NOT_SET: { + break; + } + } + return MaybeComputeUnknownFieldsSize(total_size, &_cached_size_); +} + +const ::PROTOBUF_NAMESPACE_ID::Message::ClassData Value::_class_data_ = { + ::PROTOBUF_NAMESPACE_ID::Message::CopyWithSizeCheck, + Value::MergeImpl +}; +const ::PROTOBUF_NAMESPACE_ID::Message::ClassData*Value::GetClassData() const { return &_class_data_; } + +void Value::MergeImpl(::PROTOBUF_NAMESPACE_ID::Message* to, + const ::PROTOBUF_NAMESPACE_ID::Message& from) { + static_cast<Value *>(to)->MergeFrom( + static_cast<const Value &>(from)); +} + + +void Value::MergeFrom(const Value& from) { +// @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.Value) + GOOGLE_DCHECK_NE(&from, this); + arc_ui32 cached_has_bits = 0; + (void) cached_has_bits; + + switch (from.kind_case()) { + case kNullValue: { + _internal_set_null_value(from._internal_null_value()); + break; + } + case kNumberValue: { + _internal_set_number_value(from._internal_number_value()); + break; + } + case kStringValue: { + _internal_set_string_value(from._internal_string_value()); + break; + } + case kBoolValue: { + _internal_set_bool_value(from._internal_bool_value()); + break; + } + case kStructValue: { + _internal_mutable_struct_value()->::PROTOBUF_NAMESPACE_ID::Struct::MergeFrom(from._internal_struct_value()); + break; + } + case kListValue: { + _internal_mutable_list_value()->::PROTOBUF_NAMESPACE_ID::ListValue::MergeFrom(from._internal_list_value()); + break; + } + case KIND_NOT_SET: { + break; + } + } + _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_); +} + +void Value::CopyFrom(const Value& from) { +// @@protoc_insertion_point(class_specific_copy_from_start:google.protobuf.Value) + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool Value::IsInitialized() const { + return true; +} + +void Value::InternalSwap(Value* other) { + using std::swap; + _internal_metadata_.InternalSwap(&other->_internal_metadata_); + swap(kind_, other->kind_); + swap(_oneof_case_[0], other->_oneof_case_[0]); +} + +::PROTOBUF_NAMESPACE_ID::Metadata Value::GetMetadata() const { + return ::PROTOBUF_NAMESPACE_ID::internal::AssignDescriptors( + &descriptor_table_google_2fprotobuf_2fstruct_2eproto_getter, &descriptor_table_google_2fprotobuf_2fstruct_2eproto_once, + file_level_metadata_google_2fprotobuf_2fstruct_2eproto[2]); +} + +// =================================================================== + +class ListValue::_Internal { + public: +}; + +ListValue::ListValue(::PROTOBUF_NAMESPACE_ID::Arena* arena, + bool is_message_owned) + : ::PROTOBUF_NAMESPACE_ID::Message(arena, is_message_owned), + values_(arena) { + SharedCtor(); + if (!is_message_owned) { + RegisterArenaDtor(arena); + } + // @@protoc_insertion_point(arena_constructor:google.protobuf.ListValue) +} +ListValue::ListValue(const ListValue& from) + : ::PROTOBUF_NAMESPACE_ID::Message(), + values_(from.values_) { + _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_); + // @@protoc_insertion_point(copy_constructor:google.protobuf.ListValue) +} + +inline void ListValue::SharedCtor() { +} + +ListValue::~ListValue() { + // @@protoc_insertion_point(destructor:google.protobuf.ListValue) + if (GetArenaForAllocation() != nullptr) return; + SharedDtor(); + _internal_metadata_.Delete<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(); +} + +inline void ListValue::SharedDtor() { + GOOGLE_DCHECK(GetArenaForAllocation() == nullptr); +} + +void ListValue::ArenaDtor(void* object) { + ListValue* _this = reinterpret_cast< ListValue* >(object); + (void)_this; +} +void ListValue::RegisterArenaDtor(::PROTOBUF_NAMESPACE_ID::Arena*) { +} +void ListValue::SetCachedSize(int size) const { + _cached_size_.Set(size); +} + +void ListValue::Clear() { +// @@protoc_insertion_point(message_clear_start:google.protobuf.ListValue) + arc_ui32 cached_has_bits = 0; + // Prevent compiler warnings about cached_has_bits being unused + (void) cached_has_bits; + + values_.Clear(); + _internal_metadata_.Clear<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(); +} + +const char* ListValue::_InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) { +#define CHK_(x) if (PROTOBUF_PREDICT_FALSE(!(x))) goto failure + while (!ctx->Done(&ptr)) { + arc_ui32 tag; + ptr = ::PROTOBUF_NAMESPACE_ID::internal::ReadTag(ptr, &tag); + switch (tag >> 3) { + // repeated .google.protobuf.Value values = 1; + case 1: + if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 10)) { + ptr -= 1; + do { + ptr += 1; + ptr = ctx->ParseMessage(_internal_add_values(), ptr); + CHK_(ptr); + if (!ctx->DataAvailable(ptr)) break; + } while (::PROTOBUF_NAMESPACE_ID::internal::ExpectTag<10>(ptr)); + } else + goto handle_unusual; + continue; + default: + goto handle_unusual; + } // switch + handle_unusual: + if ((tag == 0) || ((tag & 7) == 4)) { + CHK_(ptr); + ctx->SetLastTag(tag); + goto message_done; + } + ptr = UnknownFieldParse( + tag, + _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(), + ptr, ctx); + CHK_(ptr != nullptr); + } // while +message_done: + return ptr; +failure: + ptr = nullptr; + goto message_done; +#undef CHK_ +} + +uint8_t* ListValue::_InternalSerialize( + uint8_t* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const { + // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.ListValue) + arc_ui32 cached_has_bits = 0; + (void) cached_has_bits; + + // repeated .google.protobuf.Value values = 1; + for (unsigned int i = 0, + n = static_cast<unsigned int>(this->_internal_values_size()); i < n; i++) { + target = stream->EnsureSpace(target); + target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite:: + InternalWriteMessage(1, this->_internal_values(i), target, stream); + } + + if (PROTOBUF_PREDICT_FALSE(_internal_metadata_.have_unknown_fields())) { + target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::InternalSerializeUnknownFieldsToArray( + _internal_metadata_.unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(::PROTOBUF_NAMESPACE_ID::UnknownFieldSet::default_instance), target, stream); + } + // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.ListValue) + return target; +} + +size_t ListValue::ByteSizeLong() const { +// @@protoc_insertion_point(message_byte_size_start:google.protobuf.ListValue) + size_t total_size = 0; + + arc_ui32 cached_has_bits = 0; + // Prevent compiler warnings about cached_has_bits being unused + (void) cached_has_bits; + + // repeated .google.protobuf.Value values = 1; + total_size += 1UL * this->_internal_values_size(); + for (const auto& msg : this->values_) { + total_size += + ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::MessageSize(msg); + } + + return MaybeComputeUnknownFieldsSize(total_size, &_cached_size_); +} + +const ::PROTOBUF_NAMESPACE_ID::Message::ClassData ListValue::_class_data_ = { + ::PROTOBUF_NAMESPACE_ID::Message::CopyWithSizeCheck, + ListValue::MergeImpl +}; +const ::PROTOBUF_NAMESPACE_ID::Message::ClassData*ListValue::GetClassData() const { return &_class_data_; } + +void ListValue::MergeImpl(::PROTOBUF_NAMESPACE_ID::Message* to, + const ::PROTOBUF_NAMESPACE_ID::Message& from) { + static_cast<ListValue *>(to)->MergeFrom( + static_cast<const ListValue &>(from)); +} + + +void ListValue::MergeFrom(const ListValue& from) { +// @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.ListValue) + GOOGLE_DCHECK_NE(&from, this); + arc_ui32 cached_has_bits = 0; + (void) cached_has_bits; + + values_.MergeFrom(from.values_); + _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_); +} + +void ListValue::CopyFrom(const ListValue& from) { +// @@protoc_insertion_point(class_specific_copy_from_start:google.protobuf.ListValue) + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool ListValue::IsInitialized() const { + return true; +} + +void ListValue::InternalSwap(ListValue* other) { + using std::swap; + _internal_metadata_.InternalSwap(&other->_internal_metadata_); + values_.InternalSwap(&other->values_); +} + +::PROTOBUF_NAMESPACE_ID::Metadata ListValue::GetMetadata() const { + return ::PROTOBUF_NAMESPACE_ID::internal::AssignDescriptors( + &descriptor_table_google_2fprotobuf_2fstruct_2eproto_getter, &descriptor_table_google_2fprotobuf_2fstruct_2eproto_once, + file_level_metadata_google_2fprotobuf_2fstruct_2eproto[3]); +} + +// @@protoc_insertion_point(namespace_scope) +PROTOBUF_NAMESPACE_CLOSE +PROTOBUF_NAMESPACE_OPEN +template<> PROTOBUF_NOINLINE ::PROTOBUF_NAMESPACE_ID::Struct_FieldsEntry_DoNotUse* Arena::CreateMaybeMessage< ::PROTOBUF_NAMESPACE_ID::Struct_FieldsEntry_DoNotUse >(Arena* arena) { + return Arena::CreateMessageInternal< ::PROTOBUF_NAMESPACE_ID::Struct_FieldsEntry_DoNotUse >(arena); +} +template<> PROTOBUF_NOINLINE ::PROTOBUF_NAMESPACE_ID::Struct* Arena::CreateMaybeMessage< ::PROTOBUF_NAMESPACE_ID::Struct >(Arena* arena) { + return Arena::CreateMessageInternal< ::PROTOBUF_NAMESPACE_ID::Struct >(arena); +} +template<> PROTOBUF_NOINLINE ::PROTOBUF_NAMESPACE_ID::Value* Arena::CreateMaybeMessage< ::PROTOBUF_NAMESPACE_ID::Value >(Arena* arena) { + return Arena::CreateMessageInternal< ::PROTOBUF_NAMESPACE_ID::Value >(arena); +} +template<> PROTOBUF_NOINLINE ::PROTOBUF_NAMESPACE_ID::ListValue* Arena::CreateMaybeMessage< ::PROTOBUF_NAMESPACE_ID::ListValue >(Arena* arena) { + return Arena::CreateMessageInternal< ::PROTOBUF_NAMESPACE_ID::ListValue >(arena); +} +PROTOBUF_NAMESPACE_CLOSE + +// @@protoc_insertion_point(global_scope) +#include <google/protobuf/port_undef.inc> diff --git a/contrib/libs/protobuf_old/src/google/protobuf/struct.pb.h b/contrib/libs/protobuf_old/src/google/protobuf/struct.pb.h new file mode 100644 index 0000000000..b5b4dae602 --- /dev/null +++ b/contrib/libs/protobuf_old/src/google/protobuf/struct.pb.h @@ -0,0 +1,1182 @@ +// Generated by the protocol buffer compiler. DO NOT EDIT! +// source: google/protobuf/struct.proto + +#ifndef GOOGLE_PROTOBUF_INCLUDED_google_2fprotobuf_2fstruct_2eproto +#define GOOGLE_PROTOBUF_INCLUDED_google_2fprotobuf_2fstruct_2eproto + +#include <limits> +#include <string> + +#include <google/protobuf/port_def.inc> +#if PROTOBUF_VERSION < 3019000 +#error This file was generated by a newer version of protoc which is +#error incompatible with your Protocol Buffer headers. Please update +#error your headers. +#endif +#if 3019000 < PROTOBUF_MIN_PROTOC_VERSION +#error This file was generated by an older version of protoc which is +#error incompatible with your Protocol Buffer headers. Please +#error regenerate this file with a newer version of protoc. +#endif + +#include <google/protobuf/port_undef.inc> +#include <google/protobuf/io/coded_stream.h> +#include <google/protobuf/arena.h> +#include <google/protobuf/arenastring.h> +#include <google/protobuf/generated_message_table_driven.h> +#include <google/protobuf/generated_message_util.h> +#include <google/protobuf/metadata_lite.h> +#include <google/protobuf/generated_message_reflection.h> +#include <google/protobuf/message.h> +#include <google/protobuf/repeated_field.h> // IWYU pragma: export +#include <google/protobuf/extension_set.h> // IWYU pragma: export +#include <google/protobuf/map.h> // IWYU pragma: export +#include <google/protobuf/map_entry.h> +#include <google/protobuf/map_field_inl.h> +#include <google/protobuf/generated_enum_reflection.h> +#include <google/protobuf/unknown_field_set.h> +// @@protoc_insertion_point(includes) +#include <google/protobuf/port_def.inc> +#define PROTOBUF_INTERNAL_EXPORT_google_2fprotobuf_2fstruct_2eproto PROTOBUF_EXPORT +PROTOBUF_NAMESPACE_OPEN +namespace internal { +class AnyMetadata; +} // namespace internal +PROTOBUF_NAMESPACE_CLOSE + +// Internal implementation detail -- do not use these members. +struct PROTOBUF_EXPORT TableStruct_google_2fprotobuf_2fstruct_2eproto { + static const ::PROTOBUF_NAMESPACE_ID::internal::ParseTableField entries[] + PROTOBUF_SECTION_VARIABLE(protodesc_cold); + static const ::PROTOBUF_NAMESPACE_ID::internal::AuxiliaryParseTableField aux[] + PROTOBUF_SECTION_VARIABLE(protodesc_cold); + static const ::PROTOBUF_NAMESPACE_ID::internal::ParseTable schema[4] + PROTOBUF_SECTION_VARIABLE(protodesc_cold); + static const ::PROTOBUF_NAMESPACE_ID::internal::FieldMetadata field_metadata[]; + static const ::PROTOBUF_NAMESPACE_ID::internal::SerializationTable serialization_table[]; + static const arc_ui32 offsets[]; +}; +PROTOBUF_EXPORT extern const ::PROTOBUF_NAMESPACE_ID::internal::DescriptorTable descriptor_table_google_2fprotobuf_2fstruct_2eproto; +PROTOBUF_NAMESPACE_OPEN +class ListValue; +struct ListValueDefaultTypeInternal; +PROTOBUF_EXPORT extern ListValueDefaultTypeInternal _ListValue_default_instance_; +class Struct; +struct StructDefaultTypeInternal; +PROTOBUF_EXPORT extern StructDefaultTypeInternal _Struct_default_instance_; +class Struct_FieldsEntry_DoNotUse; +struct Struct_FieldsEntry_DoNotUseDefaultTypeInternal; +PROTOBUF_EXPORT extern Struct_FieldsEntry_DoNotUseDefaultTypeInternal _Struct_FieldsEntry_DoNotUse_default_instance_; +class Value; +struct ValueDefaultTypeInternal; +PROTOBUF_EXPORT extern ValueDefaultTypeInternal _Value_default_instance_; +PROTOBUF_NAMESPACE_CLOSE +PROTOBUF_NAMESPACE_OPEN +template<> PROTOBUF_EXPORT ::PROTOBUF_NAMESPACE_ID::ListValue* Arena::CreateMaybeMessage<::PROTOBUF_NAMESPACE_ID::ListValue>(Arena*); +template<> PROTOBUF_EXPORT ::PROTOBUF_NAMESPACE_ID::Struct* Arena::CreateMaybeMessage<::PROTOBUF_NAMESPACE_ID::Struct>(Arena*); +template<> PROTOBUF_EXPORT ::PROTOBUF_NAMESPACE_ID::Struct_FieldsEntry_DoNotUse* Arena::CreateMaybeMessage<::PROTOBUF_NAMESPACE_ID::Struct_FieldsEntry_DoNotUse>(Arena*); +template<> PROTOBUF_EXPORT ::PROTOBUF_NAMESPACE_ID::Value* Arena::CreateMaybeMessage<::PROTOBUF_NAMESPACE_ID::Value>(Arena*); +PROTOBUF_NAMESPACE_CLOSE +PROTOBUF_NAMESPACE_OPEN + +enum NullValue : int { + NULL_VALUE = 0, + NullValue_INT_MIN_SENTINEL_DO_NOT_USE_ = std::numeric_limits<arc_i32>::min(), + NullValue_INT_MAX_SENTINEL_DO_NOT_USE_ = std::numeric_limits<arc_i32>::max() +}; +PROTOBUF_EXPORT bool NullValue_IsValid(int value); +constexpr NullValue NullValue_MIN = NULL_VALUE; +constexpr NullValue NullValue_MAX = NULL_VALUE; +constexpr int NullValue_ARRAYSIZE = NullValue_MAX + 1; + +PROTOBUF_EXPORT const ::PROTOBUF_NAMESPACE_ID::EnumDescriptor* NullValue_descriptor(); +template<typename T> +inline const TProtoStringType& NullValue_Name(T enum_t_value) { + static_assert(::std::is_same<T, NullValue>::value || + ::std::is_integral<T>::value, + "Incorrect type passed to function NullValue_Name."); + return ::PROTOBUF_NAMESPACE_ID::internal::NameOfEnum( + NullValue_descriptor(), enum_t_value); +} +inline bool NullValue_Parse( + ::PROTOBUF_NAMESPACE_ID::ConstStringParam name, NullValue* value) { + return ::PROTOBUF_NAMESPACE_ID::internal::ParseNamedEnum<NullValue>( + NullValue_descriptor(), name, value); +} +// =================================================================== + +class Struct_FieldsEntry_DoNotUse : public ::PROTOBUF_NAMESPACE_ID::internal::MapEntry<Struct_FieldsEntry_DoNotUse, + TProtoStringType, ::PROTOBUF_NAMESPACE_ID::Value, + ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::TYPE_STRING, + ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::TYPE_MESSAGE> { +public: + typedef ::PROTOBUF_NAMESPACE_ID::internal::MapEntry<Struct_FieldsEntry_DoNotUse, + TProtoStringType, ::PROTOBUF_NAMESPACE_ID::Value, + ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::TYPE_STRING, + ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::TYPE_MESSAGE> SuperType; + Struct_FieldsEntry_DoNotUse(); + explicit constexpr Struct_FieldsEntry_DoNotUse( + ::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized); + explicit Struct_FieldsEntry_DoNotUse(::PROTOBUF_NAMESPACE_ID::Arena* arena); + void MergeFrom(const Struct_FieldsEntry_DoNotUse& other); + static const Struct_FieldsEntry_DoNotUse* internal_default_instance() { return reinterpret_cast<const Struct_FieldsEntry_DoNotUse*>(&_Struct_FieldsEntry_DoNotUse_default_instance_); } + static bool ValidateKey(TProtoStringType* s) { + return ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::VerifyUtf8String(s->data(), static_cast<int>(s->size()), ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::PARSE, "google.protobuf.Struct.FieldsEntry.key"); + } + static bool ValidateValue(void*) { return true; } + using ::PROTOBUF_NAMESPACE_ID::Message::MergeFrom; + ::PROTOBUF_NAMESPACE_ID::Metadata GetMetadata() const final; +}; + +// ------------------------------------------------------------------- + +class PROTOBUF_EXPORT Struct final : + public ::PROTOBUF_NAMESPACE_ID::Message /* @@protoc_insertion_point(class_definition:google.protobuf.Struct) */ { + public: + inline Struct() : Struct(nullptr) {} + ~Struct() override; + explicit constexpr Struct(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized); + + Struct(const Struct& from); + Struct(Struct&& from) noexcept + : Struct() { + *this = ::std::move(from); + } + + inline Struct& operator=(const Struct& from) { + CopyFrom(from); + return *this; + } + inline Struct& operator=(Struct&& from) noexcept { + if (this == &from) return *this; + if (GetOwningArena() == from.GetOwningArena() + #ifdef PROTOBUF_FORCE_COPY_IN_MOVE + && GetOwningArena() != nullptr + #endif // !PROTOBUF_FORCE_COPY_IN_MOVE + ) { + InternalSwap(&from); + } else { + CopyFrom(from); + } + return *this; + } + + static const ::PROTOBUF_NAMESPACE_ID::Descriptor* descriptor() { + return GetDescriptor(); + } + static const ::PROTOBUF_NAMESPACE_ID::Descriptor* GetDescriptor() { + return default_instance().GetMetadata().descriptor; + } + static const ::PROTOBUF_NAMESPACE_ID::Reflection* GetReflection() { + return default_instance().GetMetadata().reflection; + } + static const Struct& default_instance() { + return *internal_default_instance(); + } + static inline const Struct* internal_default_instance() { + return reinterpret_cast<const Struct*>( + &_Struct_default_instance_); + } + static constexpr int kIndexInFileMessages = + 1; + + friend void swap(Struct& a, Struct& b) { + a.Swap(&b); + } + inline void Swap(Struct* other) { + if (other == this) return; + #ifdef PROTOBUF_FORCE_COPY_IN_SWAP + if (GetOwningArena() != nullptr && + GetOwningArena() == other->GetOwningArena()) { + #else // PROTOBUF_FORCE_COPY_IN_SWAP + if (GetOwningArena() == other->GetOwningArena()) { + #endif // !PROTOBUF_FORCE_COPY_IN_SWAP + InternalSwap(other); + } else { + ::PROTOBUF_NAMESPACE_ID::internal::GenericSwap(this, other); + } + } + void UnsafeArenaSwap(Struct* other) { + if (other == this) return; + GOOGLE_DCHECK(GetOwningArena() == other->GetOwningArena()); + InternalSwap(other); + } + + // implements Message ---------------------------------------------- + + Struct* New(::PROTOBUF_NAMESPACE_ID::Arena* arena = nullptr) const final { + return CreateMaybeMessage<Struct>(arena); + } + using ::PROTOBUF_NAMESPACE_ID::Message::CopyFrom; + void CopyFrom(const Struct& from); + using ::PROTOBUF_NAMESPACE_ID::Message::MergeFrom; + void MergeFrom(const Struct& 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; + + size_t ByteSizeLong() const final; + const char* _InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) final; + uint8_t* _InternalSerialize( + uint8_t* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const final; + int GetCachedSize() const final { return _cached_size_.Get(); } + + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const final; + void InternalSwap(Struct* other); + + private: + friend class ::PROTOBUF_NAMESPACE_ID::internal::AnyMetadata; + static ::PROTOBUF_NAMESPACE_ID::StringPiece FullMessageName() { + return "google.protobuf.Struct"; + } + protected: + explicit Struct(::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 ---------------------------------------------------- + + + // accessors ------------------------------------------------------- + + enum : int { + kFieldsFieldNumber = 1, + }; + // map<string, .google.protobuf.Value> fields = 1; + int fields_size() const; + private: + int _internal_fields_size() const; + public: + void clear_fields(); + private: + const ::PROTOBUF_NAMESPACE_ID::Map< TProtoStringType, ::PROTOBUF_NAMESPACE_ID::Value >& + _internal_fields() const; + ::PROTOBUF_NAMESPACE_ID::Map< TProtoStringType, ::PROTOBUF_NAMESPACE_ID::Value >* + _internal_mutable_fields(); + public: + const ::PROTOBUF_NAMESPACE_ID::Map< TProtoStringType, ::PROTOBUF_NAMESPACE_ID::Value >& + fields() const; + ::PROTOBUF_NAMESPACE_ID::Map< TProtoStringType, ::PROTOBUF_NAMESPACE_ID::Value >* + mutable_fields(); + + // @@protoc_insertion_point(class_scope:google.protobuf.Struct) + private: + class _Internal; + + template <typename T> friend class ::PROTOBUF_NAMESPACE_ID::Arena::InternalHelper; + typedef void InternalArenaConstructable_; + typedef void DestructorSkippable_; + ::PROTOBUF_NAMESPACE_ID::internal::MapField< + Struct_FieldsEntry_DoNotUse, + TProtoStringType, ::PROTOBUF_NAMESPACE_ID::Value, + ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::TYPE_STRING, + ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::TYPE_MESSAGE> fields_; + mutable ::PROTOBUF_NAMESPACE_ID::internal::CachedSize _cached_size_; + friend struct ::TableStruct_google_2fprotobuf_2fstruct_2eproto; +}; +// ------------------------------------------------------------------- + +class PROTOBUF_EXPORT Value final : + public ::PROTOBUF_NAMESPACE_ID::Message /* @@protoc_insertion_point(class_definition:google.protobuf.Value) */ { + public: + inline Value() : Value(nullptr) {} + ~Value() override; + explicit constexpr Value(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized); + + Value(const Value& from); + Value(Value&& from) noexcept + : Value() { + *this = ::std::move(from); + } + + inline Value& operator=(const Value& from) { + CopyFrom(from); + return *this; + } + inline Value& operator=(Value&& from) noexcept { + if (this == &from) return *this; + if (GetOwningArena() == from.GetOwningArena() + #ifdef PROTOBUF_FORCE_COPY_IN_MOVE + && GetOwningArena() != nullptr + #endif // !PROTOBUF_FORCE_COPY_IN_MOVE + ) { + InternalSwap(&from); + } else { + CopyFrom(from); + } + return *this; + } + + static const ::PROTOBUF_NAMESPACE_ID::Descriptor* descriptor() { + return GetDescriptor(); + } + static const ::PROTOBUF_NAMESPACE_ID::Descriptor* GetDescriptor() { + return default_instance().GetMetadata().descriptor; + } + static const ::PROTOBUF_NAMESPACE_ID::Reflection* GetReflection() { + return default_instance().GetMetadata().reflection; + } + static const Value& default_instance() { + return *internal_default_instance(); + } + enum KindCase { + kNullValue = 1, + kNumberValue = 2, + kStringValue = 3, + kBoolValue = 4, + kStructValue = 5, + kListValue = 6, + KIND_NOT_SET = 0, + }; + + static inline const Value* internal_default_instance() { + return reinterpret_cast<const Value*>( + &_Value_default_instance_); + } + static constexpr int kIndexInFileMessages = + 2; + + friend void swap(Value& a, Value& b) { + a.Swap(&b); + } + inline void Swap(Value* other) { + if (other == this) return; + #ifdef PROTOBUF_FORCE_COPY_IN_SWAP + if (GetOwningArena() != nullptr && + GetOwningArena() == other->GetOwningArena()) { + #else // PROTOBUF_FORCE_COPY_IN_SWAP + if (GetOwningArena() == other->GetOwningArena()) { + #endif // !PROTOBUF_FORCE_COPY_IN_SWAP + InternalSwap(other); + } else { + ::PROTOBUF_NAMESPACE_ID::internal::GenericSwap(this, other); + } + } + void UnsafeArenaSwap(Value* other) { + if (other == this) return; + GOOGLE_DCHECK(GetOwningArena() == other->GetOwningArena()); + InternalSwap(other); + } + + // implements Message ---------------------------------------------- + + Value* New(::PROTOBUF_NAMESPACE_ID::Arena* arena = nullptr) const final { + return CreateMaybeMessage<Value>(arena); + } + using ::PROTOBUF_NAMESPACE_ID::Message::CopyFrom; + void CopyFrom(const Value& from); + using ::PROTOBUF_NAMESPACE_ID::Message::MergeFrom; + void MergeFrom(const Value& 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; + + size_t ByteSizeLong() const final; + const char* _InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) final; + uint8_t* _InternalSerialize( + uint8_t* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const final; + int GetCachedSize() const final { return _cached_size_.Get(); } + + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const final; + void InternalSwap(Value* other); + + private: + friend class ::PROTOBUF_NAMESPACE_ID::internal::AnyMetadata; + static ::PROTOBUF_NAMESPACE_ID::StringPiece FullMessageName() { + return "google.protobuf.Value"; + } + protected: + explicit Value(::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 ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + enum : int { + kNullValueFieldNumber = 1, + kNumberValueFieldNumber = 2, + kStringValueFieldNumber = 3, + kBoolValueFieldNumber = 4, + kStructValueFieldNumber = 5, + kListValueFieldNumber = 6, + }; + // .google.protobuf.NullValue null_value = 1; + bool has_null_value() const; + private: + bool _internal_has_null_value() const; + public: + void clear_null_value(); + ::PROTOBUF_NAMESPACE_ID::NullValue null_value() const; + void set_null_value(::PROTOBUF_NAMESPACE_ID::NullValue value); + private: + ::PROTOBUF_NAMESPACE_ID::NullValue _internal_null_value() const; + void _internal_set_null_value(::PROTOBUF_NAMESPACE_ID::NullValue value); + public: + + // double number_value = 2; + bool has_number_value() const; + private: + bool _internal_has_number_value() const; + public: + void clear_number_value(); + double number_value() const; + void set_number_value(double value); + private: + double _internal_number_value() const; + void _internal_set_number_value(double value); + public: + + // string string_value = 3; + bool has_string_value() const; + private: + bool _internal_has_string_value() const; + public: + void clear_string_value(); + const TProtoStringType& string_value() const; + template <typename ArgT0 = const TProtoStringType&, typename... ArgT> + void set_string_value(ArgT0&& arg0, ArgT... args); + TProtoStringType* mutable_string_value(); + PROTOBUF_NODISCARD TProtoStringType* release_string_value(); + void set_allocated_string_value(TProtoStringType* string_value); + private: + const TProtoStringType& _internal_string_value() const; + inline PROTOBUF_ALWAYS_INLINE void _internal_set_string_value(const TProtoStringType& value); + TProtoStringType* _internal_mutable_string_value(); + public: + + // bool bool_value = 4; + bool has_bool_value() const; + private: + bool _internal_has_bool_value() const; + public: + void clear_bool_value(); + bool bool_value() const; + void set_bool_value(bool value); + private: + bool _internal_bool_value() const; + void _internal_set_bool_value(bool value); + public: + + // .google.protobuf.Struct struct_value = 5; + bool has_struct_value() const; + private: + bool _internal_has_struct_value() const; + public: + void clear_struct_value(); + const ::PROTOBUF_NAMESPACE_ID::Struct& struct_value() const; + PROTOBUF_NODISCARD ::PROTOBUF_NAMESPACE_ID::Struct* release_struct_value(); + ::PROTOBUF_NAMESPACE_ID::Struct* mutable_struct_value(); + void set_allocated_struct_value(::PROTOBUF_NAMESPACE_ID::Struct* struct_value); + private: + const ::PROTOBUF_NAMESPACE_ID::Struct& _internal_struct_value() const; + ::PROTOBUF_NAMESPACE_ID::Struct* _internal_mutable_struct_value(); + public: + void unsafe_arena_set_allocated_struct_value( + ::PROTOBUF_NAMESPACE_ID::Struct* struct_value); + ::PROTOBUF_NAMESPACE_ID::Struct* unsafe_arena_release_struct_value(); + + // .google.protobuf.ListValue list_value = 6; + bool has_list_value() const; + private: + bool _internal_has_list_value() const; + public: + void clear_list_value(); + const ::PROTOBUF_NAMESPACE_ID::ListValue& list_value() const; + PROTOBUF_NODISCARD ::PROTOBUF_NAMESPACE_ID::ListValue* release_list_value(); + ::PROTOBUF_NAMESPACE_ID::ListValue* mutable_list_value(); + void set_allocated_list_value(::PROTOBUF_NAMESPACE_ID::ListValue* list_value); + private: + const ::PROTOBUF_NAMESPACE_ID::ListValue& _internal_list_value() const; + ::PROTOBUF_NAMESPACE_ID::ListValue* _internal_mutable_list_value(); + public: + void unsafe_arena_set_allocated_list_value( + ::PROTOBUF_NAMESPACE_ID::ListValue* list_value); + ::PROTOBUF_NAMESPACE_ID::ListValue* unsafe_arena_release_list_value(); + + void clear_kind(); + KindCase kind_case() const; + // @@protoc_insertion_point(class_scope:google.protobuf.Value) + private: + class _Internal; + void set_has_null_value(); + void set_has_number_value(); + void set_has_string_value(); + void set_has_bool_value(); + void set_has_struct_value(); + void set_has_list_value(); + + inline bool has_kind() const; + inline void clear_has_kind(); + + template <typename T> friend class ::PROTOBUF_NAMESPACE_ID::Arena::InternalHelper; + typedef void InternalArenaConstructable_; + typedef void DestructorSkippable_; + union KindUnion { + constexpr KindUnion() : _constinit_{} {} + ::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized _constinit_; + int null_value_; + double number_value_; + ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr string_value_; + bool bool_value_; + ::PROTOBUF_NAMESPACE_ID::Struct* struct_value_; + ::PROTOBUF_NAMESPACE_ID::ListValue* list_value_; + } kind_; + mutable ::PROTOBUF_NAMESPACE_ID::internal::CachedSize _cached_size_; + arc_ui32 _oneof_case_[1]; + + friend struct ::TableStruct_google_2fprotobuf_2fstruct_2eproto; +}; +// ------------------------------------------------------------------- + +class PROTOBUF_EXPORT ListValue final : + public ::PROTOBUF_NAMESPACE_ID::Message /* @@protoc_insertion_point(class_definition:google.protobuf.ListValue) */ { + public: + inline ListValue() : ListValue(nullptr) {} + ~ListValue() override; + explicit constexpr ListValue(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized); + + ListValue(const ListValue& from); + ListValue(ListValue&& from) noexcept + : ListValue() { + *this = ::std::move(from); + } + + inline ListValue& operator=(const ListValue& from) { + CopyFrom(from); + return *this; + } + inline ListValue& operator=(ListValue&& from) noexcept { + if (this == &from) return *this; + if (GetOwningArena() == from.GetOwningArena() + #ifdef PROTOBUF_FORCE_COPY_IN_MOVE + && GetOwningArena() != nullptr + #endif // !PROTOBUF_FORCE_COPY_IN_MOVE + ) { + InternalSwap(&from); + } else { + CopyFrom(from); + } + return *this; + } + + static const ::PROTOBUF_NAMESPACE_ID::Descriptor* descriptor() { + return GetDescriptor(); + } + static const ::PROTOBUF_NAMESPACE_ID::Descriptor* GetDescriptor() { + return default_instance().GetMetadata().descriptor; + } + static const ::PROTOBUF_NAMESPACE_ID::Reflection* GetReflection() { + return default_instance().GetMetadata().reflection; + } + static const ListValue& default_instance() { + return *internal_default_instance(); + } + static inline const ListValue* internal_default_instance() { + return reinterpret_cast<const ListValue*>( + &_ListValue_default_instance_); + } + static constexpr int kIndexInFileMessages = + 3; + + friend void swap(ListValue& a, ListValue& b) { + a.Swap(&b); + } + inline void Swap(ListValue* other) { + if (other == this) return; + #ifdef PROTOBUF_FORCE_COPY_IN_SWAP + if (GetOwningArena() != nullptr && + GetOwningArena() == other->GetOwningArena()) { + #else // PROTOBUF_FORCE_COPY_IN_SWAP + if (GetOwningArena() == other->GetOwningArena()) { + #endif // !PROTOBUF_FORCE_COPY_IN_SWAP + InternalSwap(other); + } else { + ::PROTOBUF_NAMESPACE_ID::internal::GenericSwap(this, other); + } + } + void UnsafeArenaSwap(ListValue* other) { + if (other == this) return; + GOOGLE_DCHECK(GetOwningArena() == other->GetOwningArena()); + InternalSwap(other); + } + + // implements Message ---------------------------------------------- + + ListValue* New(::PROTOBUF_NAMESPACE_ID::Arena* arena = nullptr) const final { + return CreateMaybeMessage<ListValue>(arena); + } + using ::PROTOBUF_NAMESPACE_ID::Message::CopyFrom; + void CopyFrom(const ListValue& from); + using ::PROTOBUF_NAMESPACE_ID::Message::MergeFrom; + void MergeFrom(const ListValue& 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; + + size_t ByteSizeLong() const final; + const char* _InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) final; + uint8_t* _InternalSerialize( + uint8_t* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const final; + int GetCachedSize() const final { return _cached_size_.Get(); } + + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const final; + void InternalSwap(ListValue* other); + + private: + friend class ::PROTOBUF_NAMESPACE_ID::internal::AnyMetadata; + static ::PROTOBUF_NAMESPACE_ID::StringPiece FullMessageName() { + return "google.protobuf.ListValue"; + } + protected: + explicit ListValue(::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 ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + enum : int { + kValuesFieldNumber = 1, + }; + // repeated .google.protobuf.Value values = 1; + int values_size() const; + private: + int _internal_values_size() const; + public: + void clear_values(); + ::PROTOBUF_NAMESPACE_ID::Value* mutable_values(int index); + ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::Value >* + mutable_values(); + private: + const ::PROTOBUF_NAMESPACE_ID::Value& _internal_values(int index) const; + ::PROTOBUF_NAMESPACE_ID::Value* _internal_add_values(); + public: + const ::PROTOBUF_NAMESPACE_ID::Value& values(int index) const; + ::PROTOBUF_NAMESPACE_ID::Value* add_values(); + const ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::Value >& + values() const; + + // @@protoc_insertion_point(class_scope:google.protobuf.ListValue) + private: + class _Internal; + + template <typename T> friend class ::PROTOBUF_NAMESPACE_ID::Arena::InternalHelper; + typedef void InternalArenaConstructable_; + typedef void DestructorSkippable_; + ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::Value > values_; + mutable ::PROTOBUF_NAMESPACE_ID::internal::CachedSize _cached_size_; + friend struct ::TableStruct_google_2fprotobuf_2fstruct_2eproto; +}; +// =================================================================== + + +// =================================================================== + +#ifdef __GNUC__ + #pragma GCC diagnostic push + #pragma GCC diagnostic ignored "-Wstrict-aliasing" +#endif // __GNUC__ +// ------------------------------------------------------------------- + +// Struct + +// map<string, .google.protobuf.Value> fields = 1; +inline int Struct::_internal_fields_size() const { + return fields_.size(); +} +inline int Struct::fields_size() const { + return _internal_fields_size(); +} +inline void Struct::clear_fields() { + fields_.Clear(); +} +inline const ::PROTOBUF_NAMESPACE_ID::Map< TProtoStringType, ::PROTOBUF_NAMESPACE_ID::Value >& +Struct::_internal_fields() const { + return fields_.GetMap(); +} +inline const ::PROTOBUF_NAMESPACE_ID::Map< TProtoStringType, ::PROTOBUF_NAMESPACE_ID::Value >& +Struct::fields() const { + // @@protoc_insertion_point(field_map:google.protobuf.Struct.fields) + return _internal_fields(); +} +inline ::PROTOBUF_NAMESPACE_ID::Map< TProtoStringType, ::PROTOBUF_NAMESPACE_ID::Value >* +Struct::_internal_mutable_fields() { + return fields_.MutableMap(); +} +inline ::PROTOBUF_NAMESPACE_ID::Map< TProtoStringType, ::PROTOBUF_NAMESPACE_ID::Value >* +Struct::mutable_fields() { + // @@protoc_insertion_point(field_mutable_map:google.protobuf.Struct.fields) + return _internal_mutable_fields(); +} + +// ------------------------------------------------------------------- + +// Value + +// .google.protobuf.NullValue null_value = 1; +inline bool Value::_internal_has_null_value() const { + return kind_case() == kNullValue; +} +inline bool Value::has_null_value() const { + return _internal_has_null_value(); +} +inline void Value::set_has_null_value() { + _oneof_case_[0] = kNullValue; +} +inline void Value::clear_null_value() { + if (_internal_has_null_value()) { + kind_.null_value_ = 0; + clear_has_kind(); + } +} +inline ::PROTOBUF_NAMESPACE_ID::NullValue Value::_internal_null_value() const { + if (_internal_has_null_value()) { + return static_cast< ::PROTOBUF_NAMESPACE_ID::NullValue >(kind_.null_value_); + } + return static_cast< ::PROTOBUF_NAMESPACE_ID::NullValue >(0); +} +inline ::PROTOBUF_NAMESPACE_ID::NullValue Value::null_value() const { + // @@protoc_insertion_point(field_get:google.protobuf.Value.null_value) + return _internal_null_value(); +} +inline void Value::_internal_set_null_value(::PROTOBUF_NAMESPACE_ID::NullValue value) { + if (!_internal_has_null_value()) { + clear_kind(); + set_has_null_value(); + } + kind_.null_value_ = value; +} +inline void Value::set_null_value(::PROTOBUF_NAMESPACE_ID::NullValue value) { + _internal_set_null_value(value); + // @@protoc_insertion_point(field_set:google.protobuf.Value.null_value) +} + +// double number_value = 2; +inline bool Value::_internal_has_number_value() const { + return kind_case() == kNumberValue; +} +inline bool Value::has_number_value() const { + return _internal_has_number_value(); +} +inline void Value::set_has_number_value() { + _oneof_case_[0] = kNumberValue; +} +inline void Value::clear_number_value() { + if (_internal_has_number_value()) { + kind_.number_value_ = 0; + clear_has_kind(); + } +} +inline double Value::_internal_number_value() const { + if (_internal_has_number_value()) { + return kind_.number_value_; + } + return 0; +} +inline void Value::_internal_set_number_value(double value) { + if (!_internal_has_number_value()) { + clear_kind(); + set_has_number_value(); + } + kind_.number_value_ = value; +} +inline double Value::number_value() const { + // @@protoc_insertion_point(field_get:google.protobuf.Value.number_value) + return _internal_number_value(); +} +inline void Value::set_number_value(double value) { + _internal_set_number_value(value); + // @@protoc_insertion_point(field_set:google.protobuf.Value.number_value) +} + +// string string_value = 3; +inline bool Value::_internal_has_string_value() const { + return kind_case() == kStringValue; +} +inline bool Value::has_string_value() const { + return _internal_has_string_value(); +} +inline void Value::set_has_string_value() { + _oneof_case_[0] = kStringValue; +} +inline void Value::clear_string_value() { + if (_internal_has_string_value()) { + kind_.string_value_.Destroy(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, GetArenaForAllocation()); + clear_has_kind(); + } +} +inline const TProtoStringType& Value::string_value() const { + // @@protoc_insertion_point(field_get:google.protobuf.Value.string_value) + return _internal_string_value(); +} +template <typename ArgT0, typename... ArgT> +inline void Value::set_string_value(ArgT0&& arg0, ArgT... args) { + if (!_internal_has_string_value()) { + clear_kind(); + set_has_string_value(); + kind_.string_value_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); + } + kind_.string_value_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, static_cast<ArgT0 &&>(arg0), args..., GetArenaForAllocation()); + // @@protoc_insertion_point(field_set:google.protobuf.Value.string_value) +} +inline TProtoStringType* Value::mutable_string_value() { + TProtoStringType* _s = _internal_mutable_string_value(); + // @@protoc_insertion_point(field_mutable:google.protobuf.Value.string_value) + return _s; +} +inline const TProtoStringType& Value::_internal_string_value() const { + if (_internal_has_string_value()) { + return kind_.string_value_.Get(); + } + return ::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(); +} +inline void Value::_internal_set_string_value(const TProtoStringType& value) { + if (!_internal_has_string_value()) { + clear_kind(); + set_has_string_value(); + kind_.string_value_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); + } + kind_.string_value_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, value, GetArenaForAllocation()); +} +inline TProtoStringType* Value::_internal_mutable_string_value() { + if (!_internal_has_string_value()) { + clear_kind(); + set_has_string_value(); + kind_.string_value_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); + } + return kind_.string_value_.Mutable( + ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, GetArenaForAllocation()); +} +inline TProtoStringType* Value::release_string_value() { + // @@protoc_insertion_point(field_release:google.protobuf.Value.string_value) + if (_internal_has_string_value()) { + clear_has_kind(); + return kind_.string_value_.ReleaseNonDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArenaForAllocation()); + } else { + return nullptr; + } +} +inline void Value::set_allocated_string_value(TProtoStringType* string_value) { + if (has_kind()) { + clear_kind(); + } + if (string_value != nullptr) { + set_has_string_value(); + kind_.string_value_.UnsafeSetDefault(string_value); + ::PROTOBUF_NAMESPACE_ID::Arena* arena = GetArenaForAllocation(); + if (arena != nullptr) { + arena->Own(string_value); + } + } + // @@protoc_insertion_point(field_set_allocated:google.protobuf.Value.string_value) +} + +// bool bool_value = 4; +inline bool Value::_internal_has_bool_value() const { + return kind_case() == kBoolValue; +} +inline bool Value::has_bool_value() const { + return _internal_has_bool_value(); +} +inline void Value::set_has_bool_value() { + _oneof_case_[0] = kBoolValue; +} +inline void Value::clear_bool_value() { + if (_internal_has_bool_value()) { + kind_.bool_value_ = false; + clear_has_kind(); + } +} +inline bool Value::_internal_bool_value() const { + if (_internal_has_bool_value()) { + return kind_.bool_value_; + } + return false; +} +inline void Value::_internal_set_bool_value(bool value) { + if (!_internal_has_bool_value()) { + clear_kind(); + set_has_bool_value(); + } + kind_.bool_value_ = value; +} +inline bool Value::bool_value() const { + // @@protoc_insertion_point(field_get:google.protobuf.Value.bool_value) + return _internal_bool_value(); +} +inline void Value::set_bool_value(bool value) { + _internal_set_bool_value(value); + // @@protoc_insertion_point(field_set:google.protobuf.Value.bool_value) +} + +// .google.protobuf.Struct struct_value = 5; +inline bool Value::_internal_has_struct_value() const { + return kind_case() == kStructValue; +} +inline bool Value::has_struct_value() const { + return _internal_has_struct_value(); +} +inline void Value::set_has_struct_value() { + _oneof_case_[0] = kStructValue; +} +inline void Value::clear_struct_value() { + if (_internal_has_struct_value()) { + if (GetArenaForAllocation() == nullptr) { + delete kind_.struct_value_; + } + clear_has_kind(); + } +} +inline ::PROTOBUF_NAMESPACE_ID::Struct* Value::release_struct_value() { + // @@protoc_insertion_point(field_release:google.protobuf.Value.struct_value) + if (_internal_has_struct_value()) { + clear_has_kind(); + ::PROTOBUF_NAMESPACE_ID::Struct* temp = kind_.struct_value_; + if (GetArenaForAllocation() != nullptr) { + temp = ::PROTOBUF_NAMESPACE_ID::internal::DuplicateIfNonNull(temp); + } + kind_.struct_value_ = nullptr; + return temp; + } else { + return nullptr; + } +} +inline const ::PROTOBUF_NAMESPACE_ID::Struct& Value::_internal_struct_value() const { + return _internal_has_struct_value() + ? *kind_.struct_value_ + : reinterpret_cast< ::PROTOBUF_NAMESPACE_ID::Struct&>(::PROTOBUF_NAMESPACE_ID::_Struct_default_instance_); +} +inline const ::PROTOBUF_NAMESPACE_ID::Struct& Value::struct_value() const { + // @@protoc_insertion_point(field_get:google.protobuf.Value.struct_value) + return _internal_struct_value(); +} +inline ::PROTOBUF_NAMESPACE_ID::Struct* Value::unsafe_arena_release_struct_value() { + // @@protoc_insertion_point(field_unsafe_arena_release:google.protobuf.Value.struct_value) + if (_internal_has_struct_value()) { + clear_has_kind(); + ::PROTOBUF_NAMESPACE_ID::Struct* temp = kind_.struct_value_; + kind_.struct_value_ = nullptr; + return temp; + } else { + return nullptr; + } +} +inline void Value::unsafe_arena_set_allocated_struct_value(::PROTOBUF_NAMESPACE_ID::Struct* struct_value) { + clear_kind(); + if (struct_value) { + set_has_struct_value(); + kind_.struct_value_ = struct_value; + } + // @@protoc_insertion_point(field_unsafe_arena_set_allocated:google.protobuf.Value.struct_value) +} +inline ::PROTOBUF_NAMESPACE_ID::Struct* Value::_internal_mutable_struct_value() { + if (!_internal_has_struct_value()) { + clear_kind(); + set_has_struct_value(); + kind_.struct_value_ = CreateMaybeMessage< ::PROTOBUF_NAMESPACE_ID::Struct >(GetArenaForAllocation()); + } + return kind_.struct_value_; +} +inline ::PROTOBUF_NAMESPACE_ID::Struct* Value::mutable_struct_value() { + ::PROTOBUF_NAMESPACE_ID::Struct* _msg = _internal_mutable_struct_value(); + // @@protoc_insertion_point(field_mutable:google.protobuf.Value.struct_value) + return _msg; +} + +// .google.protobuf.ListValue list_value = 6; +inline bool Value::_internal_has_list_value() const { + return kind_case() == kListValue; +} +inline bool Value::has_list_value() const { + return _internal_has_list_value(); +} +inline void Value::set_has_list_value() { + _oneof_case_[0] = kListValue; +} +inline void Value::clear_list_value() { + if (_internal_has_list_value()) { + if (GetArenaForAllocation() == nullptr) { + delete kind_.list_value_; + } + clear_has_kind(); + } +} +inline ::PROTOBUF_NAMESPACE_ID::ListValue* Value::release_list_value() { + // @@protoc_insertion_point(field_release:google.protobuf.Value.list_value) + if (_internal_has_list_value()) { + clear_has_kind(); + ::PROTOBUF_NAMESPACE_ID::ListValue* temp = kind_.list_value_; + if (GetArenaForAllocation() != nullptr) { + temp = ::PROTOBUF_NAMESPACE_ID::internal::DuplicateIfNonNull(temp); + } + kind_.list_value_ = nullptr; + return temp; + } else { + return nullptr; + } +} +inline const ::PROTOBUF_NAMESPACE_ID::ListValue& Value::_internal_list_value() const { + return _internal_has_list_value() + ? *kind_.list_value_ + : reinterpret_cast< ::PROTOBUF_NAMESPACE_ID::ListValue&>(::PROTOBUF_NAMESPACE_ID::_ListValue_default_instance_); +} +inline const ::PROTOBUF_NAMESPACE_ID::ListValue& Value::list_value() const { + // @@protoc_insertion_point(field_get:google.protobuf.Value.list_value) + return _internal_list_value(); +} +inline ::PROTOBUF_NAMESPACE_ID::ListValue* Value::unsafe_arena_release_list_value() { + // @@protoc_insertion_point(field_unsafe_arena_release:google.protobuf.Value.list_value) + if (_internal_has_list_value()) { + clear_has_kind(); + ::PROTOBUF_NAMESPACE_ID::ListValue* temp = kind_.list_value_; + kind_.list_value_ = nullptr; + return temp; + } else { + return nullptr; + } +} +inline void Value::unsafe_arena_set_allocated_list_value(::PROTOBUF_NAMESPACE_ID::ListValue* list_value) { + clear_kind(); + if (list_value) { + set_has_list_value(); + kind_.list_value_ = list_value; + } + // @@protoc_insertion_point(field_unsafe_arena_set_allocated:google.protobuf.Value.list_value) +} +inline ::PROTOBUF_NAMESPACE_ID::ListValue* Value::_internal_mutable_list_value() { + if (!_internal_has_list_value()) { + clear_kind(); + set_has_list_value(); + kind_.list_value_ = CreateMaybeMessage< ::PROTOBUF_NAMESPACE_ID::ListValue >(GetArenaForAllocation()); + } + return kind_.list_value_; +} +inline ::PROTOBUF_NAMESPACE_ID::ListValue* Value::mutable_list_value() { + ::PROTOBUF_NAMESPACE_ID::ListValue* _msg = _internal_mutable_list_value(); + // @@protoc_insertion_point(field_mutable:google.protobuf.Value.list_value) + return _msg; +} + +inline bool Value::has_kind() const { + return kind_case() != KIND_NOT_SET; +} +inline void Value::clear_has_kind() { + _oneof_case_[0] = KIND_NOT_SET; +} +inline Value::KindCase Value::kind_case() const { + return Value::KindCase(_oneof_case_[0]); +} +// ------------------------------------------------------------------- + +// ListValue + +// repeated .google.protobuf.Value values = 1; +inline int ListValue::_internal_values_size() const { + return values_.size(); +} +inline int ListValue::values_size() const { + return _internal_values_size(); +} +inline void ListValue::clear_values() { + values_.Clear(); +} +inline ::PROTOBUF_NAMESPACE_ID::Value* ListValue::mutable_values(int index) { + // @@protoc_insertion_point(field_mutable:google.protobuf.ListValue.values) + return values_.Mutable(index); +} +inline ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::Value >* +ListValue::mutable_values() { + // @@protoc_insertion_point(field_mutable_list:google.protobuf.ListValue.values) + return &values_; +} +inline const ::PROTOBUF_NAMESPACE_ID::Value& ListValue::_internal_values(int index) const { + return values_.Get(index); +} +inline const ::PROTOBUF_NAMESPACE_ID::Value& ListValue::values(int index) const { + // @@protoc_insertion_point(field_get:google.protobuf.ListValue.values) + return _internal_values(index); +} +inline ::PROTOBUF_NAMESPACE_ID::Value* ListValue::_internal_add_values() { + return values_.Add(); +} +inline ::PROTOBUF_NAMESPACE_ID::Value* ListValue::add_values() { + ::PROTOBUF_NAMESPACE_ID::Value* _add = _internal_add_values(); + // @@protoc_insertion_point(field_add:google.protobuf.ListValue.values) + return _add; +} +inline const ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::Value >& +ListValue::values() const { + // @@protoc_insertion_point(field_list:google.protobuf.ListValue.values) + return values_; +} + +#ifdef __GNUC__ + #pragma GCC diagnostic pop +#endif // __GNUC__ +// ------------------------------------------------------------------- + +// ------------------------------------------------------------------- + +// ------------------------------------------------------------------- + + +// @@protoc_insertion_point(namespace_scope) + +PROTOBUF_NAMESPACE_CLOSE + +PROTOBUF_NAMESPACE_OPEN + +template <> struct is_proto_enum< ::PROTOBUF_NAMESPACE_ID::NullValue> : ::std::true_type {}; +template <> +inline const EnumDescriptor* GetEnumDescriptor< ::PROTOBUF_NAMESPACE_ID::NullValue>() { + return ::PROTOBUF_NAMESPACE_ID::NullValue_descriptor(); +} + +PROTOBUF_NAMESPACE_CLOSE + +// @@protoc_insertion_point(global_scope) + +#include <google/protobuf/port_undef.inc> +#endif // GOOGLE_PROTOBUF_INCLUDED_GOOGLE_PROTOBUF_INCLUDED_google_2fprotobuf_2fstruct_2eproto diff --git a/contrib/libs/protobuf_old/src/google/protobuf/struct.proto b/contrib/libs/protobuf_old/src/google/protobuf/struct.proto new file mode 100644 index 0000000000..0ac843ca08 --- /dev/null +++ b/contrib/libs/protobuf_old/src/google/protobuf/struct.proto @@ -0,0 +1,95 @@ +// 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 google.protobuf; + +option csharp_namespace = "Google.Protobuf.WellKnownTypes"; +option cc_enable_arenas = true; +option go_package = "google.golang.org/protobuf/types/known/structpb"; +option java_package = "com.google.protobuf"; +option java_outer_classname = "StructProto"; +option java_multiple_files = true; +option objc_class_prefix = "GPB"; + +// `Struct` represents a structured data value, consisting of fields +// which map to dynamically typed values. In some languages, `Struct` +// might be supported by a native representation. For example, in +// scripting languages like JS a struct is represented as an +// object. The details of that representation are described together +// with the proto support for the language. +// +// The JSON representation for `Struct` is JSON object. +message Struct { + // Unordered map of dynamically typed values. + map<string, Value> fields = 1; +} + +// `Value` represents a dynamically typed value which can be either +// null, a number, a string, a boolean, a recursive struct value, or a +// list of values. A producer of value is expected to set one of these +// variants. Absence of any variant indicates an error. +// +// The JSON representation for `Value` is JSON value. +message Value { + // The kind of value. + oneof kind { + // Represents a null value. + NullValue null_value = 1; + // Represents a double value. + double number_value = 2; + // Represents a string value. + string string_value = 3; + // Represents a boolean value. + bool bool_value = 4; + // Represents a structured value. + Struct struct_value = 5; + // Represents a repeated `Value`. + ListValue list_value = 6; + } +} + +// `NullValue` is a singleton enumeration to represent the null value for the +// `Value` type union. +// +// The JSON representation for `NullValue` is JSON `null`. +enum NullValue { + // Null value. + NULL_VALUE = 0; +} + +// `ListValue` is a wrapper around a repeated field of values. +// +// The JSON representation for `ListValue` is JSON array. +message ListValue { + // Repeated field of dynamically typed values. + repeated Value values = 1; +} diff --git a/contrib/libs/protobuf_old/src/google/protobuf/stubs/bytestream.cc b/contrib/libs/protobuf_old/src/google/protobuf/stubs/bytestream.cc new file mode 100644 index 0000000000..980d6f6cfc --- /dev/null +++ b/contrib/libs/protobuf_old/src/google/protobuf/stubs/bytestream.cc @@ -0,0 +1,194 @@ +// 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 <google/protobuf/stubs/bytestream.h> + +#include <string.h> +#include <algorithm> + +#include <google/protobuf/stubs/logging.h> + +namespace google { +namespace protobuf { +namespace strings { + +void ByteSource::CopyTo(ByteSink* sink, size_t n) { + while (n > 0) { + StringPiece fragment = Peek(); + if (fragment.empty()) { + GOOGLE_LOG(DFATAL) << "ByteSource::CopyTo() overran input."; + break; + } + std::size_t fragment_size = std::min<std::size_t>(n, fragment.size()); + sink->Append(fragment.data(), fragment_size); + Skip(fragment_size); + n -= fragment_size; + } +} + +void ByteSink::Flush() {} + +void UncheckedArrayByteSink::Append(const char* data, size_t n) { + if (data != dest_) { + // Catch cases where the pointer returned by GetAppendBuffer() was modified. + GOOGLE_DCHECK(!(dest_ <= data && data < (dest_ + n))) + << "Append() data[] overlaps with dest_[]"; + memcpy(dest_, data, n); + } + dest_ += n; +} + +CheckedArrayByteSink::CheckedArrayByteSink(char* outbuf, size_t capacity) + : outbuf_(outbuf), capacity_(capacity), size_(0), overflowed_(false) { +} + +void CheckedArrayByteSink::Append(const char* bytes, size_t n) { + size_t available = capacity_ - size_; + if (n > available) { + n = available; + overflowed_ = true; + } + if (n > 0 && bytes != (outbuf_ + size_)) { + // Catch cases where the pointer returned by GetAppendBuffer() was modified. + GOOGLE_DCHECK(!(outbuf_ <= bytes && bytes < (outbuf_ + capacity_))) + << "Append() bytes[] overlaps with outbuf_[]"; + memcpy(outbuf_ + size_, bytes, n); + } + size_ += n; +} + +GrowingArrayByteSink::GrowingArrayByteSink(size_t estimated_size) + : capacity_(estimated_size), + buf_(new char[estimated_size]), + size_(0) { +} + +GrowingArrayByteSink::~GrowingArrayByteSink() { + delete[] buf_; // Just in case the user didn't call GetBuffer. +} + +void GrowingArrayByteSink::Append(const char* bytes, size_t n) { + size_t available = capacity_ - size_; + if (bytes != (buf_ + size_)) { + // Catch cases where the pointer returned by GetAppendBuffer() was modified. + // We need to test for this before calling Expand() which may reallocate. + GOOGLE_DCHECK(!(buf_ <= bytes && bytes < (buf_ + capacity_))) + << "Append() bytes[] overlaps with buf_[]"; + } + if (n > available) { + Expand(n - available); + } + if (n > 0 && bytes != (buf_ + size_)) { + memcpy(buf_ + size_, bytes, n); + } + size_ += n; +} + +char* GrowingArrayByteSink::GetBuffer(size_t* nbytes) { + ShrinkToFit(); + char* b = buf_; + *nbytes = size_; + buf_ = nullptr; + size_ = capacity_ = 0; + return b; +} + +void GrowingArrayByteSink::Expand(size_t amount) { // Expand by at least 50%. + size_t new_capacity = std::max(capacity_ + amount, (3 * capacity_) / 2); + char* bigger = new char[new_capacity]; + memcpy(bigger, buf_, size_); + delete[] buf_; + buf_ = bigger; + capacity_ = new_capacity; +} + +void GrowingArrayByteSink::ShrinkToFit() { + // Shrink only if the buffer is large and size_ is less than 3/4 + // of capacity_. + if (capacity_ > 256 && size_ < (3 * capacity_) / 4) { + char* just_enough = new char[size_]; + memcpy(just_enough, buf_, size_); + delete[] buf_; + buf_ = just_enough; + capacity_ = size_; + } +} + +void StringByteSink::Append(const char* data, size_t n) { + dest_->append(data, n); +} + +size_t ArrayByteSource::Available() const { + return input_.size(); +} + +StringPiece ArrayByteSource::Peek() { + return input_; +} + +void ArrayByteSource::Skip(size_t n) { + GOOGLE_DCHECK_LE(n, input_.size()); + input_.remove_prefix(n); +} + +LimitByteSource::LimitByteSource(ByteSource *source, size_t limit) + : source_(source), + limit_(limit) { +} + +size_t LimitByteSource::Available() const { + size_t available = source_->Available(); + if (available > limit_) { + available = limit_; + } + + return available; +} + +StringPiece LimitByteSource::Peek() { + StringPiece piece = source_->Peek(); + return StringPiece(piece.data(), std::min(piece.size(), limit_)); +} + +void LimitByteSource::Skip(size_t n) { + GOOGLE_DCHECK_LE(n, limit_); + source_->Skip(n); + limit_ -= n; +} + +void LimitByteSource::CopyTo(ByteSink *sink, size_t n) { + GOOGLE_DCHECK_LE(n, limit_); + source_->CopyTo(sink, n); + limit_ -= n; +} + +} // namespace strings +} // namespace protobuf +} // namespace google diff --git a/contrib/libs/protobuf_old/src/google/protobuf/stubs/bytestream.h b/contrib/libs/protobuf_old/src/google/protobuf/stubs/bytestream.h new file mode 100644 index 0000000000..05d69ab89f --- /dev/null +++ b/contrib/libs/protobuf_old/src/google/protobuf/stubs/bytestream.h @@ -0,0 +1,351 @@ +// 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 declares the ByteSink and ByteSource abstract interfaces. These +// interfaces represent objects that consume (ByteSink) or produce (ByteSource) +// a sequence of bytes. Using these abstract interfaces in your APIs can help +// make your code work with a variety of input and output types. +// +// This file also declares the following commonly used implementations of these +// interfaces. +// +// ByteSink: +// UncheckedArrayByteSink Writes to an array, without bounds checking +// CheckedArrayByteSink Writes to an array, with bounds checking +// GrowingArrayByteSink Allocates and writes to a growable buffer +// StringByteSink Writes to an STL string +// NullByteSink Consumes a never-ending stream of bytes +// +// ByteSource: +// ArrayByteSource Reads from an array or string/StringPiece +// LimitedByteSource Limits the number of bytes read from an + +#ifndef GOOGLE_PROTOBUF_STUBS_BYTESTREAM_H_ +#define GOOGLE_PROTOBUF_STUBS_BYTESTREAM_H_ + +#include <stddef.h> +#include <string> + +#include <google/protobuf/stubs/common.h> +#include <google/protobuf/stubs/stringpiece.h> + +#include <google/protobuf/port_def.inc> + +class CordByteSink; + +namespace google { +namespace protobuf { +namespace strings { + +// An abstract interface for an object that consumes a sequence of bytes. This +// interface offers a way to append data as well as a Flush() function. +// +// Example: +// +// string my_data; +// ... +// ByteSink* sink = ... +// sink->Append(my_data.data(), my_data.size()); +// sink->Flush(); +// +class PROTOBUF_EXPORT ByteSink { + public: + ByteSink() {} + virtual ~ByteSink() {} + + // Appends the "n" bytes starting at "bytes". + virtual void Append(const char* bytes, size_t n) = 0; + + // Flushes internal buffers. The default implementation does nothing. ByteSink + // subclasses may use internal buffers that require calling Flush() at the end + // of the stream. + virtual void Flush(); + + private: + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ByteSink); +}; + +// An abstract interface for an object that produces a fixed-size sequence of +// bytes. +// +// Example: +// +// ByteSource* source = ... +// while (source->Available() > 0) { +// StringPiece data = source->Peek(); +// ... do something with "data" ... +// source->Skip(data.length()); +// } +// +class PROTOBUF_EXPORT ByteSource { + public: + ByteSource() {} + virtual ~ByteSource() {} + + // Returns the number of bytes left to read from the source. Available() + // should decrease by N each time Skip(N) is called. Available() may not + // increase. Available() returning 0 indicates that the ByteSource is + // exhausted. + // + // Note: Size() may have been a more appropriate name as it's more + // indicative of the fixed-size nature of a ByteSource. + virtual size_t Available() const = 0; + + // Returns a StringPiece of the next contiguous region of the source. Does not + // reposition the source. The returned region is empty iff Available() == 0. + // + // The returned region is valid until the next call to Skip() or until this + // object is destroyed, whichever occurs first. + // + // The length of the returned StringPiece will be <= Available(). + virtual StringPiece Peek() = 0; + + // Skips the next n bytes. Invalidates any StringPiece returned by a previous + // call to Peek(). + // + // REQUIRES: Available() >= n + virtual void Skip(size_t n) = 0; + + // Writes the next n bytes in this ByteSource to the given ByteSink, and + // advances this ByteSource past the copied bytes. The default implementation + // of this method just copies the bytes normally, but subclasses might + // override CopyTo to optimize certain cases. + // + // REQUIRES: Available() >= n + virtual void CopyTo(ByteSink* sink, size_t n); + + private: + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ByteSource); +}; + +// +// Some commonly used implementations of ByteSink +// + +// Implementation of ByteSink that writes to an unsized byte array. No +// bounds-checking is performed--it is the caller's responsibility to ensure +// that the destination array is large enough. +// +// Example: +// +// char buf[10]; +// UncheckedArrayByteSink sink(buf); +// sink.Append("hi", 2); // OK +// sink.Append(data, 100); // WOOPS! Overflows buf[10]. +// +class PROTOBUF_EXPORT UncheckedArrayByteSink : public ByteSink { + public: + explicit UncheckedArrayByteSink(char* dest) : dest_(dest) {} + virtual void Append(const char* data, size_t n) override; + + // Returns the current output pointer so that a caller can see how many bytes + // were produced. + // + // Note: this method is not part of the ByteSink interface. + char* CurrentDestination() const { return dest_; } + + private: + char* dest_; + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(UncheckedArrayByteSink); +}; + +// Implementation of ByteSink that writes to a sized byte array. This sink will +// not write more than "capacity" bytes to outbuf. Once "capacity" bytes are +// appended, subsequent bytes will be ignored and Overflowed() will return true. +// Overflowed() does not cause a runtime error (i.e., it does not CHECK fail). +// +// Example: +// +// char buf[10]; +// CheckedArrayByteSink sink(buf, 10); +// sink.Append("hi", 2); // OK +// sink.Append(data, 100); // Will only write 8 more bytes +// +class PROTOBUF_EXPORT CheckedArrayByteSink : public ByteSink { + public: + CheckedArrayByteSink(char* outbuf, size_t capacity); + virtual void Append(const char* bytes, size_t n) override; + + // Returns the number of bytes actually written to the sink. + size_t NumberOfBytesWritten() const { return size_; } + + // Returns true if any bytes were discarded, i.e., if there was an + // attempt to write more than 'capacity' bytes. + bool Overflowed() const { return overflowed_; } + + private: + char* outbuf_; + const size_t capacity_; + size_t size_; + bool overflowed_; + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(CheckedArrayByteSink); +}; + +// Implementation of ByteSink that allocates an internal buffer (a char array) +// and expands it as needed to accommodate appended data (similar to a string), +// and allows the caller to take ownership of the internal buffer via the +// GetBuffer() method. The buffer returned from GetBuffer() must be deleted by +// the caller with delete[]. GetBuffer() also sets the internal buffer to be +// empty, and subsequent appends to the sink will create a new buffer. The +// destructor will free the internal buffer if GetBuffer() was not called. +// +// Example: +// +// GrowingArrayByteSink sink(10); +// sink.Append("hi", 2); +// sink.Append(data, n); +// const char* buf = sink.GetBuffer(); // Ownership transferred +// delete[] buf; +// +class PROTOBUF_EXPORT GrowingArrayByteSink : public strings::ByteSink { + public: + explicit GrowingArrayByteSink(size_t estimated_size); + virtual ~GrowingArrayByteSink(); + virtual void Append(const char* bytes, size_t n) override; + + // Returns the allocated buffer, and sets nbytes to its size. The caller takes + // ownership of the buffer and must delete it with delete[]. + char* GetBuffer(size_t* nbytes); + + private: + void Expand(size_t amount); + void ShrinkToFit(); + + size_t capacity_; + char* buf_; + size_t size_; + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(GrowingArrayByteSink); +}; + +// Implementation of ByteSink that appends to the given string. +// Existing contents of "dest" are not modified; new data is appended. +// +// Example: +// +// string dest = "Hello "; +// StringByteSink sink(&dest); +// sink.Append("World", 5); +// assert(dest == "Hello World"); +// +class PROTOBUF_EXPORT StringByteSink : public ByteSink { + public: + explicit StringByteSink(TProtoStringType* dest) : dest_(dest) {} + virtual void Append(const char* data, size_t n) override; + + private: + TProtoStringType* dest_; + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(StringByteSink); +}; + +// Implementation of ByteSink that discards all data. +// +// Example: +// +// NullByteSink sink; +// sink.Append(data, data.size()); // All data ignored. +// +class PROTOBUF_EXPORT NullByteSink : public ByteSink { + public: + NullByteSink() {} + void Append(const char* /*data*/, size_t /*n*/) override {} + + private: + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(NullByteSink); +}; + +// +// Some commonly used implementations of ByteSource +// + +// Implementation of ByteSource that reads from a StringPiece. +// +// Example: +// +// string data = "Hello"; +// ArrayByteSource source(data); +// assert(source.Available() == 5); +// assert(source.Peek() == "Hello"); +// +class PROTOBUF_EXPORT ArrayByteSource : public ByteSource { + public: + explicit ArrayByteSource(StringPiece s) : input_(s) {} + + virtual size_t Available() const override; + virtual StringPiece Peek() override; + virtual void Skip(size_t n) override; + + private: + StringPiece input_; + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ArrayByteSource); +}; + +// Implementation of ByteSource that wraps another ByteSource, limiting the +// number of bytes returned. +// +// The caller maintains ownership of the underlying source, and may not use the +// underlying source while using the LimitByteSource object. The underlying +// source's pointer is advanced by n bytes every time this LimitByteSource +// object is advanced by n. +// +// Example: +// +// string data = "Hello World"; +// ArrayByteSource abs(data); +// assert(abs.Available() == data.size()); +// +// LimitByteSource limit(abs, 5); +// assert(limit.Available() == 5); +// assert(limit.Peek() == "Hello"); +// +class PROTOBUF_EXPORT LimitByteSource : public ByteSource { + public: + // Returns at most "limit" bytes from "source". + LimitByteSource(ByteSource* source, size_t limit); + + virtual size_t Available() const override; + virtual StringPiece Peek() override; + virtual void Skip(size_t n) override; + + // We override CopyTo so that we can forward to the underlying source, in + // case it has an efficient implementation of CopyTo. + virtual void CopyTo(ByteSink* sink, size_t n) override; + + private: + ByteSource* source_; + size_t limit_; +}; + +} // namespace strings +} // namespace protobuf +} // namespace google + +#include <google/protobuf/port_undef.inc> + +#endif // GOOGLE_PROTOBUF_STUBS_BYTESTREAM_H_ diff --git a/contrib/libs/protobuf_old/src/google/protobuf/stubs/callback.h b/contrib/libs/protobuf_old/src/google/protobuf/stubs/callback.h new file mode 100644 index 0000000000..6e0f62dcd7 --- /dev/null +++ b/contrib/libs/protobuf_old/src/google/protobuf/stubs/callback.h @@ -0,0 +1,583 @@ +#ifndef GOOGLE_PROTOBUF_STUBS_CALLBACK_H_ +#define GOOGLE_PROTOBUF_STUBS_CALLBACK_H_ + +#include <type_traits> + +#include <google/protobuf/stubs/macros.h> + +#include <google/protobuf/port_def.inc> + +// =================================================================== +// emulates google3/base/callback.h + +namespace google { +namespace protobuf { + +// Abstract interface for a callback. When calling an RPC, you must provide +// a Closure to call when the procedure completes. See the Service interface +// in service.h. +// +// To automatically construct a Closure which calls a particular function or +// method with a particular set of parameters, use the NewCallback() function. +// Example: +// void FooDone(const FooResponse* response) { +// ... +// } +// +// void CallFoo() { +// ... +// // When done, call FooDone() and pass it a pointer to the response. +// Closure* callback = NewCallback(&FooDone, response); +// // Make the call. +// service->Foo(controller, request, response, callback); +// } +// +// Example that calls a method: +// class Handler { +// public: +// ... +// +// void FooDone(const FooResponse* response) { +// ... +// } +// +// void CallFoo() { +// ... +// // When done, call FooDone() and pass it a pointer to the response. +// Closure* callback = NewCallback(this, &Handler::FooDone, response); +// // Make the call. +// service->Foo(controller, request, response, callback); +// } +// }; +// +// Currently NewCallback() supports binding zero, one, or two arguments. +// +// Callbacks created with NewCallback() automatically delete themselves when +// executed. They should be used when a callback is to be called exactly +// once (usually the case with RPC callbacks). If a callback may be called +// a different number of times (including zero), create it with +// NewPermanentCallback() instead. You are then responsible for deleting the +// callback (using the "delete" keyword as normal). +// +// Note that NewCallback() is a bit touchy regarding argument types. Generally, +// the values you provide for the parameter bindings must exactly match the +// types accepted by the callback function. For example: +// void Foo(TProtoStringType s); +// NewCallback(&Foo, "foo"); // WON'T WORK: const char* != string +// NewCallback(&Foo, TProtoStringType("foo")); // WORKS +// Also note that the arguments cannot be references: +// void Foo(const TProtoStringType& s); +// TProtoStringType my_str; +// NewCallback(&Foo, my_str); // WON'T WORK: Can't use references. +// However, correctly-typed pointers will work just fine. +class PROTOBUF_EXPORT Closure { + public: + Closure() {} + virtual ~Closure(); + + virtual void Run() = 0; + + private: + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(Closure); +}; + +template<typename R> +class ResultCallback { + public: + ResultCallback() {} + virtual ~ResultCallback() {} + + virtual R Run() = 0; + + private: + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ResultCallback); +}; + +template <typename R, typename A1> +class PROTOBUF_EXPORT ResultCallback1 { + public: + ResultCallback1() {} + virtual ~ResultCallback1() {} + + virtual R Run(A1) = 0; + + private: + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ResultCallback1); +}; + +template <typename R, typename A1, typename A2> +class PROTOBUF_EXPORT ResultCallback2 { + public: + ResultCallback2() {} + virtual ~ResultCallback2() {} + + virtual R Run(A1,A2) = 0; + + private: + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ResultCallback2); +}; + +namespace internal { + +class PROTOBUF_EXPORT FunctionClosure0 : public Closure { + public: + typedef void (*FunctionType)(); + + FunctionClosure0(FunctionType function, bool self_deleting) + : function_(function), self_deleting_(self_deleting) {} + ~FunctionClosure0(); + + void Run() override { + bool needs_delete = self_deleting_; // read in case callback deletes + function_(); + if (needs_delete) delete this; + } + + private: + FunctionType function_; + bool self_deleting_; +}; + +template <typename Class> +class MethodClosure0 : public Closure { + public: + typedef void (Class::*MethodType)(); + + MethodClosure0(Class* object, MethodType method, bool self_deleting) + : object_(object), method_(method), self_deleting_(self_deleting) {} + ~MethodClosure0() {} + + void Run() override { + bool needs_delete = self_deleting_; // read in case callback deletes + (object_->*method_)(); + if (needs_delete) delete this; + } + + private: + Class* object_; + MethodType method_; + bool self_deleting_; +}; + +template <typename Arg1> +class FunctionClosure1 : public Closure { + public: + typedef void (*FunctionType)(Arg1 arg1); + + FunctionClosure1(FunctionType function, bool self_deleting, + Arg1 arg1) + : function_(function), self_deleting_(self_deleting), + arg1_(arg1) {} + ~FunctionClosure1() {} + + void Run() override { + bool needs_delete = self_deleting_; // read in case callback deletes + function_(arg1_); + if (needs_delete) delete this; + } + + private: + FunctionType function_; + bool self_deleting_; + Arg1 arg1_; +}; + +template <typename Class, typename Arg1> +class MethodClosure1 : public Closure { + public: + typedef void (Class::*MethodType)(Arg1 arg1); + + MethodClosure1(Class* object, MethodType method, bool self_deleting, + Arg1 arg1) + : object_(object), method_(method), self_deleting_(self_deleting), + arg1_(arg1) {} + ~MethodClosure1() {} + + void Run() override { + bool needs_delete = self_deleting_; // read in case callback deletes + (object_->*method_)(arg1_); + if (needs_delete) delete this; + } + + private: + Class* object_; + MethodType method_; + bool self_deleting_; + Arg1 arg1_; +}; + +template <typename Arg1, typename Arg2> +class FunctionClosure2 : public Closure { + public: + typedef void (*FunctionType)(Arg1 arg1, Arg2 arg2); + + FunctionClosure2(FunctionType function, bool self_deleting, + Arg1 arg1, Arg2 arg2) + : function_(function), self_deleting_(self_deleting), + arg1_(arg1), arg2_(arg2) {} + ~FunctionClosure2() {} + + void Run() override { + bool needs_delete = self_deleting_; // read in case callback deletes + function_(arg1_, arg2_); + if (needs_delete) delete this; + } + + private: + FunctionType function_; + bool self_deleting_; + Arg1 arg1_; + Arg2 arg2_; +}; + +template <typename Class, typename Arg1, typename Arg2> +class MethodClosure2 : public Closure { + public: + typedef void (Class::*MethodType)(Arg1 arg1, Arg2 arg2); + + MethodClosure2(Class* object, MethodType method, bool self_deleting, + Arg1 arg1, Arg2 arg2) + : object_(object), method_(method), self_deleting_(self_deleting), + arg1_(arg1), arg2_(arg2) {} + ~MethodClosure2() {} + + void Run() override { + bool needs_delete = self_deleting_; // read in case callback deletes + (object_->*method_)(arg1_, arg2_); + if (needs_delete) delete this; + } + + private: + Class* object_; + MethodType method_; + bool self_deleting_; + Arg1 arg1_; + Arg2 arg2_; +}; + +template<typename R> +class FunctionResultCallback_0_0 : public ResultCallback<R> { + public: + typedef R (*FunctionType)(); + + FunctionResultCallback_0_0(FunctionType function, bool self_deleting) + : function_(function), self_deleting_(self_deleting) {} + ~FunctionResultCallback_0_0() {} + + R Run() override { + bool needs_delete = self_deleting_; // read in case callback deletes + R result = function_(); + if (needs_delete) delete this; + return result; + } + + private: + FunctionType function_; + bool self_deleting_; +}; + +template<typename R, typename P1> +class FunctionResultCallback_1_0 : public ResultCallback<R> { + public: + typedef R (*FunctionType)(P1); + + FunctionResultCallback_1_0(FunctionType function, bool self_deleting, + P1 p1) + : function_(function), self_deleting_(self_deleting), p1_(p1) {} + ~FunctionResultCallback_1_0() {} + + R Run() override { + bool needs_delete = self_deleting_; // read in case callback deletes + R result = function_(p1_); + if (needs_delete) delete this; + return result; + } + + private: + FunctionType function_; + bool self_deleting_; + P1 p1_; +}; + +template<typename R, typename Arg1> +class FunctionResultCallback_0_1 : public ResultCallback1<R, Arg1> { + public: + typedef R (*FunctionType)(Arg1 arg1); + + FunctionResultCallback_0_1(FunctionType function, bool self_deleting) + : function_(function), self_deleting_(self_deleting) {} + ~FunctionResultCallback_0_1() {} + + R Run(Arg1 a1) override { + bool needs_delete = self_deleting_; // read in case callback deletes + R result = function_(a1); + if (needs_delete) delete this; + return result; + } + + private: + FunctionType function_; + bool self_deleting_; +}; + +template<typename R, typename P1, typename A1> +class FunctionResultCallback_1_1 : public ResultCallback1<R, A1> { + public: + typedef R (*FunctionType)(P1, A1); + + FunctionResultCallback_1_1(FunctionType function, bool self_deleting, + P1 p1) + : function_(function), self_deleting_(self_deleting), p1_(p1) {} + ~FunctionResultCallback_1_1() {} + + R Run(A1 a1) override { + bool needs_delete = self_deleting_; // read in case callback deletes + R result = function_(p1_, a1); + if (needs_delete) delete this; + return result; + } + + private: + FunctionType function_; + bool self_deleting_; + P1 p1_; +}; + +template <typename T> +struct InternalConstRef { + typedef typename std::remove_reference<T>::type base_type; + typedef const base_type& type; +}; + +template<typename R, typename T> +class MethodResultCallback_0_0 : public ResultCallback<R> { + public: + typedef R (T::*MethodType)(); + MethodResultCallback_0_0(T* object, MethodType method, bool self_deleting) + : object_(object), + method_(method), + self_deleting_(self_deleting) {} + ~MethodResultCallback_0_0() {} + + R Run() { + bool needs_delete = self_deleting_; + R result = (object_->*method_)(); + if (needs_delete) delete this; + return result; + } + + private: + T* object_; + MethodType method_; + bool self_deleting_; +}; + +template <typename R, typename T, typename P1, typename P2, typename P3, + typename P4, typename P5, typename P6, typename A1, typename A2> +class MethodResultCallback_6_2 : public ResultCallback2<R, A1, A2> { + public: + typedef R (T::*MethodType)(P1, P2, P3, P4, P5, P6, A1, A2); + MethodResultCallback_6_2(T* object, MethodType method, bool self_deleting, + P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6) + : object_(object), + method_(method), + self_deleting_(self_deleting), + p1_(p1), + p2_(p2), + p3_(p3), + p4_(p4), + p5_(p5), + p6_(p6) {} + ~MethodResultCallback_6_2() {} + + R Run(A1 a1, A2 a2) override { + bool needs_delete = self_deleting_; + R result = (object_->*method_)(p1_, p2_, p3_, p4_, p5_, p6_, a1, a2); + if (needs_delete) delete this; + return result; + } + + private: + T* object_; + MethodType method_; + bool self_deleting_; + typename std::remove_reference<P1>::type p1_; + typename std::remove_reference<P2>::type p2_; + typename std::remove_reference<P3>::type p3_; + typename std::remove_reference<P4>::type p4_; + typename std::remove_reference<P5>::type p5_; + typename std::remove_reference<P6>::type p6_; +}; + +} // namespace internal + +// See Closure. +inline Closure* NewCallback(void (*function)()) { + return new internal::FunctionClosure0(function, true); +} + +// See Closure. +inline Closure* NewPermanentCallback(void (*function)()) { + return new internal::FunctionClosure0(function, false); +} + +// See Closure. +template <typename Class> +inline Closure* NewCallback(Class* object, void (Class::*method)()) { + return new internal::MethodClosure0<Class>(object, method, true); +} + +// See Closure. +template <typename Class> +inline Closure* NewPermanentCallback(Class* object, void (Class::*method)()) { + return new internal::MethodClosure0<Class>(object, method, false); +} + +// See Closure. +template <typename Arg1> +inline Closure* NewCallback(void (*function)(Arg1), + Arg1 arg1) { + return new internal::FunctionClosure1<Arg1>(function, true, arg1); +} + +// See Closure. +template <typename Arg1> +inline Closure* NewPermanentCallback(void (*function)(Arg1), + Arg1 arg1) { + return new internal::FunctionClosure1<Arg1>(function, false, arg1); +} + +// See Closure. +template <typename Class, typename Arg1> +inline Closure* NewCallback(Class* object, void (Class::*method)(Arg1), + Arg1 arg1) { + return new internal::MethodClosure1<Class, Arg1>(object, method, true, arg1); +} + +// See Closure. +template <typename Class, typename Arg1> +inline Closure* NewPermanentCallback(Class* object, void (Class::*method)(Arg1), + Arg1 arg1) { + return new internal::MethodClosure1<Class, Arg1>(object, method, false, arg1); +} + +// See Closure. +template <typename Arg1, typename Arg2> +inline Closure* NewCallback(void (*function)(Arg1, Arg2), + Arg1 arg1, Arg2 arg2) { + return new internal::FunctionClosure2<Arg1, Arg2>( + function, true, arg1, arg2); +} + +// See Closure. +template <typename Arg1, typename Arg2> +inline Closure* NewPermanentCallback(void (*function)(Arg1, Arg2), + Arg1 arg1, Arg2 arg2) { + return new internal::FunctionClosure2<Arg1, Arg2>( + function, false, arg1, arg2); +} + +// See Closure. +template <typename Class, typename Arg1, typename Arg2> +inline Closure* NewCallback(Class* object, void (Class::*method)(Arg1, Arg2), + Arg1 arg1, Arg2 arg2) { + return new internal::MethodClosure2<Class, Arg1, Arg2>( + object, method, true, arg1, arg2); +} + +// See Closure. +template <typename Class, typename Arg1, typename Arg2> +inline Closure* NewPermanentCallback( + Class* object, void (Class::*method)(Arg1, Arg2), + Arg1 arg1, Arg2 arg2) { + return new internal::MethodClosure2<Class, Arg1, Arg2>( + object, method, false, arg1, arg2); +} + +// See ResultCallback +template<typename R> +inline ResultCallback<R>* NewCallback(R (*function)()) { + return new internal::FunctionResultCallback_0_0<R>(function, true); +} + +// See ResultCallback +template<typename R> +inline ResultCallback<R>* NewPermanentCallback(R (*function)()) { + return new internal::FunctionResultCallback_0_0<R>(function, false); +} + +// See ResultCallback +template<typename R, typename P1> +inline ResultCallback<R>* NewCallback(R (*function)(P1), P1 p1) { + return new internal::FunctionResultCallback_1_0<R, P1>( + function, true, p1); +} + +// See ResultCallback +template<typename R, typename P1> +inline ResultCallback<R>* NewPermanentCallback( + R (*function)(P1), P1 p1) { + return new internal::FunctionResultCallback_1_0<R, P1>( + function, false, p1); +} + +// See ResultCallback1 +template<typename R, typename A1> +inline ResultCallback1<R, A1>* NewCallback(R (*function)(A1)) { + return new internal::FunctionResultCallback_0_1<R, A1>(function, true); +} + +// See ResultCallback1 +template<typename R, typename A1> +inline ResultCallback1<R, A1>* NewPermanentCallback(R (*function)(A1)) { + return new internal::FunctionResultCallback_0_1<R, A1>(function, false); +} + +// See ResultCallback1 +template<typename R, typename P1, typename A1> +inline ResultCallback1<R, A1>* NewCallback(R (*function)(P1, A1), P1 p1) { + return new internal::FunctionResultCallback_1_1<R, P1, A1>( + function, true, p1); +} + +// See ResultCallback1 +template<typename R, typename P1, typename A1> +inline ResultCallback1<R, A1>* NewPermanentCallback( + R (*function)(P1, A1), P1 p1) { + return new internal::FunctionResultCallback_1_1<R, P1, A1>( + function, false, p1); +} + +// See MethodResultCallback_0_0 +template <typename R, typename T1, typename T2> +inline ResultCallback<R>* NewPermanentCallback( + T1* object, R (T2::*function)()) { + return new internal::MethodResultCallback_0_0<R, T1>(object, function, false); +} + +// See MethodResultCallback_6_2 +template <typename R, typename T, typename P1, typename P2, typename P3, + typename P4, typename P5, typename P6, typename A1, typename A2> +inline ResultCallback2<R, A1, A2>* NewPermanentCallback( + T* object, R (T::*function)(P1, P2, P3, P4, P5, P6, A1, A2), + typename internal::InternalConstRef<P1>::type p1, + typename internal::InternalConstRef<P2>::type p2, + typename internal::InternalConstRef<P3>::type p3, + typename internal::InternalConstRef<P4>::type p4, + typename internal::InternalConstRef<P5>::type p5, + typename internal::InternalConstRef<P6>::type p6) { + return new internal::MethodResultCallback_6_2<R, T, P1, P2, P3, P4, P5, P6, + A1, A2>(object, function, false, + p1, p2, p3, p4, p5, p6); +} + +// A function which does nothing. Useful for creating no-op callbacks, e.g.: +// Closure* nothing = NewCallback(&DoNothing); +void PROTOBUF_EXPORT DoNothing(); + +} // namespace protobuf +} // namespace google + +#include <google/protobuf/port_undef.inc> + +#endif // GOOGLE_PROTOBUF_STUBS_CALLBACK_H_ diff --git a/contrib/libs/protobuf_old/src/google/protobuf/stubs/casts.h b/contrib/libs/protobuf_old/src/google/protobuf/stubs/casts.h new file mode 100644 index 0000000000..ad29dac1f8 --- /dev/null +++ b/contrib/libs/protobuf_old/src/google/protobuf/stubs/casts.h @@ -0,0 +1,138 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2014 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_CASTS_H__ +#define GOOGLE_PROTOBUF_CASTS_H__ + +#include <google/protobuf/stubs/common.h> + +#include <google/protobuf/port_def.inc> +#include <type_traits> + +namespace google { +namespace protobuf { +namespace internal { + +// Use implicit_cast as a safe version of static_cast or const_cast +// for upcasting in the type hierarchy (i.e. casting a pointer to Foo +// to a pointer to SuperclassOfFoo or casting a pointer to Foo to +// a const pointer to Foo). +// When you use implicit_cast, the compiler checks that the cast is safe. +// Such explicit implicit_casts are necessary in surprisingly many +// situations where C++ demands an exact type match instead of an +// argument type convertible to a target type. +// +// The From type can be inferred, so the preferred syntax for using +// implicit_cast is the same as for static_cast etc.: +// +// implicit_cast<ToType>(expr) +// +// implicit_cast would have been part of the C++ standard library, +// but the proposal was submitted too late. It will probably make +// its way into the language in the future. +template<typename To, typename From> +inline To implicit_cast(From const &f) { + return f; +} + +// When you upcast (that is, cast a pointer from type Foo to type +// SuperclassOfFoo), it's fine to use implicit_cast<>, since upcasts +// always succeed. When you downcast (that is, cast a pointer from +// type Foo to type SubclassOfFoo), static_cast<> isn't safe, because +// how do you know the pointer is really of type SubclassOfFoo? It +// could be a bare Foo, or of type DifferentSubclassOfFoo. Thus, +// when you downcast, you should use this macro. In debug mode, we +// use dynamic_cast<> to double-check the downcast is legal (we die +// if it's not). In normal mode, we do the efficient static_cast<> +// instead. Thus, it's important to test in debug mode to make sure +// the cast is legal! +// This is the only place in the code we should use dynamic_cast<>. +// In particular, you SHOULDN'T be using dynamic_cast<> in order to +// do RTTI (eg code like this: +// if (dynamic_cast<Subclass1>(foo)) HandleASubclass1Object(foo); +// if (dynamic_cast<Subclass2>(foo)) HandleASubclass2Object(foo); +// You should design the code some other way not to need this. + +template<typename To, typename From> // use like this: down_cast<T*>(foo); +inline To down_cast(From* f) { // so we only accept pointers + // Ensures that To is a sub-type of From *. This test is here only + // for compile-time type checking, and has no overhead in an + // optimized build at run-time, as it will be optimized away + // completely. + if (false) { + implicit_cast<From*, To>(0); + } + +#if !defined(NDEBUG) && PROTOBUF_RTTI + assert(f == nullptr || dynamic_cast<To>(f) != nullptr); // RTTI: debug mode only! +#endif + return static_cast<To>(f); +} + +template<typename To, typename From> // use like this: down_cast<T&>(foo); +inline To down_cast(From& f) { + typedef typename std::remove_reference<To>::type* ToAsPointer; + // Ensures that To is a sub-type of From *. This test is here only + // for compile-time type checking, and has no overhead in an + // optimized build at run-time, as it will be optimized away + // completely. + if (false) { + implicit_cast<From*, ToAsPointer>(0); + } + +#if !defined(NDEBUG) && PROTOBUF_RTTI + // RTTI: debug mode only! + assert(dynamic_cast<ToAsPointer>(&f) != nullptr); +#endif + return *static_cast<ToAsPointer>(&f); +} + +template<typename To, typename From> +inline To bit_cast(const From& from) { + static_assert(sizeof(From) == sizeof(To), "bit_cast_with_different_sizes"); + To dest; + memcpy(&dest, &from, sizeof(dest)); + return dest; +} + +} // namespace internal + +// We made these internal so that they would show up as such in the docs, +// but we don't want to stick "internal::" in front of them everywhere. +using internal::implicit_cast; +using internal::down_cast; +using internal::bit_cast; + +} // namespace protobuf +} // namespace google + +#include <google/protobuf/port_undef.inc> + +#endif // GOOGLE_PROTOBUF_CASTS_H__ diff --git a/contrib/libs/protobuf_old/src/google/protobuf/stubs/common.cc b/contrib/libs/protobuf_old/src/google/protobuf/stubs/common.cc new file mode 100644 index 0000000000..6f8f8d0172 --- /dev/null +++ b/contrib/libs/protobuf_old/src/google/protobuf/stubs/common.cc @@ -0,0 +1,324 @@ +// 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: kenton@google.com (Kenton Varda) + +#include <google/protobuf/stubs/common.h> + +#include <atomic> +#include <errno.h> +#include <sstream> +#include <stdio.h> +#include <vector> + +#ifdef _WIN32 +#ifndef WIN32_LEAN_AND_MEAN +#define WIN32_LEAN_AND_MEAN // We only need minimal includes +#endif +#include <windows.h> +#define snprintf _snprintf // see comment in strutil.cc +#endif +#if defined(__ANDROID__) +#include <android/log.h> +#endif + +#include <google/protobuf/stubs/callback.h> +#include <google/protobuf/stubs/logging.h> +#include <google/protobuf/stubs/once.h> +#include <google/protobuf/stubs/status.h> +#include <google/protobuf/stubs/stringpiece.h> +#include <google/protobuf/stubs/strutil.h> +#include <google/protobuf/stubs/int128.h> + +#include <google/protobuf/port_def.inc> + +namespace google { +namespace protobuf { + +namespace internal { + +void VerifyVersion(int headerVersion, + int minLibraryVersion, + const char* filename) { + if (GOOGLE_PROTOBUF_VERSION < minLibraryVersion) { + // Library is too old for headers. + GOOGLE_LOG(FATAL) + << "This program requires version " << VersionString(minLibraryVersion) + << " of the Protocol Buffer runtime library, but the installed version " + "is " << VersionString(GOOGLE_PROTOBUF_VERSION) << ". Please update " + "your library. If you compiled the program yourself, make sure that " + "your headers are from the same version of Protocol Buffers as your " + "link-time library. (Version verification failed in \"" + << filename << "\".)"; + } + if (headerVersion < kMinHeaderVersionForLibrary) { + // Headers are too old for library. + GOOGLE_LOG(FATAL) + << "This program was compiled against version " + << VersionString(headerVersion) << " of the Protocol Buffer runtime " + "library, which is not compatible with the installed version (" + << VersionString(GOOGLE_PROTOBUF_VERSION) << "). Contact the program " + "author for an update. If you compiled the program yourself, make " + "sure that your headers are from the same version of Protocol Buffers " + "as your link-time library. (Version verification failed in \"" + << filename << "\".)"; + } +} + +TProtoStringType VersionString(int version) { + int major = version / 1000000; + int minor = (version / 1000) % 1000; + int micro = version % 1000; + + // 128 bytes should always be enough, but we use snprintf() anyway to be + // safe. + char buffer[128]; + snprintf(buffer, sizeof(buffer), "%d.%d.%d", major, minor, micro); + + // Guard against broken MSVC snprintf(). + buffer[sizeof(buffer)-1] = '\0'; + + return buffer; +} + +} // namespace internal + +// =================================================================== +// emulates google3/base/logging.cc + +// If the minimum logging level is not set, we default to logging messages for +// all levels. +#ifndef GOOGLE_PROTOBUF_MIN_LOG_LEVEL +#define GOOGLE_PROTOBUF_MIN_LOG_LEVEL LOGLEVEL_INFO +#endif + +namespace internal { + +#if defined(__ANDROID__) +inline void DefaultLogHandler(LogLevel level, const char* filename, int line, + const TProtoStringType& message) { + if (level < GOOGLE_PROTOBUF_MIN_LOG_LEVEL) { + return; + } + static const char* level_names[] = {"INFO", "WARNING", "ERROR", "FATAL"}; + + static const int android_log_levels[] = { + ANDROID_LOG_INFO, // LOG(INFO), + ANDROID_LOG_WARN, // LOG(WARNING) + ANDROID_LOG_ERROR, // LOG(ERROR) + ANDROID_LOG_FATAL, // LOG(FATAL) + }; + + // Bound the logging level. + const int android_log_level = android_log_levels[level]; + ::std::ostringstream ostr; + ostr << "[libprotobuf " << level_names[level] << " " << filename << ":" + << line << "] " << message.c_str(); + + // Output the log string the Android log at the appropriate level. + __android_log_write(android_log_level, "libprotobuf-native", + ostr.str().c_str()); + // Also output to std::cerr. + fprintf(stderr, "%s", ostr.str().c_str()); + fflush(stderr); + + // Indicate termination if needed. + if (android_log_level == ANDROID_LOG_FATAL) { + __android_log_write(ANDROID_LOG_FATAL, "libprotobuf-native", + "terminating.\n"); + } +} + +#else +void DefaultLogHandler(LogLevel level, const char* filename, int line, + const TProtoStringType& message) { + if (level < GOOGLE_PROTOBUF_MIN_LOG_LEVEL) { + return; + } + static const char* level_names[] = { "INFO", "WARNING", "ERROR", "FATAL" }; + + // We use fprintf() instead of cerr because we want this to work at static + // initialization time. + fprintf(stderr, "[libprotobuf %s %s:%d] %s\n", + level_names[level], filename, line, message.c_str()); + fflush(stderr); // Needed on MSVC. +} +#endif + +void NullLogHandler(LogLevel /* level */, const char* /* filename */, + int /* line */, const TProtoStringType& /* message */) { + // Nothing. +} + +static LogHandler* log_handler_ = &DefaultLogHandler; +static std::atomic<int> log_silencer_count_ = ATOMIC_VAR_INIT(0); + +LogMessage& LogMessage::operator<<(const TProtoStringType& value) { + message_ += value; + return *this; +} + +LogMessage& LogMessage::operator<<(const char* value) { + message_ += value; + return *this; +} + +LogMessage& LogMessage::operator<<(const StringPiece& value) { + message_ += value.ToString(); + return *this; +} + +LogMessage& LogMessage::operator<<(const util::Status& status) { + message_ += status.ToString(); + return *this; +} + +LogMessage& LogMessage::operator<<(const uint128& value) { + std::ostringstream str; + str << value; + message_ += str.str(); + return *this; +} + +LogMessage& LogMessage::operator<<(char value) { + return *this << StringPiece(&value, 1); +} + +LogMessage& LogMessage::operator<<(void* value) { + StrAppend(&message_, strings::Hex(reinterpret_cast<uintptr_t>(value))); + return *this; +} + +#undef DECLARE_STREAM_OPERATOR +#define DECLARE_STREAM_OPERATOR(TYPE) \ + LogMessage& LogMessage::operator<<(TYPE value) { \ + StrAppend(&message_, value); \ + return *this; \ + } + +DECLARE_STREAM_OPERATOR(int) +DECLARE_STREAM_OPERATOR(unsigned int) +DECLARE_STREAM_OPERATOR(long) // NOLINT(runtime/int) +DECLARE_STREAM_OPERATOR(unsigned long) // NOLINT(runtime/int) +DECLARE_STREAM_OPERATOR(double) +DECLARE_STREAM_OPERATOR(long long) // NOLINT(runtime/int) +DECLARE_STREAM_OPERATOR(unsigned long long) // NOLINT(runtime/int) +#undef DECLARE_STREAM_OPERATOR + +LogMessage::LogMessage(LogLevel level, const char* filename, int line) + : level_(level), filename_(filename), line_(line) {} +LogMessage::~LogMessage() {} + +void LogMessage::Finish() { + bool suppress = false; + + if (level_ != LOGLEVEL_FATAL) { + suppress = log_silencer_count_ > 0; + } + + if (!suppress) { + log_handler_(level_, filename_, line_, message_); + } + + if (level_ == LOGLEVEL_FATAL) { +#if PROTOBUF_USE_EXCEPTIONS + throw FatalException(filename_, line_, message_); +#else + abort(); +#endif + } +} + +void LogFinisher::operator=(LogMessage& other) { + other.Finish(); +} + +} // namespace internal + +LogHandler* SetLogHandler(LogHandler* new_func) { + LogHandler* old = internal::log_handler_; + if (old == &internal::NullLogHandler) { + old = nullptr; + } + if (new_func == nullptr) { + internal::log_handler_ = &internal::NullLogHandler; + } else { + internal::log_handler_ = new_func; + } + return old; +} + +LogSilencer::LogSilencer() { + ++internal::log_silencer_count_; +}; + +LogSilencer::~LogSilencer() { + --internal::log_silencer_count_; +}; + +// =================================================================== +// emulates google3/base/callback.cc + +Closure::~Closure() {} + +namespace internal { FunctionClosure0::~FunctionClosure0() {} } + +void DoNothing() {} + +// =================================================================== +// emulates google3/util/endian/endian.h +// +// TODO(xiaofeng): PROTOBUF_LITTLE_ENDIAN is unfortunately defined in +// google/protobuf/io/coded_stream.h and therefore can not be used here. +// Maybe move that macro definition here in the future. +uint32 ghtonl(uint32 x) { + union { + uint32 result; + uint8 result_array[4]; + }; + result_array[0] = static_cast<uint8>(x >> 24); + result_array[1] = static_cast<uint8>((x >> 16) & 0xFF); + result_array[2] = static_cast<uint8>((x >> 8) & 0xFF); + result_array[3] = static_cast<uint8>(x & 0xFF); + return result; +} + +#if PROTOBUF_USE_EXCEPTIONS +FatalException::~FatalException() throw() {} + +const char* FatalException::what() const throw() { + return message_.c_str(); +} +#endif + +} // namespace protobuf +} // namespace google + +#include <google/protobuf/port_undef.inc> diff --git a/contrib/libs/protobuf_old/src/google/protobuf/stubs/common.h b/contrib/libs/protobuf_old/src/google/protobuf/stubs/common.h new file mode 100644 index 0000000000..4a7036df17 --- /dev/null +++ b/contrib/libs/protobuf_old/src/google/protobuf/stubs/common.h @@ -0,0 +1,208 @@ +// 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: kenton@google.com (Kenton Varda) and others +// +// Contains basic types and utilities used by the rest of the library. + +#ifndef GOOGLE_PROTOBUF_COMMON_H__ +#define GOOGLE_PROTOBUF_COMMON_H__ + +#include <algorithm> +#include <iostream> +#include <map> +#include <memory> +#include <set> +#include <string> +#include <vector> + +#include <google/protobuf/stubs/macros.h> +#include <google/protobuf/stubs/platform_macros.h> +#include <google/protobuf/stubs/port.h> +#include <google/protobuf/stubs/stringpiece.h> + +#ifndef PROTOBUF_USE_EXCEPTIONS +#if defined(_MSC_VER) && defined(_CPPUNWIND) + #define PROTOBUF_USE_EXCEPTIONS 1 +#elif defined(__EXCEPTIONS) + #define PROTOBUF_USE_EXCEPTIONS 1 +#else + #define PROTOBUF_USE_EXCEPTIONS 0 +#endif +#endif + +#define Y_PROTOBUF_SUPPRESS_NODISCARD [[maybe_unused]] bool Y_GENERATE_UNIQUE_ID(pb_checker)= + +#if PROTOBUF_USE_EXCEPTIONS +#include <exception> +#endif +#if defined(__APPLE__) +#include <TargetConditionals.h> // for TARGET_OS_IPHONE +#endif + +#if defined(__ANDROID__) || defined(GOOGLE_PROTOBUF_OS_ANDROID) || (defined(TARGET_OS_IPHONE) && TARGET_OS_IPHONE) || defined(GOOGLE_PROTOBUF_OS_IPHONE) +#include <pthread.h> +#endif + +#include <google/protobuf/port_def.inc> + +namespace std {} + +namespace google { +namespace protobuf { +namespace internal { + +// Some of these constants are macros rather than const ints so that they can +// be used in #if directives. + +// The current version, represented as a single integer to make comparison +// easier: major * 10^6 + minor * 10^3 + micro +#define GOOGLE_PROTOBUF_VERSION 3019000 + +// A suffix string for alpha, beta or rc releases. Empty for stable releases. +#define GOOGLE_PROTOBUF_VERSION_SUFFIX "" + +// The minimum header version which works with the current version of +// the library. This constant should only be used by protoc's C++ code +// generator. +static const int kMinHeaderVersionForLibrary = 3019000; + +// The minimum protoc version which works with the current version of the +// headers. +#define GOOGLE_PROTOBUF_MIN_PROTOC_VERSION 3019000 + +// The minimum header version which works with the current version of +// protoc. This constant should only be used in VerifyVersion(). +static const int kMinHeaderVersionForProtoc = 3019000; + +// Verifies that the headers and libraries are compatible. Use the macro +// below to call this. +void PROTOBUF_EXPORT VerifyVersion(int headerVersion, int minLibraryVersion, + const char* filename); + +// Converts a numeric version number to a string. +TProtoStringType PROTOBUF_EXPORT VersionString(int version); + +} // namespace internal + +// Place this macro in your main() function (or somewhere before you attempt +// to use the protobuf library) to verify that the version you link against +// matches the headers you compiled against. If a version mismatch is +// detected, the process will abort. +#define GOOGLE_PROTOBUF_VERIFY_VERSION \ + ::google::protobuf::internal::VerifyVersion( \ + GOOGLE_PROTOBUF_VERSION, GOOGLE_PROTOBUF_MIN_LIBRARY_VERSION, \ + __FILE__) + + +// =================================================================== +// from google3/util/utf8/public/unilib.h + +namespace internal { + +// Checks if the buffer contains structurally-valid UTF-8. Implemented in +// structurally_valid.cc. +PROTOBUF_EXPORT bool IsStructurallyValidUTF8(const char* buf, int len); + +inline bool IsStructurallyValidUTF8(StringPiece str) { + return IsStructurallyValidUTF8(str.data(), static_cast<int>(str.length())); +} + +// Returns initial number of bytes of structurally valid UTF-8. +PROTOBUF_EXPORT int UTF8SpnStructurallyValid(StringPiece str); + +// Coerce UTF-8 byte string in src_str to be +// a structurally-valid equal-length string by selectively +// overwriting illegal bytes with replace_char (typically ' ' or '?'). +// replace_char must be legal printable 7-bit Ascii 0x20..0x7e. +// src_str is read-only. +// +// Returns pointer to output buffer, src_str.data() if no changes were made, +// or idst if some bytes were changed. idst is allocated by the caller +// and must be at least as big as src_str +// +// Optimized for: all structurally valid and no byte copying is done. +// +PROTOBUF_EXPORT char* UTF8CoerceToStructurallyValid(StringPiece str, char* dst, + char replace_char); + +} // namespace internal + +// This lives in message_lite.h now, but we leave this here for any users that +// #include common.h and not message_lite.h. +PROTOBUF_EXPORT void ShutdownProtobufLibrary(); + +namespace internal { + +// Strongly references the given variable such that the linker will be forced +// to pull in this variable's translation unit. +template <typename T> +void StrongReference(const T& var) { + auto volatile unused = &var; + (void)&unused; // Use address to avoid an extra load of "unused". +} + +} // namespace internal + +#if PROTOBUF_USE_EXCEPTIONS +class FatalException : public std::exception { + public: + FatalException(const char* filename, int line, const TProtoStringType& message) + : filename_(filename), line_(line), message_(message) {} + virtual ~FatalException() throw(); + + const char* what() const throw() override; + + const char* filename() const { return filename_; } + int line() const { return line_; } + const TProtoStringType& message() const { return message_; } + + private: + const char* filename_; + const int line_; + const TProtoStringType message_; +}; +#endif + +// This is at the end of the file instead of the beginning to work around a bug +// in some versions of MSVC. +using string = TProtoStringType; + +} // namespace protobuf +} // namespace google + +namespace NProtoBuf { + using namespace google; + using namespace google::protobuf; +} + +#include <google/protobuf/port_undef.inc> + +#endif // GOOGLE_PROTOBUF_COMMON_H__ diff --git a/contrib/libs/protobuf_old/src/google/protobuf/stubs/hash.h b/contrib/libs/protobuf_old/src/google/protobuf/stubs/hash.h new file mode 100644 index 0000000000..9883c0d5b3 --- /dev/null +++ b/contrib/libs/protobuf_old/src/google/protobuf/stubs/hash.h @@ -0,0 +1,116 @@ +// 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: kenton@google.com (Kenton Varda) + +#ifndef GOOGLE_PROTOBUF_STUBS_HASH_H__ +#define GOOGLE_PROTOBUF_STUBS_HASH_H__ + +#include <cstring> +#include <string> +#include <unordered_map> +#include <unordered_set> + +#include <google/protobuf/stubs/port.h> + +# define GOOGLE_PROTOBUF_HASH_NAMESPACE_DECLARATION_START \ + namespace google { \ + namespace protobuf { +# define GOOGLE_PROTOBUF_HASH_NAMESPACE_DECLARATION_END }} + +namespace google { +namespace protobuf { + +template <typename Key> +struct hash : public std::hash<Key> {}; + +template <typename Key> +struct hash<const Key*> { + inline size_t operator()(const Key* key) const { + return reinterpret_cast<size_t>(key); + } +}; + +// Unlike the old SGI version, the TR1 "hash" does not special-case char*. So, +// we go ahead and provide our own implementation. +template <> +struct hash<const char*> { + inline size_t operator()(const char* str) const { + size_t result = 0; + for (; *str != '\0'; str++) { + result = 5 * result + static_cast<size_t>(*str); + } + return result; + } +}; + +template<> +struct hash<bool> { + size_t operator()(bool x) const { + return static_cast<size_t>(x); + } +}; + +template <> +struct hash<TProtoStringType> { + inline size_t operator()(const TProtoStringType& key) const { + return hash<const char*>()(key.c_str()); + } + + static const size_t bucket_size = 4; + static const size_t min_buckets = 8; + inline bool operator()(const TProtoStringType& a, const TProtoStringType& b) const { + return a < b; + } +}; + +template <typename First, typename Second> +struct hash<std::pair<First, Second> > { + inline size_t operator()(const std::pair<First, Second>& key) const { + size_t first_hash = hash<First>()(key.first); + size_t second_hash = hash<Second>()(key.second); + + // FIXME(kenton): What is the best way to compute this hash? I have + // no idea! This seems a bit better than an XOR. + return first_hash * ((1 << 16) - 1) + second_hash; + } + + static const size_t bucket_size = 4; + static const size_t min_buckets = 8; + inline bool operator()(const std::pair<First, Second>& a, + const std::pair<First, Second>& b) const { + return a < b; + } +}; + +} // namespace protobuf +} // namespace google + +#endif // GOOGLE_PROTOBUF_STUBS_HASH_H__ diff --git a/contrib/libs/protobuf_old/src/google/protobuf/stubs/int128.cc b/contrib/libs/protobuf_old/src/google/protobuf/stubs/int128.cc new file mode 100644 index 0000000000..ca1f3863ac --- /dev/null +++ b/contrib/libs/protobuf_old/src/google/protobuf/stubs/int128.cc @@ -0,0 +1,192 @@ +// 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 <google/protobuf/stubs/int128.h> + +#include <iomanip> +#include <ostream> // NOLINT(readability/streams) +#include <sstream> + +#include <google/protobuf/stubs/logging.h> + +#include <google/protobuf/port_def.inc> + +namespace google { +namespace protobuf { + +const uint128_pod kuint128max = {arc_ui64{0xFFFFFFFFFFFFFFFFu}, + arc_ui64{0xFFFFFFFFFFFFFFFFu}}; + +// Returns the 0-based position of the last set bit (i.e., most significant bit) +// in the given uint64. The argument may not be 0. +// +// For example: +// Given: 5 (decimal) == 101 (binary) +// Returns: 2 +#define STEP(T, n, pos, sh) \ + do { \ + if ((n) >= (static_cast<T>(1) << (sh))) { \ + (n) = (n) >> (sh); \ + (pos) |= (sh); \ + } \ + } while (0) +static inline int Fls64(uint64 n) { + GOOGLE_DCHECK_NE(0, n); + int pos = 0; + STEP(uint64, n, pos, 0x20); + uint32 n32 = n; + STEP(uint32, n32, pos, 0x10); + STEP(uint32, n32, pos, 0x08); + STEP(uint32, n32, pos, 0x04); + return pos + ((arc_ui64{0x3333333322221100u} >> (n32 << 2)) & 0x3); +} +#undef STEP + +// Like Fls64() above, but returns the 0-based position of the last set bit +// (i.e., most significant bit) in the given uint128. The argument may not be 0. +static inline int Fls128(uint128 n) { + if (uint64 hi = Uint128High64(n)) { + return Fls64(hi) + 64; + } + return Fls64(Uint128Low64(n)); +} + +void uint128::DivModImpl(uint128 dividend, uint128 divisor, + uint128* quotient_ret, uint128* remainder_ret) { + if (divisor == 0) { + GOOGLE_LOG(FATAL) << "Division or mod by zero: dividend.hi=" << dividend.hi_ + << ", lo=" << dividend.lo_; + } else if (dividend < divisor) { + *quotient_ret = 0; + *remainder_ret = dividend; + return; + } else { + int dividend_bit_length = Fls128(dividend); + int divisor_bit_length = Fls128(divisor); + int difference = dividend_bit_length - divisor_bit_length; + uint128 quotient = 0; + while (difference >= 0) { + quotient <<= 1; + uint128 shifted_divisor = divisor << difference; + if (shifted_divisor <= dividend) { + dividend -= shifted_divisor; + quotient += 1; + } + difference -= 1; + } + //record the final quotient and remainder + *quotient_ret = quotient; + *remainder_ret = dividend; + } +} + + +uint128& uint128::operator/=(const uint128& divisor) { + uint128 quotient = 0; + uint128 remainder = 0; + DivModImpl(*this, divisor, "ient, &remainder); + *this = quotient; + return *this; +} +uint128& uint128::operator%=(const uint128& divisor) { + uint128 quotient = 0; + uint128 remainder = 0; + DivModImpl(*this, divisor, "ient, &remainder); + *this = remainder; + return *this; +} + +std::ostream& operator<<(std::ostream& o, const uint128& b) { + std::ios_base::fmtflags flags = o.flags(); + + // Select a divisor which is the largest power of the base < 2^64. + uint128 div; + std::streamsize div_base_log; + switch (flags & std::ios::basefield) { + case std::ios::hex: + div = + static_cast<uint64>(arc_ui64{0x1000000000000000u}); // 16^15 + div_base_log = 15; + break; + case std::ios::oct: + div = static_cast<uint64>( + arc_ui64{01000000000000000000000u}); // 8^21 + div_base_log = 21; + break; + default: // std::ios::dec + div = static_cast<uint64>( + arc_ui64{10000000000000000000u}); // 10^19 + div_base_log = 19; + break; + } + + // Now piece together the uint128 representation from three chunks of + // the original value, each less than "div" and therefore representable + // as a uint64. + std::ostringstream os; + std::ios_base::fmtflags copy_mask = + std::ios::basefield | std::ios::showbase | std::ios::uppercase; + os.setf(flags & copy_mask, copy_mask); + uint128 high = b; + uint128 low; + uint128::DivModImpl(high, div, &high, &low); + uint128 mid; + uint128::DivModImpl(high, div, &high, &mid); + if (high.lo_ != 0) { + os << high.lo_; + os << std::noshowbase << std::setfill('0') << std::setw(div_base_log); + os << mid.lo_; + os << std::setw(div_base_log); + } else if (mid.lo_ != 0) { + os << mid.lo_; + os << std::noshowbase << std::setfill('0') << std::setw(div_base_log); + } + os << low.lo_; + std::string rep = os.str(); + + // Add the requisite padding. + std::streamsize width = o.width(0); + if (width > rep.size()) { + if ((flags & std::ios::adjustfield) == std::ios::left) { + rep.append(width - rep.size(), o.fill()); + } else { + rep.insert(static_cast<TProtoStringType::size_type>(0), + width - rep.size(), o.fill()); + } + } + + // Stream the final representation in a single "<<" call. + return o << rep; +} + +} // namespace protobuf +} // namespace google + +#include <google/protobuf/port_undef.inc> // NOLINT diff --git a/contrib/libs/protobuf_old/src/google/protobuf/stubs/int128.h b/contrib/libs/protobuf_old/src/google/protobuf/stubs/int128.h new file mode 100644 index 0000000000..dc70d96eb3 --- /dev/null +++ b/contrib/libs/protobuf_old/src/google/protobuf/stubs/int128.h @@ -0,0 +1,387 @@ +// 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_STUBS_INT128_H_ +#define GOOGLE_PROTOBUF_STUBS_INT128_H_ + +#include <google/protobuf/stubs/common.h> + +#include <iosfwd> + +#include <google/protobuf/port_def.inc> + +namespace google { +namespace protobuf { + +struct uint128_pod; + +// TODO(xiaofeng): Define GOOGLE_PROTOBUF_HAS_CONSTEXPR when constexpr is +// available. +#ifdef GOOGLE_PROTOBUF_HAS_CONSTEXPR +# define UINT128_CONSTEXPR constexpr +#else +# define UINT128_CONSTEXPR +#endif + +// An unsigned 128-bit integer type. Thread-compatible. +class PROTOBUF_EXPORT uint128 { + public: + UINT128_CONSTEXPR uint128(); // Sets to 0, but don't trust on this behavior. + UINT128_CONSTEXPR uint128(uint64 top, uint64 bottom); +#ifndef SWIG + UINT128_CONSTEXPR uint128(int bottom); + UINT128_CONSTEXPR uint128(uint32 bottom); // Top 96 bits = 0 +#endif + UINT128_CONSTEXPR uint128(uint64 bottom); // hi_ = 0 + UINT128_CONSTEXPR uint128(const uint128_pod &val); + + // Trivial copy constructor, assignment operator and destructor. + + void Initialize(uint64 top, uint64 bottom); + + // Arithmetic operators. + uint128& operator+=(const uint128& b); + uint128& operator-=(const uint128& b); + uint128& operator*=(const uint128& b); + // Long division/modulo for uint128. + uint128& operator/=(const uint128& b); + uint128& operator%=(const uint128& b); + uint128 operator++(int); + uint128 operator--(int); + uint128& operator<<=(int); + uint128& operator>>=(int); + uint128& operator&=(const uint128& b); + uint128& operator|=(const uint128& b); + uint128& operator^=(const uint128& b); + uint128& operator++(); + uint128& operator--(); + + friend uint64 Uint128Low64(const uint128& v); + friend uint64 Uint128High64(const uint128& v); + + // We add "std::" to avoid including all of port.h. + PROTOBUF_EXPORT friend std::ostream& operator<<(std::ostream& o, + const uint128& b); + + private: + static void DivModImpl(uint128 dividend, uint128 divisor, + uint128* quotient_ret, uint128* remainder_ret); + + // Little-endian memory order optimizations can benefit from + // having lo_ first, hi_ last. + // See util/endian/endian.h and Load128/Store128 for storing a uint128. + uint64 lo_; + uint64 hi_; + + // Not implemented, just declared for catching automatic type conversions. + uint128(uint8); + uint128(uint16); + uint128(float v); + uint128(double v); +}; + +// This is a POD form of uint128 which can be used for static variables which +// need to be operated on as uint128. +struct uint128_pod { + // Note: The ordering of fields is different than 'class uint128' but the + // same as its 2-arg constructor. This enables more obvious initialization + // of static instances, which is the primary reason for this struct in the + // first place. This does not seem to defeat any optimizations wrt + // operations involving this struct. + uint64 hi; + uint64 lo; +}; + +PROTOBUF_EXPORT extern const uint128_pod kuint128max; + +// allow uint128 to be logged +PROTOBUF_EXPORT extern std::ostream& operator<<(std::ostream& o, + const uint128& b); + +// Methods to access low and high pieces of 128-bit value. +// Defined externally from uint128 to facilitate conversion +// to native 128-bit types when compilers support them. +inline uint64 Uint128Low64(const uint128& v) { return v.lo_; } +inline uint64 Uint128High64(const uint128& v) { return v.hi_; } + +// TODO: perhaps it would be nice to have int128, a signed 128-bit type? + +// -------------------------------------------------------------------------- +// Implementation details follow +// -------------------------------------------------------------------------- +inline bool operator==(const uint128& lhs, const uint128& rhs) { + return (Uint128Low64(lhs) == Uint128Low64(rhs) && + Uint128High64(lhs) == Uint128High64(rhs)); +} +inline bool operator!=(const uint128& lhs, const uint128& rhs) { + return !(lhs == rhs); +} + +inline UINT128_CONSTEXPR uint128::uint128() : lo_(0), hi_(0) {} +inline UINT128_CONSTEXPR uint128::uint128(uint64 top, uint64 bottom) + : lo_(bottom), hi_(top) {} +inline UINT128_CONSTEXPR uint128::uint128(const uint128_pod& v) + : lo_(v.lo), hi_(v.hi) {} +inline UINT128_CONSTEXPR uint128::uint128(uint64 bottom) + : lo_(bottom), hi_(0) {} +#ifndef SWIG +inline UINT128_CONSTEXPR uint128::uint128(uint32 bottom) + : lo_(bottom), hi_(0) {} +inline UINT128_CONSTEXPR uint128::uint128(int bottom) + : lo_(bottom), hi_(static_cast<int64>((bottom < 0) ? -1 : 0)) {} +#endif + +#undef UINT128_CONSTEXPR + +inline void uint128::Initialize(uint64 top, uint64 bottom) { + hi_ = top; + lo_ = bottom; +} + +// Comparison operators. + +#define CMP128(op) \ +inline bool operator op(const uint128& lhs, const uint128& rhs) { \ + return (Uint128High64(lhs) == Uint128High64(rhs)) ? \ + (Uint128Low64(lhs) op Uint128Low64(rhs)) : \ + (Uint128High64(lhs) op Uint128High64(rhs)); \ +} + +CMP128(<) +CMP128(>) +CMP128(>=) +CMP128(<=) + +#undef CMP128 + +// Unary operators + +inline uint128 operator-(const uint128& val) { + const uint64 hi_flip = ~Uint128High64(val); + const uint64 lo_flip = ~Uint128Low64(val); + const uint64 lo_add = lo_flip + 1; + if (lo_add < lo_flip) { + return uint128(hi_flip + 1, lo_add); + } + return uint128(hi_flip, lo_add); +} + +inline bool operator!(const uint128& val) { + return !Uint128High64(val) && !Uint128Low64(val); +} + +// Logical operators. + +inline uint128 operator~(const uint128& val) { + return uint128(~Uint128High64(val), ~Uint128Low64(val)); +} + +#define LOGIC128(op) \ +inline uint128 operator op(const uint128& lhs, const uint128& rhs) { \ + return uint128(Uint128High64(lhs) op Uint128High64(rhs), \ + Uint128Low64(lhs) op Uint128Low64(rhs)); \ +} + +LOGIC128(|) +LOGIC128(&) +LOGIC128(^) + +#undef LOGIC128 + +#define LOGICASSIGN128(op) \ +inline uint128& uint128::operator op(const uint128& other) { \ + hi_ op other.hi_; \ + lo_ op other.lo_; \ + return *this; \ +} + +LOGICASSIGN128(|=) +LOGICASSIGN128(&=) +LOGICASSIGN128(^=) + +#undef LOGICASSIGN128 + +// Shift operators. + +inline uint128 operator<<(const uint128& val, int amount) { + // uint64 shifts of >= 64 are undefined, so we will need some special-casing. + if (amount < 64) { + if (amount == 0) { + return val; + } + uint64 new_hi = (Uint128High64(val) << amount) | + (Uint128Low64(val) >> (64 - amount)); + uint64 new_lo = Uint128Low64(val) << amount; + return uint128(new_hi, new_lo); + } else if (amount < 128) { + return uint128(Uint128Low64(val) << (amount - 64), 0); + } else { + return uint128(0, 0); + } +} + +inline uint128 operator>>(const uint128& val, int amount) { + // uint64 shifts of >= 64 are undefined, so we will need some special-casing. + if (amount < 64) { + if (amount == 0) { + return val; + } + uint64 new_hi = Uint128High64(val) >> amount; + uint64 new_lo = (Uint128Low64(val) >> amount) | + (Uint128High64(val) << (64 - amount)); + return uint128(new_hi, new_lo); + } else if (amount < 128) { + return uint128(0, Uint128High64(val) >> (amount - 64)); + } else { + return uint128(0, 0); + } +} + +inline uint128& uint128::operator<<=(int amount) { + // uint64 shifts of >= 64 are undefined, so we will need some special-casing. + if (amount < 64) { + if (amount != 0) { + hi_ = (hi_ << amount) | (lo_ >> (64 - amount)); + lo_ = lo_ << amount; + } + } else if (amount < 128) { + hi_ = lo_ << (amount - 64); + lo_ = 0; + } else { + hi_ = 0; + lo_ = 0; + } + return *this; +} + +inline uint128& uint128::operator>>=(int amount) { + // uint64 shifts of >= 64 are undefined, so we will need some special-casing. + if (amount < 64) { + if (amount != 0) { + lo_ = (lo_ >> amount) | (hi_ << (64 - amount)); + hi_ = hi_ >> amount; + } + } else if (amount < 128) { + lo_ = hi_ >> (amount - 64); + hi_ = 0; + } else { + lo_ = 0; + hi_ = 0; + } + return *this; +} + +inline uint128 operator+(const uint128& lhs, const uint128& rhs) { + return uint128(lhs) += rhs; +} + +inline uint128 operator-(const uint128& lhs, const uint128& rhs) { + return uint128(lhs) -= rhs; +} + +inline uint128 operator*(const uint128& lhs, const uint128& rhs) { + return uint128(lhs) *= rhs; +} + +inline uint128 operator/(const uint128& lhs, const uint128& rhs) { + return uint128(lhs) /= rhs; +} + +inline uint128 operator%(const uint128& lhs, const uint128& rhs) { + return uint128(lhs) %= rhs; +} + +inline uint128& uint128::operator+=(const uint128& b) { + hi_ += b.hi_; + uint64 lolo = lo_ + b.lo_; + if (lolo < lo_) + ++hi_; + lo_ = lolo; + return *this; +} + +inline uint128& uint128::operator-=(const uint128& b) { + hi_ -= b.hi_; + if (b.lo_ > lo_) + --hi_; + lo_ -= b.lo_; + return *this; +} + +inline uint128& uint128::operator*=(const uint128& b) { + uint64 a96 = hi_ >> 32; + uint64 a64 = hi_ & 0xffffffffu; + uint64 a32 = lo_ >> 32; + uint64 a00 = lo_ & 0xffffffffu; + uint64 b96 = b.hi_ >> 32; + uint64 b64 = b.hi_ & 0xffffffffu; + uint64 b32 = b.lo_ >> 32; + uint64 b00 = b.lo_ & 0xffffffffu; + // multiply [a96 .. a00] x [b96 .. b00] + // terms higher than c96 disappear off the high side + // terms c96 and c64 are safe to ignore carry bit + uint64 c96 = a96 * b00 + a64 * b32 + a32 * b64 + a00 * b96; + uint64 c64 = a64 * b00 + a32 * b32 + a00 * b64; + this->hi_ = (c96 << 32) + c64; + this->lo_ = 0; + // add terms after this one at a time to capture carry + *this += uint128(a32 * b00) << 32; + *this += uint128(a00 * b32) << 32; + *this += a00 * b00; + return *this; +} + +inline uint128 uint128::operator++(int) { + uint128 tmp(*this); + *this += 1; + return tmp; +} + +inline uint128 uint128::operator--(int) { + uint128 tmp(*this); + *this -= 1; + return tmp; +} + +inline uint128& uint128::operator++() { + *this += 1; + return *this; +} + +inline uint128& uint128::operator--() { + *this -= 1; + return *this; +} + +} // namespace protobuf +} // namespace google + +#include <google/protobuf/port_undef.inc> + +#endif // GOOGLE_PROTOBUF_STUBS_INT128_H_ diff --git a/contrib/libs/protobuf_old/src/google/protobuf/stubs/logging.h b/contrib/libs/protobuf_old/src/google/protobuf/stubs/logging.h new file mode 100644 index 0000000000..61a271434f --- /dev/null +++ b/contrib/libs/protobuf_old/src/google/protobuf/stubs/logging.h @@ -0,0 +1,239 @@ +// 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_STUBS_LOGGING_H_ +#define GOOGLE_PROTOBUF_STUBS_LOGGING_H_ + +#include <google/protobuf/stubs/macros.h> +#include <google/protobuf/stubs/port.h> +#include <google/protobuf/stubs/status.h> +#include <google/protobuf/stubs/stringpiece.h> + +#include <google/protobuf/port_def.inc> + +// =================================================================== +// emulates google3/base/logging.h + +namespace google { +namespace protobuf { + +enum LogLevel { + LOGLEVEL_INFO, // Informational. This is never actually used by + // libprotobuf. + LOGLEVEL_WARNING, // Warns about issues that, although not technically a + // problem now, could cause problems in the future. For + // example, a // warning will be printed when parsing a + // message that is near the message size limit. + LOGLEVEL_ERROR, // An error occurred which should never happen during + // normal use. + LOGLEVEL_FATAL, // An error occurred from which the library cannot + // recover. This usually indicates a programming error + // in the code which calls the library, especially when + // compiled in debug mode. + +#ifdef NDEBUG + LOGLEVEL_DFATAL = LOGLEVEL_ERROR +#else + LOGLEVEL_DFATAL = LOGLEVEL_FATAL +#endif +}; + +class uint128; +namespace internal { + +class LogFinisher; + +class PROTOBUF_EXPORT LogMessage { + public: + LogMessage(LogLevel level, const char* filename, int line); + ~LogMessage(); + + LogMessage& operator<<(const TProtoStringType& value); + LogMessage& operator<<(const char* value); + LogMessage& operator<<(char value); + LogMessage& operator<<(int value); + LogMessage& operator<<(uint value); + LogMessage& operator<<(long value); + LogMessage& operator<<(unsigned long value); + LogMessage& operator<<(long long value); + LogMessage& operator<<(unsigned long long value); + LogMessage& operator<<(double value); + LogMessage& operator<<(void* value); + LogMessage& operator<<(const StringPiece& value); + LogMessage& operator<<(const util::Status& status); + LogMessage& operator<<(const uint128& value); + + private: + friend class LogFinisher; + void Finish(); + + LogLevel level_; + const char* filename_; + int line_; + TProtoStringType message_; +}; + +// Used to make the entire "LOG(BLAH) << etc." expression have a void return +// type and print a newline after each message. +class PROTOBUF_EXPORT LogFinisher { + public: + void operator=(LogMessage& other); +}; + +template<typename T> +bool IsOk(T status) { return status.ok(); } +template<> +inline bool IsOk(bool status) { return status; } + +} // namespace internal + +// Undef everything in case we're being mixed with some other Google library +// which already defined them itself. Presumably all Google libraries will +// support the same syntax for these so it should not be a big deal if they +// end up using our definitions instead. +#undef GOOGLE_LOG +#undef GOOGLE_LOG_IF + +#undef GOOGLE_CHECK +#undef GOOGLE_CHECK_OK +#undef GOOGLE_CHECK_EQ +#undef GOOGLE_CHECK_NE +#undef GOOGLE_CHECK_LT +#undef GOOGLE_CHECK_LE +#undef GOOGLE_CHECK_GT +#undef GOOGLE_CHECK_GE +#undef GOOGLE_CHECK_NOTNULL + +#undef GOOGLE_DLOG +#undef GOOGLE_DCHECK +#undef GOOGLE_DCHECK_OK +#undef GOOGLE_DCHECK_EQ +#undef GOOGLE_DCHECK_NE +#undef GOOGLE_DCHECK_LT +#undef GOOGLE_DCHECK_LE +#undef GOOGLE_DCHECK_GT +#undef GOOGLE_DCHECK_GE + +#define GOOGLE_LOG(LEVEL) \ + ::google::protobuf::internal::LogFinisher() = \ + ::google::protobuf::internal::LogMessage( \ + ::google::protobuf::LOGLEVEL_##LEVEL, __FILE__, __LINE__) +#define GOOGLE_LOG_IF(LEVEL, CONDITION) \ + !(CONDITION) ? (void)0 : GOOGLE_LOG(LEVEL) + +#define GOOGLE_CHECK(EXPRESSION) \ + GOOGLE_LOG_IF(FATAL, !(EXPRESSION)) << "CHECK failed: " #EXPRESSION ": " +#define GOOGLE_CHECK_OK(A) GOOGLE_CHECK(::google::protobuf::internal::IsOk(A)) +#define GOOGLE_CHECK_EQ(A, B) GOOGLE_CHECK((A) == (B)) +#define GOOGLE_CHECK_NE(A, B) GOOGLE_CHECK((A) != (B)) +#define GOOGLE_CHECK_LT(A, B) GOOGLE_CHECK((A) < (B)) +#define GOOGLE_CHECK_LE(A, B) GOOGLE_CHECK((A) <= (B)) +#define GOOGLE_CHECK_GT(A, B) GOOGLE_CHECK((A) > (B)) +#define GOOGLE_CHECK_GE(A, B) GOOGLE_CHECK((A) >= (B)) + +namespace internal { +template<typename T> +T* CheckNotNull(const char* /* file */, int /* line */, + const char* name, T* val) { + if (val == nullptr) { + GOOGLE_LOG(FATAL) << name; + } + return val; +} +} // namespace internal +#define GOOGLE_CHECK_NOTNULL(A) \ + ::google::protobuf::internal::CheckNotNull( \ + __FILE__, __LINE__, "'" #A "' must not be nullptr", (A)) + +#ifdef NDEBUG + +#define GOOGLE_DLOG(LEVEL) GOOGLE_LOG_IF(LEVEL, false) + +#define GOOGLE_DCHECK(EXPRESSION) while(false) GOOGLE_CHECK(EXPRESSION) +#define GOOGLE_DCHECK_OK(E) GOOGLE_DCHECK(::google::protobuf::internal::IsOk(E)) +#define GOOGLE_DCHECK_EQ(A, B) GOOGLE_DCHECK((A) == (B)) +#define GOOGLE_DCHECK_NE(A, B) GOOGLE_DCHECK((A) != (B)) +#define GOOGLE_DCHECK_LT(A, B) GOOGLE_DCHECK((A) < (B)) +#define GOOGLE_DCHECK_LE(A, B) GOOGLE_DCHECK((A) <= (B)) +#define GOOGLE_DCHECK_GT(A, B) GOOGLE_DCHECK((A) > (B)) +#define GOOGLE_DCHECK_GE(A, B) GOOGLE_DCHECK((A) >= (B)) + +#else // NDEBUG + +#define GOOGLE_DLOG GOOGLE_LOG + +#define GOOGLE_DCHECK GOOGLE_CHECK +#define GOOGLE_DCHECK_OK GOOGLE_CHECK_OK +#define GOOGLE_DCHECK_EQ GOOGLE_CHECK_EQ +#define GOOGLE_DCHECK_NE GOOGLE_CHECK_NE +#define GOOGLE_DCHECK_LT GOOGLE_CHECK_LT +#define GOOGLE_DCHECK_LE GOOGLE_CHECK_LE +#define GOOGLE_DCHECK_GT GOOGLE_CHECK_GT +#define GOOGLE_DCHECK_GE GOOGLE_CHECK_GE + +#endif // !NDEBUG + +typedef void LogHandler(LogLevel level, const char* filename, int line, + const TProtoStringType& message); + +// The protobuf library sometimes writes warning and error messages to +// stderr. These messages are primarily useful for developers, but may +// also help end users figure out a problem. If you would prefer that +// these messages be sent somewhere other than stderr, call SetLogHandler() +// to set your own handler. This returns the old handler. Set the handler +// to nullptr to ignore log messages (but see also LogSilencer, below). +// +// Obviously, SetLogHandler is not thread-safe. You should only call it +// at initialization time, and probably not from library code. If you +// simply want to suppress log messages temporarily (e.g. because you +// have some code that tends to trigger them frequently and you know +// the warnings are not important to you), use the LogSilencer class +// below. +PROTOBUF_EXPORT LogHandler* SetLogHandler(LogHandler* new_func); + +// Create a LogSilencer if you want to temporarily suppress all log +// messages. As long as any LogSilencer objects exist, non-fatal +// log messages will be discarded (the current LogHandler will *not* +// be called). Constructing a LogSilencer is thread-safe. You may +// accidentally suppress log messages occurring in another thread, but +// since messages are generally for debugging purposes only, this isn't +// a big deal. If you want to intercept log messages, use SetLogHandler(). +class PROTOBUF_EXPORT LogSilencer { + public: + LogSilencer(); + ~LogSilencer(); +}; + +} // namespace protobuf +} // namespace google + +#include <google/protobuf/port_undef.inc> + +#endif // GOOGLE_PROTOBUF_STUBS_LOGGING_H_ diff --git a/contrib/libs/protobuf_old/src/google/protobuf/stubs/macros.h b/contrib/libs/protobuf_old/src/google/protobuf/stubs/macros.h new file mode 100644 index 0000000000..ae9a8b987f --- /dev/null +++ b/contrib/libs/protobuf_old/src/google/protobuf/stubs/macros.h @@ -0,0 +1,93 @@ +// 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_MACROS_H__ +#define GOOGLE_PROTOBUF_MACROS_H__ + +namespace google { +namespace protobuf { + +#undef GOOGLE_DISALLOW_EVIL_CONSTRUCTORS +#define GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(TypeName) \ + TypeName(const TypeName&) = delete; \ + void operator=(const TypeName&) = delete + +#undef GOOGLE_DISALLOW_IMPLICIT_CONSTRUCTORS +#define GOOGLE_DISALLOW_IMPLICIT_CONSTRUCTORS(TypeName) \ + TypeName() = delete; \ + TypeName(const TypeName&) = delete; \ + void operator=(const TypeName&) = delete + +// =================================================================== +// from google3/base/basictypes.h + +// The GOOGLE_ARRAYSIZE(arr) macro returns the # of elements in an array arr. +// The expression is a compile-time constant, and therefore can be +// used in defining new arrays, for example. +// +// GOOGLE_ARRAYSIZE catches a few type errors. If you see a compiler error +// +// "warning: division by zero in ..." +// +// when using GOOGLE_ARRAYSIZE, you are (wrongfully) giving it a pointer. +// You should only use GOOGLE_ARRAYSIZE on statically allocated arrays. +// +// The following comments are on the implementation details, and can +// be ignored by the users. +// +// ARRAYSIZE(arr) works by inspecting sizeof(arr) (the # of bytes in +// the array) and sizeof(*(arr)) (the # of bytes in one array +// element). If the former is divisible by the latter, perhaps arr is +// indeed an array, in which case the division result is the # of +// elements in the array. Otherwise, arr cannot possibly be an array, +// and we generate a compiler error to prevent the code from +// compiling. +// +// Since the size of bool is implementation-defined, we need to cast +// !(sizeof(a) & sizeof(*(a))) to size_t in order to ensure the final +// result has type size_t. +// +// This macro is not perfect as it wrongfully accepts certain +// pointers, namely where the pointer size is divisible by the pointee +// size. Since all our code has to go through a 32-bit compiler, +// where a pointer is 4 bytes, this means all pointers to a type whose +// size is 3 or greater than 4 will be (righteously) rejected. +// +// Kudos to Jorg Brown for this simple and elegant implementation. + +#undef GOOGLE_ARRAYSIZE +#define GOOGLE_ARRAYSIZE(a) \ + ((sizeof(a) / sizeof(*(a))) / \ + static_cast<size_t>(!(sizeof(a) % sizeof(*(a))))) + +} // namespace protobuf +} // namespace google + +#endif // GOOGLE_PROTOBUF_MACROS_H__ diff --git a/contrib/libs/protobuf_old/src/google/protobuf/stubs/map_util.h b/contrib/libs/protobuf_old/src/google/protobuf/stubs/map_util.h new file mode 100644 index 0000000000..24e098ad1b --- /dev/null +++ b/contrib/libs/protobuf_old/src/google/protobuf/stubs/map_util.h @@ -0,0 +1,769 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2014 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. + +// from google3/util/gtl/map_util.h +// Author: Anton Carver + +#ifndef GOOGLE_PROTOBUF_STUBS_MAP_UTIL_H__ +#define GOOGLE_PROTOBUF_STUBS_MAP_UTIL_H__ + +#include <stddef.h> +#include <iterator> +#include <string> +#include <utility> +#include <vector> + +#include <google/protobuf/stubs/common.h> + +namespace google { +namespace protobuf { +namespace internal { +// Local implementation of RemoveConst to avoid including base/type_traits.h. +template <class T> struct RemoveConst { typedef T type; }; +template <class T> struct RemoveConst<const T> : RemoveConst<T> {}; +} // namespace internal + +// +// Find*() +// + +// Returns a const reference to the value associated with the given key if it +// exists. Crashes otherwise. +// +// This is intended as a replacement for operator[] as an rvalue (for reading) +// when the key is guaranteed to exist. +// +// operator[] for lookup is discouraged for several reasons: +// * It has a side-effect of inserting missing keys +// * It is not thread-safe (even when it is not inserting, it can still +// choose to resize the underlying storage) +// * It invalidates iterators (when it chooses to resize) +// * It default constructs a value object even if it doesn't need to +// +// This version assumes the key is printable, and includes it in the fatal log +// message. +template <class Collection> +const typename Collection::value_type::second_type& +FindOrDie(const Collection& collection, + const typename Collection::value_type::first_type& key) { + typename Collection::const_iterator it = collection.find(key); + GOOGLE_CHECK(it != collection.end()) << "Map key not found: " << key; + return it->second; +} + +// Same as above, but returns a non-const reference. +template <class Collection> +typename Collection::value_type::second_type& +FindOrDie(Collection& collection, // NOLINT + const typename Collection::value_type::first_type& key) { + typename Collection::iterator it = collection.find(key); + GOOGLE_CHECK(it != collection.end()) << "Map key not found: " << key; + return it->second; +} + +// Same as FindOrDie above, but doesn't log the key on failure. +template <class Collection> +const typename Collection::value_type::second_type& +FindOrDieNoPrint(const Collection& collection, + const typename Collection::value_type::first_type& key) { + typename Collection::const_iterator it = collection.find(key); + GOOGLE_CHECK(it != collection.end()) << "Map key not found"; + return it->second; +} + +// Same as above, but returns a non-const reference. +template <class Collection> +typename Collection::value_type::second_type& +FindOrDieNoPrint(Collection& collection, // NOLINT + const typename Collection::value_type::first_type& key) { + typename Collection::iterator it = collection.find(key); + GOOGLE_CHECK(it != collection.end()) << "Map key not found"; + return it->second; +} + +// Returns a const reference to the value associated with the given key if it +// exists, otherwise returns a const reference to the provided default value. +// +// WARNING: If a temporary object is passed as the default "value," +// this function will return a reference to that temporary object, +// which will be destroyed at the end of the statement. A common +// example: if you have a map with string values, and you pass a char* +// as the default "value," either use the returned value immediately +// or store it in a string (not string&). +// Details: http://go/findwithdefault +template <class Collection> +const typename Collection::value_type::second_type& +FindWithDefault(const Collection& collection, + const typename Collection::value_type::first_type& key, + const typename Collection::value_type::second_type& value) { + typename Collection::const_iterator it = collection.find(key); + if (it == collection.end()) { + return value; + } + return it->second; +} + +// Returns a pointer to the const value associated with the given key if it +// exists, or nullptr otherwise. +template <class Collection> +const typename Collection::value_type::second_type* +FindOrNull(const Collection& collection, + const typename Collection::value_type::first_type& key) { + typename Collection::const_iterator it = collection.find(key); + if (it == collection.end()) { + return 0; + } + return &it->second; +} + +// Same as above but returns a pointer to the non-const value. +template <class Collection> +typename Collection::value_type::second_type* +FindOrNull(Collection& collection, // NOLINT + const typename Collection::value_type::first_type& key) { + typename Collection::iterator it = collection.find(key); + if (it == collection.end()) { + return 0; + } + return &it->second; +} + +// Returns the pointer value associated with the given key. If none is found, +// nullptr is returned. The function is designed to be used with a map of keys to +// pointers. +// +// This function does not distinguish between a missing key and a key mapped +// to nullptr. +template <class Collection> +typename Collection::value_type::second_type +FindPtrOrNull(const Collection& collection, + const typename Collection::value_type::first_type& key) { + typename Collection::const_iterator it = collection.find(key); + if (it == collection.end()) { + return typename Collection::value_type::second_type(); + } + return it->second; +} + +// Same as above, except takes non-const reference to collection. +// +// This function is needed for containers that propagate constness to the +// pointee, such as boost::ptr_map. +template <class Collection> +typename Collection::value_type::second_type +FindPtrOrNull(Collection& collection, // NOLINT + const typename Collection::value_type::first_type& key) { + typename Collection::iterator it = collection.find(key); + if (it == collection.end()) { + return typename Collection::value_type::second_type(); + } + return it->second; +} + +// Finds the pointer value associated with the given key in a map whose values +// are linked_ptrs. Returns nullptr if key is not found. +template <class Collection> +typename Collection::value_type::second_type::element_type* +FindLinkedPtrOrNull(const Collection& collection, + const typename Collection::value_type::first_type& key) { + typename Collection::const_iterator it = collection.find(key); + if (it == collection.end()) { + return 0; + } + // Since linked_ptr::get() is a const member returning a non const, + // we do not need a version of this function taking a non const collection. + return it->second.get(); +} + +// Same as above, but dies if the key is not found. +template <class Collection> +typename Collection::value_type::second_type::element_type& +FindLinkedPtrOrDie(const Collection& collection, + const typename Collection::value_type::first_type& key) { + typename Collection::const_iterator it = collection.find(key); + GOOGLE_CHECK(it != collection.end()) << "key not found: " << key; + // Since linked_ptr::operator*() is a const member returning a non const, + // we do not need a version of this function taking a non const collection. + return *it->second; +} + +// Finds the value associated with the given key and copies it to *value (if not +// nullptr). Returns false if the key was not found, true otherwise. +template <class Collection, class Key, class Value> +bool FindCopy(const Collection& collection, + const Key& key, + Value* const value) { + typename Collection::const_iterator it = collection.find(key); + if (it == collection.end()) { + return false; + } + if (value) { + *value = it->second; + } + return true; +} + +// +// Contains*() +// + +// Returns true if and only if the given collection contains the given key. +template <class Collection, class Key> +bool ContainsKey(const Collection& collection, const Key& key) { + return collection.find(key) != collection.end(); +} + +// Returns true if and only if the given collection contains the given key-value +// pair. +template <class Collection, class Key, class Value> +bool ContainsKeyValuePair(const Collection& collection, + const Key& key, + const Value& value) { + typedef typename Collection::const_iterator const_iterator; + std::pair<const_iterator, const_iterator> range = collection.equal_range(key); + for (const_iterator it = range.first; it != range.second; ++it) { + if (it->second == value) { + return true; + } + } + return false; +} + +// +// Insert*() +// + +// Inserts the given key-value pair into the collection. Returns true if and +// only if the key from the given pair didn't previously exist. Otherwise, the +// value in the map is replaced with the value from the given pair. +template <class Collection> +bool InsertOrUpdate(Collection* const collection, + const typename Collection::value_type& vt) { + std::pair<typename Collection::iterator, bool> ret = collection->insert(vt); + if (!ret.second) { + // update + ret.first->second = vt.second; + return false; + } + return true; +} + +// Same as above, except that the key and value are passed separately. +template <class Collection> +bool InsertOrUpdate(Collection* const collection, + const typename Collection::value_type::first_type& key, + const typename Collection::value_type::second_type& value) { + return InsertOrUpdate( + collection, typename Collection::value_type(key, value)); +} + +// Inserts/updates all the key-value pairs from the range defined by the +// iterators "first" and "last" into the given collection. +template <class Collection, class InputIterator> +void InsertOrUpdateMany(Collection* const collection, + InputIterator first, InputIterator last) { + for (; first != last; ++first) { + InsertOrUpdate(collection, *first); + } +} + +// Change the value associated with a particular key in a map or hash_map +// of the form map<Key, Value*> which owns the objects pointed to by the +// value pointers. If there was an existing value for the key, it is deleted. +// True indicates an insert took place, false indicates an update + delete. +template <class Collection> +bool InsertAndDeleteExisting( + Collection* const collection, + const typename Collection::value_type::first_type& key, + const typename Collection::value_type::second_type& value) { + std::pair<typename Collection::iterator, bool> ret = + collection->insert(typename Collection::value_type(key, value)); + if (!ret.second) { + delete ret.first->second; + ret.first->second = value; + return false; + } + return true; +} + +// Inserts the given key and value into the given collection if and only if the +// given key did NOT already exist in the collection. If the key previously +// existed in the collection, the value is not changed. Returns true if the +// key-value pair was inserted; returns false if the key was already present. +template <class Collection> +bool InsertIfNotPresent(Collection* const collection, + const typename Collection::value_type& vt) { + return collection->insert(vt).second; +} + +// Same as above except the key and value are passed separately. +template <class Collection> +bool InsertIfNotPresent( + Collection* const collection, + const typename Collection::value_type::first_type& key, + const typename Collection::value_type::second_type& value) { + return InsertIfNotPresent( + collection, typename Collection::value_type(key, value)); +} + +// Same as above except dies if the key already exists in the collection. +template <class Collection> +void InsertOrDie(Collection* const collection, + const typename Collection::value_type& value) { + GOOGLE_CHECK(InsertIfNotPresent(collection, value)) + << "duplicate value: " << value; +} + +// Same as above except doesn't log the value on error. +template <class Collection> +void InsertOrDieNoPrint(Collection* const collection, + const typename Collection::value_type& value) { + GOOGLE_CHECK(InsertIfNotPresent(collection, value)) << "duplicate value."; +} + +// Inserts the key-value pair into the collection. Dies if key was already +// present. +template <class Collection> +void InsertOrDie(Collection* const collection, + const typename Collection::value_type::first_type& key, + const typename Collection::value_type::second_type& data) { + GOOGLE_CHECK(InsertIfNotPresent(collection, key, data)) + << "duplicate key: " << key; +} + +// Same as above except doesn't log the key on error. +template <class Collection> +void InsertOrDieNoPrint( + Collection* const collection, + const typename Collection::value_type::first_type& key, + const typename Collection::value_type::second_type& data) { + GOOGLE_CHECK(InsertIfNotPresent(collection, key, data)) << "duplicate key."; +} + +// Inserts a new key and default-initialized value. Dies if the key was already +// present. Returns a reference to the value. Example usage: +// +// map<int, SomeProto> m; +// SomeProto& proto = InsertKeyOrDie(&m, 3); +// proto.set_field("foo"); +template <class Collection> +typename Collection::value_type::second_type& InsertKeyOrDie( + Collection* const collection, + const typename Collection::value_type::first_type& key) { + typedef typename Collection::value_type value_type; + std::pair<typename Collection::iterator, bool> res = + collection->insert(value_type(key, typename value_type::second_type())); + GOOGLE_CHECK(res.second) << "duplicate key: " << key; + return res.first->second; +} + +// +// Lookup*() +// + +// Looks up a given key and value pair in a collection and inserts the key-value +// pair if it's not already present. Returns a reference to the value associated +// with the key. +template <class Collection> +typename Collection::value_type::second_type& +LookupOrInsert(Collection* const collection, + const typename Collection::value_type& vt) { + return collection->insert(vt).first->second; +} + +// Same as above except the key-value are passed separately. +template <class Collection> +typename Collection::value_type::second_type& +LookupOrInsert(Collection* const collection, + const typename Collection::value_type::first_type& key, + const typename Collection::value_type::second_type& value) { + return LookupOrInsert( + collection, typename Collection::value_type(key, value)); +} + +// Counts the number of equivalent elements in the given "sequence", and stores +// the results in "count_map" with element as the key and count as the value. +// +// Example: +// vector<string> v = {"a", "b", "c", "a", "b"}; +// map<string, int> m; +// AddTokenCounts(v, 1, &m); +// assert(m["a"] == 2); +// assert(m["b"] == 2); +// assert(m["c"] == 1); +template <typename Sequence, typename Collection> +void AddTokenCounts( + const Sequence& sequence, + const typename Collection::value_type::second_type& increment, + Collection* const count_map) { + for (typename Sequence::const_iterator it = sequence.begin(); + it != sequence.end(); ++it) { + typename Collection::value_type::second_type& value = + LookupOrInsert(count_map, *it, + typename Collection::value_type::second_type()); + value += increment; + } +} + +// Returns a reference to the value associated with key. If not found, a value +// is default constructed on the heap and added to the map. +// +// This function is useful for containers of the form map<Key, Value*>, where +// inserting a new key, value pair involves constructing a new heap-allocated +// Value, and storing a pointer to that in the collection. +template <class Collection> +typename Collection::value_type::second_type& +LookupOrInsertNew(Collection* const collection, + const typename Collection::value_type::first_type& key) { + typedef typename std::iterator_traits< + typename Collection::value_type::second_type>::value_type Element; + std::pair<typename Collection::iterator, bool> ret = + collection->insert(typename Collection::value_type( + key, + static_cast<typename Collection::value_type::second_type>(nullptr))); + if (ret.second) { + ret.first->second = new Element(); + } + return ret.first->second; +} + +// Same as above but constructs the value using the single-argument constructor +// and the given "arg". +template <class Collection, class Arg> +typename Collection::value_type::second_type& +LookupOrInsertNew(Collection* const collection, + const typename Collection::value_type::first_type& key, + const Arg& arg) { + typedef typename std::iterator_traits< + typename Collection::value_type::second_type>::value_type Element; + std::pair<typename Collection::iterator, bool> ret = + collection->insert(typename Collection::value_type( + key, + static_cast<typename Collection::value_type::second_type>(nullptr))); + if (ret.second) { + ret.first->second = new Element(arg); + } + return ret.first->second; +} + +// Lookup of linked/shared pointers is used in two scenarios: +// +// Use LookupOrInsertNewLinkedPtr if the container owns the elements. +// In this case it is fine working with the raw pointer as long as it is +// guaranteed that no other thread can delete/update an accessed element. +// A mutex will need to lock the container operation as well as the use +// of the returned elements. Finding an element may be performed using +// FindLinkedPtr*(). +// +// Use LookupOrInsertNewSharedPtr if the container does not own the elements +// for their whole lifetime. This is typically the case when a reader allows +// parallel updates to the container. In this case a Mutex only needs to lock +// container operations, but all element operations must be performed on the +// shared pointer. Finding an element must be performed using FindPtr*() and +// cannot be done with FindLinkedPtr*() even though it compiles. + +// Lookup a key in a map or hash_map whose values are linked_ptrs. If it is +// missing, set collection[key].reset(new Value::element_type) and return that. +// Value::element_type must be default constructable. +template <class Collection> +typename Collection::value_type::second_type::element_type* +LookupOrInsertNewLinkedPtr( + Collection* const collection, + const typename Collection::value_type::first_type& key) { + typedef typename Collection::value_type::second_type Value; + std::pair<typename Collection::iterator, bool> ret = + collection->insert(typename Collection::value_type(key, Value())); + if (ret.second) { + ret.first->second.reset(new typename Value::element_type); + } + return ret.first->second.get(); +} + +// A variant of LookupOrInsertNewLinkedPtr where the value is constructed using +// a single-parameter constructor. Note: the constructor argument is computed +// even if it will not be used, so only values cheap to compute should be passed +// here. On the other hand it does not matter how expensive the construction of +// the actual stored value is, as that only occurs if necessary. +template <class Collection, class Arg> +typename Collection::value_type::second_type::element_type* +LookupOrInsertNewLinkedPtr( + Collection* const collection, + const typename Collection::value_type::first_type& key, + const Arg& arg) { + typedef typename Collection::value_type::second_type Value; + std::pair<typename Collection::iterator, bool> ret = + collection->insert(typename Collection::value_type(key, Value())); + if (ret.second) { + ret.first->second.reset(new typename Value::element_type(arg)); + } + return ret.first->second.get(); +} + +// Lookup a key in a map or hash_map whose values are shared_ptrs. If it is +// missing, set collection[key].reset(new Value::element_type). Unlike +// LookupOrInsertNewLinkedPtr, this function returns the shared_ptr instead of +// the raw pointer. Value::element_type must be default constructable. +template <class Collection> +typename Collection::value_type::second_type& +LookupOrInsertNewSharedPtr( + Collection* const collection, + const typename Collection::value_type::first_type& key) { + typedef typename Collection::value_type::second_type SharedPtr; + typedef typename Collection::value_type::second_type::element_type Element; + std::pair<typename Collection::iterator, bool> ret = + collection->insert(typename Collection::value_type(key, SharedPtr())); + if (ret.second) { + ret.first->second.reset(new Element()); + } + return ret.first->second; +} + +// A variant of LookupOrInsertNewSharedPtr where the value is constructed using +// a single-parameter constructor. Note: the constructor argument is computed +// even if it will not be used, so only values cheap to compute should be passed +// here. On the other hand it does not matter how expensive the construction of +// the actual stored value is, as that only occurs if necessary. +template <class Collection, class Arg> +typename Collection::value_type::second_type& +LookupOrInsertNewSharedPtr( + Collection* const collection, + const typename Collection::value_type::first_type& key, + const Arg& arg) { + typedef typename Collection::value_type::second_type SharedPtr; + typedef typename Collection::value_type::second_type::element_type Element; + std::pair<typename Collection::iterator, bool> ret = + collection->insert(typename Collection::value_type(key, SharedPtr())); + if (ret.second) { + ret.first->second.reset(new Element(arg)); + } + return ret.first->second; +} + +// +// Misc Utility Functions +// + +// Updates the value associated with the given key. If the key was not already +// present, then the key-value pair are inserted and "previous" is unchanged. If +// the key was already present, the value is updated and "*previous" will +// contain a copy of the old value. +// +// InsertOrReturnExisting has complementary behavior that returns the +// address of an already existing value, rather than updating it. +template <class Collection> +bool UpdateReturnCopy(Collection* const collection, + const typename Collection::value_type::first_type& key, + const typename Collection::value_type::second_type& value, + typename Collection::value_type::second_type* previous) { + std::pair<typename Collection::iterator, bool> ret = + collection->insert(typename Collection::value_type(key, value)); + if (!ret.second) { + // update + if (previous) { + *previous = ret.first->second; + } + ret.first->second = value; + return true; + } + return false; +} + +// Same as above except that the key and value are passed as a pair. +template <class Collection> +bool UpdateReturnCopy(Collection* const collection, + const typename Collection::value_type& vt, + typename Collection::value_type::second_type* previous) { + std::pair<typename Collection::iterator, bool> ret = collection->insert(vt); + if (!ret.second) { + // update + if (previous) { + *previous = ret.first->second; + } + ret.first->second = vt.second; + return true; + } + return false; +} + +// Tries to insert the given key-value pair into the collection. Returns nullptr if +// the insert succeeds. Otherwise, returns a pointer to the existing value. +// +// This complements UpdateReturnCopy in that it allows to update only after +// verifying the old value and still insert quickly without having to look up +// twice. Unlike UpdateReturnCopy this also does not come with the issue of an +// undefined previous* in case new data was inserted. +template <class Collection> +typename Collection::value_type::second_type* InsertOrReturnExisting( + Collection* const collection, const typename Collection::value_type& vt) { + std::pair<typename Collection::iterator, bool> ret = collection->insert(vt); + if (ret.second) { + return nullptr; // Inserted, no existing previous value. + } else { + return &ret.first->second; // Return address of already existing value. + } +} + +// Same as above, except for explicit key and data. +template <class Collection> +typename Collection::value_type::second_type* InsertOrReturnExisting( + Collection* const collection, + const typename Collection::value_type::first_type& key, + const typename Collection::value_type::second_type& data) { + return InsertOrReturnExisting(collection, + typename Collection::value_type(key, data)); +} + +// Erases the collection item identified by the given key, and returns the value +// associated with that key. It is assumed that the value (i.e., the +// mapped_type) is a pointer. Returns nullptr if the key was not found in the +// collection. +// +// Examples: +// map<string, MyType*> my_map; +// +// One line cleanup: +// delete EraseKeyReturnValuePtr(&my_map, "abc"); +// +// Use returned value: +// std::unique_ptr<MyType> value_ptr( +// EraseKeyReturnValuePtr(&my_map, "abc")); +// if (value_ptr.get()) +// value_ptr->DoSomething(); +// +template <class Collection> +typename Collection::value_type::second_type EraseKeyReturnValuePtr( + Collection* const collection, + const typename Collection::value_type::first_type& key) { + typename Collection::iterator it = collection->find(key); + if (it == collection->end()) { + return nullptr; + } + typename Collection::value_type::second_type v = it->second; + collection->erase(it); + return v; +} + +// Inserts all the keys from map_container into key_container, which must +// support insert(MapContainer::key_type). +// +// Note: any initial contents of the key_container are not cleared. +template <class MapContainer, class KeyContainer> +void InsertKeysFromMap(const MapContainer& map_container, + KeyContainer* key_container) { + GOOGLE_CHECK(key_container != nullptr); + for (typename MapContainer::const_iterator it = map_container.begin(); + it != map_container.end(); ++it) { + key_container->insert(it->first); + } +} + +// Appends all the keys from map_container into key_container, which must +// support push_back(MapContainer::key_type). +// +// Note: any initial contents of the key_container are not cleared. +template <class MapContainer, class KeyContainer> +void AppendKeysFromMap(const MapContainer& map_container, + KeyContainer* key_container) { + GOOGLE_CHECK(key_container != nullptr); + for (typename MapContainer::const_iterator it = map_container.begin(); + it != map_container.end(); ++it) { + key_container->push_back(it->first); + } +} + +// A more specialized overload of AppendKeysFromMap to optimize reallocations +// for the common case in which we're appending keys to a vector and hence can +// (and sometimes should) call reserve() first. +// +// (It would be possible to play SFINAE games to call reserve() for any +// container that supports it, but this seems to get us 99% of what we need +// without the complexity of a SFINAE-based solution.) +template <class MapContainer, class KeyType> +void AppendKeysFromMap(const MapContainer& map_container, + std::vector<KeyType>* key_container) { + GOOGLE_CHECK(key_container != nullptr); + // We now have the opportunity to call reserve(). Calling reserve() every + // time is a bad idea for some use cases: libstdc++'s implementation of + // vector<>::reserve() resizes the vector's backing store to exactly the + // given size (unless it's already at least that big). Because of this, + // the use case that involves appending a lot of small maps (total size + // N) one by one to a vector would be O(N^2). But never calling reserve() + // loses the opportunity to improve the use case of adding from a large + // map to an empty vector (this improves performance by up to 33%). A + // number of heuristics are possible; see the discussion in + // cl/34081696. Here we use the simplest one. + if (key_container->empty()) { + key_container->reserve(map_container.size()); + } + for (typename MapContainer::const_iterator it = map_container.begin(); + it != map_container.end(); ++it) { + key_container->push_back(it->first); + } +} + +// Inserts all the values from map_container into value_container, which must +// support push_back(MapContainer::mapped_type). +// +// Note: any initial contents of the value_container are not cleared. +template <class MapContainer, class ValueContainer> +void AppendValuesFromMap(const MapContainer& map_container, + ValueContainer* value_container) { + GOOGLE_CHECK(value_container != nullptr); + for (typename MapContainer::const_iterator it = map_container.begin(); + it != map_container.end(); ++it) { + value_container->push_back(it->second); + } +} + +// A more specialized overload of AppendValuesFromMap to optimize reallocations +// for the common case in which we're appending values to a vector and hence +// can (and sometimes should) call reserve() first. +// +// (It would be possible to play SFINAE games to call reserve() for any +// container that supports it, but this seems to get us 99% of what we need +// without the complexity of a SFINAE-based solution.) +template <class MapContainer, class ValueType> +void AppendValuesFromMap(const MapContainer& map_container, + std::vector<ValueType>* value_container) { + GOOGLE_CHECK(value_container != nullptr); + // See AppendKeysFromMap for why this is done. + if (value_container->empty()) { + value_container->reserve(map_container.size()); + } + for (typename MapContainer::const_iterator it = map_container.begin(); + it != map_container.end(); ++it) { + value_container->push_back(it->second); + } +} + +} // namespace protobuf +} // namespace google + +#endif // GOOGLE_PROTOBUF_STUBS_MAP_UTIL_H__ diff --git a/contrib/libs/protobuf_old/src/google/protobuf/stubs/mathutil.h b/contrib/libs/protobuf_old/src/google/protobuf/stubs/mathutil.h new file mode 100644 index 0000000000..1d16bcedb2 --- /dev/null +++ b/contrib/libs/protobuf_old/src/google/protobuf/stubs/mathutil.h @@ -0,0 +1,162 @@ +// 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_STUBS_MATHUTIL_H_ +#define GOOGLE_PROTOBUF_STUBS_MATHUTIL_H_ + +#include <cmath> +#include <float.h> +#include <limits> + +#include <google/protobuf/stubs/common.h> +#include <google/protobuf/stubs/logging.h> + +namespace google { +namespace protobuf { +namespace internal { + +// Like std::make_unsigned_t except floating point types map to themselves. +template <typename T> +using MakeUnsignedT = + typename std::conditional<std::is_integral<T>::value, std::make_unsigned<T>, + std::common_type<T>>::type::type; + +// Like std::isnan() except a template function that is defined for all numeric +// types. +template <typename T, + typename std::enable_if<std::is_integral<T>::value, int>::type = 0> +bool IsNan(T /*val*/) { + return false; +} + +template <typename T, typename std::enable_if<std::is_floating_point<T>::value, + int>::type = 0> +bool IsNan(T val) { + return std::isnan(val); +} + +template<typename T> +bool AlmostEquals(T a, T b) { + return a == b; +} +template<> +inline bool AlmostEquals(float a, float b) { + return fabs(a - b) < 32 * FLT_EPSILON; +} + +template<> +inline bool AlmostEquals(double a, double b) { + return fabs(a - b) < 32 * DBL_EPSILON; +} + +} // namespace internal + +class MathUtil { + public: + template <typename T> + static T Sign(T value) { + if (value == T(0) || internal::IsNan(value)) { + return value; + } + return value > T(0) ? 1 : -1; + } + + template <typename T> + static bool AlmostEquals(T a, T b) { + return internal::AlmostEquals(a, b); + } + + // Largest of two values. + // Works correctly for special floating point values. + // Note: 0.0 and -0.0 are not differentiated by Max (Max(0.0, -0.0) is -0.0), + // which should be OK because, although they (can) have different + // bit representation, they are observably the same when examined + // with arithmetic and (in)equality operators. + template <typename T> + static T Max(const T x, const T y) { + return internal::IsNan(x) || x > y ? x : y; + } + + // Absolute value of x + // Works correctly for unsigned types and + // for special floating point values. + // Note: 0.0 and -0.0 are not differentiated by Abs (Abs(0.0) is -0.0), + // which should be OK: see the comment for Max above. + template<typename T> + static T Abs(const T x) { + return x > T(0) ? x : -x; + } + + // Absolute value of the difference between two numbers. + // Works correctly for signed types and special floating point values. + template <typename T> + static typename internal::MakeUnsignedT<T> AbsDiff(const T x, const T y) { + // Carries out arithmetic as unsigned to avoid overflow. + typedef typename internal::MakeUnsignedT<T> R; + return x > y ? R(x) - R(y) : R(y) - R(x); + } + + // If two (usually floating point) numbers are within a certain + // fraction of their magnitude or within a certain absolute margin of error. + // This is the same as the following but faster: + // WithinFraction(x, y, fraction) || WithinMargin(x, y, margin) + // E.g. WithinFraction(0.0, 1e-10, 1e-5) is false but + // WithinFractionOrMargin(0.0, 1e-10, 1e-5, 1e-5) is true. + template<typename T> + static bool WithinFractionOrMargin(const T x, const T y, + const T fraction, const T margin); +}; + +template<typename T> +bool MathUtil::WithinFractionOrMargin(const T x, const T y, + const T fraction, const T margin) { + // Not just "0 <= fraction" to fool the compiler for unsigned types. + GOOGLE_DCHECK((T(0) < fraction || T(0) == fraction) && + fraction < T(1) && + margin >= T(0)); + + // Template specialization will convert the if() condition to a constant, + // which will cause the compiler to generate code for either the "if" part + // or the "then" part. In this way we avoid a compiler warning + // about a potential integer overflow in crosstool v12 (gcc 4.3.1). + if (std::numeric_limits<T>::is_integer) { + return x == y; + } else { + if (!std::isfinite(x) || !std::isfinite(y)) { + return false; + } + T relative_margin = static_cast<T>(fraction * Max(Abs(x), Abs(y))); + return AbsDiff(x, y) <= Max(margin, relative_margin); + } +} + +} // namespace protobuf +} // namespace google + +#endif // GOOGLE_PROTOBUF_STUBS_MATHUTIL_H_ diff --git a/contrib/libs/protobuf_old/src/google/protobuf/stubs/mutex.h b/contrib/libs/protobuf_old/src/google/protobuf/stubs/mutex.h new file mode 100644 index 0000000000..c4599913be --- /dev/null +++ b/contrib/libs/protobuf_old/src/google/protobuf/stubs/mutex.h @@ -0,0 +1,218 @@ +// Copyright (c) 2006, Google Inc. +// All rights reserved. +// +// 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_STUBS_MUTEX_H_ +#define GOOGLE_PROTOBUF_STUBS_MUTEX_H_ + +#include <mutex> + +#ifdef GOOGLE_PROTOBUF_SUPPORT_WINDOWS_XP + +#include <windows.h> + +// GetMessage conflicts with GeneratedMessageReflection::GetMessage(). +#ifdef GetMessage +#undef GetMessage +#endif + +#endif + +#include <google/protobuf/stubs/macros.h> + +// Define thread-safety annotations for use below, if we are building with +// Clang. +#if defined(__clang__) && !defined(SWIG) +#define GOOGLE_PROTOBUF_ACQUIRE(...) \ + __attribute__((acquire_capability(__VA_ARGS__))) +#define GOOGLE_PROTOBUF_RELEASE(...) \ + __attribute__((release_capability(__VA_ARGS__))) +#define GOOGLE_PROTOBUF_SCOPED_CAPABILITY __attribute__((scoped_lockable)) +#define GOOGLE_PROTOBUF_CAPABILITY(x) __attribute__((capability(x))) +#else +#define GOOGLE_PROTOBUF_ACQUIRE(...) +#define GOOGLE_PROTOBUF_RELEASE(...) +#define GOOGLE_PROTOBUF_SCOPED_CAPABILITY +#define GOOGLE_PROTOBUF_CAPABILITY(x) +#endif + +#include <google/protobuf/port_def.inc> + +// =================================================================== +// emulates google3/base/mutex.h +namespace google { +namespace protobuf { +namespace internal { + +#define GOOGLE_PROTOBUF_LINKER_INITIALIZED + +#ifdef GOOGLE_PROTOBUF_SUPPORT_WINDOWS_XP + +// This class is a lightweight replacement for std::mutex on Windows platforms. +// std::mutex does not work on Windows XP SP2 with the latest VC++ libraries, +// because it utilizes the Concurrency Runtime that is only supported on Windows +// XP SP3 and above. +class PROTOBUF_EXPORT CriticalSectionLock { + public: + CriticalSectionLock() { InitializeCriticalSection(&critical_section_); } + ~CriticalSectionLock() { DeleteCriticalSection(&critical_section_); } + void lock() { EnterCriticalSection(&critical_section_); } + void unlock() { LeaveCriticalSection(&critical_section_); } + + private: + CRITICAL_SECTION critical_section_; + + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(CriticalSectionLock); +}; + +#endif + +// In MSVC std::mutex does not have a constexpr constructor. +// This wrapper makes the constructor constexpr. +template <typename T> +class CallOnceInitializedMutex { + public: + constexpr CallOnceInitializedMutex() : flag_{}, buf_{} {} + ~CallOnceInitializedMutex() { get().~T(); } + + void lock() { get().lock(); } + void unlock() { get().unlock(); } + + private: + T& get() { + std::call_once(flag_, [&] { ::new (static_cast<void*>(&buf_)) T(); }); + return reinterpret_cast<T&>(buf_); + } + + std::once_flag flag_; + alignas(T) char buf_[sizeof(T)]; +}; + +// Mutex is a natural type to wrap. As both google and other organization have +// specialized mutexes. gRPC also provides an injection mechanism for custom +// mutexes. +class GOOGLE_PROTOBUF_CAPABILITY("mutex") PROTOBUF_EXPORT WrappedMutex { + public: +#if defined(__QNX__) + constexpr WrappedMutex() = default; +#else + constexpr WrappedMutex() {} +#endif + void Lock() GOOGLE_PROTOBUF_ACQUIRE() { mu_.lock(); } + void Unlock() GOOGLE_PROTOBUF_RELEASE() { mu_.unlock(); } + // Crash if this Mutex is not held exclusively by this thread. + // May fail to crash when it should; will never crash when it should not. + void AssertHeld() const {} + + private: +#if defined(GOOGLE_PROTOBUF_SUPPORT_WINDOWS_XP) + CallOnceInitializedMutex<CriticalSectionLock> mu_{}; +#elif defined(_WIN32) + CallOnceInitializedMutex<std::mutex> mu_{}; +#else + std::mutex mu_{}; +#endif +}; + +using Mutex = WrappedMutex; + +// MutexLock(mu) acquires mu when constructed and releases it when destroyed. +class GOOGLE_PROTOBUF_SCOPED_CAPABILITY PROTOBUF_EXPORT MutexLock { + public: + explicit MutexLock(Mutex* mu) GOOGLE_PROTOBUF_ACQUIRE(mu) : mu_(mu) { + this->mu_->Lock(); + } + ~MutexLock() GOOGLE_PROTOBUF_RELEASE() { this->mu_->Unlock(); } + + private: + Mutex *const mu_; + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(MutexLock); +}; + +// TODO(kenton): Implement these? Hard to implement portably. +typedef MutexLock ReaderMutexLock; +typedef MutexLock WriterMutexLock; + +// MutexLockMaybe is like MutexLock, but is a no-op when mu is nullptr. +class PROTOBUF_EXPORT MutexLockMaybe { + public: + explicit MutexLockMaybe(Mutex *mu) : + mu_(mu) { if (this->mu_ != nullptr) { this->mu_->Lock(); } } + ~MutexLockMaybe() { if (this->mu_ != nullptr) { this->mu_->Unlock(); } } + private: + Mutex *const mu_; + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(MutexLockMaybe); +}; + +#if defined(GOOGLE_PROTOBUF_NO_THREADLOCAL) +template<typename T> +class ThreadLocalStorage { + public: + ThreadLocalStorage() { + pthread_key_create(&key_, &ThreadLocalStorage::Delete); + } + ~ThreadLocalStorage() { + pthread_key_delete(key_); + } + T* Get() { + T* result = static_cast<T*>(pthread_getspecific(key_)); + if (result == nullptr) { + result = new T(); + pthread_setspecific(key_, result); + } + return result; + } + private: + static void Delete(void* value) { + delete static_cast<T*>(value); + } + pthread_key_t key_; + + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ThreadLocalStorage); +}; +#endif + +} // namespace internal + +// We made these internal so that they would show up as such in the docs, +// but we don't want to stick "internal::" in front of them everywhere. +using internal::Mutex; +using internal::MutexLock; +using internal::ReaderMutexLock; +using internal::WriterMutexLock; +using internal::MutexLockMaybe; + +} // namespace protobuf +} // namespace google + +#undef GOOGLE_PROTOBUF_ACQUIRE +#undef GOOGLE_PROTOBUF_RELEASE + +#include <google/protobuf/port_undef.inc> + +#endif // GOOGLE_PROTOBUF_STUBS_MUTEX_H_ diff --git a/contrib/libs/protobuf_old/src/google/protobuf/stubs/once.h b/contrib/libs/protobuf_old/src/google/protobuf/stubs/once.h new file mode 100644 index 0000000000..070d36d193 --- /dev/null +++ b/contrib/libs/protobuf_old/src/google/protobuf/stubs/once.h @@ -0,0 +1,55 @@ +// 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_STUBS_ONCE_H__ +#define GOOGLE_PROTOBUF_STUBS_ONCE_H__ + +#include <mutex> +#include <utility> + +#include <google/protobuf/port_def.inc> + +namespace google { +namespace protobuf { +namespace internal { + +using once_flag = std::once_flag; +template <typename... Args> +void call_once(Args&&... args ) { + std::call_once(std::forward<Args>(args)...); +} + +} // namespace internal +} // namespace protobuf +} // namespace google + +#include <google/protobuf/port_undef.inc> + +#endif // GOOGLE_PROTOBUF_STUBS_ONCE_H__ diff --git a/contrib/libs/protobuf_old/src/google/protobuf/stubs/platform_macros.h b/contrib/libs/protobuf_old/src/google/protobuf/stubs/platform_macros.h new file mode 100644 index 0000000000..24799600dc --- /dev/null +++ b/contrib/libs/protobuf_old/src/google/protobuf/stubs/platform_macros.h @@ -0,0 +1,138 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2012 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_PLATFORM_MACROS_H_ +#define GOOGLE_PROTOBUF_PLATFORM_MACROS_H_ + +#define GOOGLE_PROTOBUF_PLATFORM_ERROR \ +#error "Host platform was not detected as supported by protobuf" + +// Processor architecture detection. For more info on what's defined, see: +// http://msdn.microsoft.com/en-us/library/b0084kay.aspx +// http://www.agner.org/optimize/calling_conventions.pdf +// or with gcc, run: "echo | gcc -E -dM -" +#if defined(_M_X64) || defined(__x86_64__) +#define GOOGLE_PROTOBUF_ARCH_X64 1 +#define GOOGLE_PROTOBUF_ARCH_64_BIT 1 +#elif defined(_M_IX86) || defined(__i386__) +#define GOOGLE_PROTOBUF_ARCH_IA32 1 +#define GOOGLE_PROTOBUF_ARCH_32_BIT 1 +#elif defined(__QNX__) +#define GOOGLE_PROTOBUF_ARCH_ARM_QNX 1 +#if defined(__aarch64__) +#define GOOGLE_PROTOBUF_ARCH_64_BIT 1 +#else +#define GOOGLE_PROTOBUF_ARCH_32_BIT 1 +#endif +#elif defined(_M_ARM) || defined(__ARMEL__) +#define GOOGLE_PROTOBUF_ARCH_ARM 1 +#define GOOGLE_PROTOBUF_ARCH_32_BIT 1 +#elif defined(_M_ARM64) +#define GOOGLE_PROTOBUF_ARCH_ARM 1 +#define GOOGLE_PROTOBUF_ARCH_64_BIT 1 +#elif defined(__aarch64__) +#define GOOGLE_PROTOBUF_ARCH_AARCH64 1 +#define GOOGLE_PROTOBUF_ARCH_64_BIT 1 +#elif defined(__mips__) +#if defined(__LP64__) +#define GOOGLE_PROTOBUF_ARCH_MIPS64 1 +#define GOOGLE_PROTOBUF_ARCH_64_BIT 1 +#else +#define GOOGLE_PROTOBUF_ARCH_MIPS 1 +#define GOOGLE_PROTOBUF_ARCH_32_BIT 1 +#endif +#elif defined(__pnacl__) +#define GOOGLE_PROTOBUF_ARCH_32_BIT 1 +#elif defined(sparc) +#define GOOGLE_PROTOBUF_ARCH_SPARC 1 +#if defined(__sparc_v9__) || defined(__sparcv9) || defined(__arch64__) +#define GOOGLE_PROTOBUF_ARCH_64_BIT 1 +#else +#define GOOGLE_PROTOBUF_ARCH_32_BIT 1 +#endif +#elif defined(_POWER) || defined(__powerpc64__) || defined(__PPC64__) +#define GOOGLE_PROTOBUF_ARCH_POWER 1 +#define GOOGLE_PROTOBUF_ARCH_64_BIT 1 +#elif defined(__PPC__) +#define GOOGLE_PROTOBUF_ARCH_PPC 1 +#define GOOGLE_PROTOBUF_ARCH_32_BIT 1 +#elif defined(__GNUC__) +# if (((__GNUC__ == 4) && (__GNUC_MINOR__ >= 7)) || (__GNUC__ > 4)) +// We fallback to the generic Clang/GCC >= 4.7 implementation in atomicops.h +# elif defined(__clang__) +# if !__has_extension(c_atomic) +GOOGLE_PROTOBUF_PLATFORM_ERROR +# endif +// We fallback to the generic Clang/GCC >= 4.7 implementation in atomicops.h +# endif +# if __LP64__ +# define GOOGLE_PROTOBUF_ARCH_64_BIT 1 +# else +# define GOOGLE_PROTOBUF_ARCH_32_BIT 1 +# endif +#else +GOOGLE_PROTOBUF_PLATFORM_ERROR +#endif + +#if defined(__APPLE__) +#define GOOGLE_PROTOBUF_OS_APPLE +#include <Availability.h> +#include <TargetConditionals.h> +#if TARGET_OS_IPHONE +#define GOOGLE_PROTOBUF_OS_IPHONE +#endif +#elif defined(__EMSCRIPTEN__) +#define GOOGLE_PROTOBUF_OS_EMSCRIPTEN +#elif defined(__native_client__) +#define GOOGLE_PROTOBUF_OS_NACL +#elif defined(sun) +#define GOOGLE_PROTOBUF_OS_SOLARIS +#elif defined(_AIX) +#define GOOGLE_PROTOBUF_OS_AIX +#elif defined(__ANDROID__) +#define GOOGLE_PROTOBUF_OS_ANDROID +#endif + +#undef GOOGLE_PROTOBUF_PLATFORM_ERROR + +#if defined(GOOGLE_PROTOBUF_OS_ANDROID) || defined(GOOGLE_PROTOBUF_OS_IPHONE) || defined(__OpenBSD__) +// Android ndk does not support the __thread keyword very well yet. Here +// we use pthread_key_create()/pthread_getspecific()/... methods for +// TLS support on android. +// iOS and OpenBSD also do not support the __thread keyword. +#define GOOGLE_PROTOBUF_NO_THREADLOCAL +#endif + +#if defined(__MAC_OS_X_VERSION_MIN_REQUIRED) && __MAC_OS_X_VERSION_MIN_REQUIRED < 1070 +// __thread keyword requires at least 10.7 +#define GOOGLE_PROTOBUF_NO_THREADLOCAL +#endif + +#endif // GOOGLE_PROTOBUF_PLATFORM_MACROS_H_ diff --git a/contrib/libs/protobuf_old/src/google/protobuf/stubs/port.h b/contrib/libs/protobuf_old/src/google/protobuf/stubs/port.h new file mode 100644 index 0000000000..c5159b19fc --- /dev/null +++ b/contrib/libs/protobuf_old/src/google/protobuf/stubs/port.h @@ -0,0 +1,419 @@ +// 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_STUBS_PORT_H_ +#define GOOGLE_PROTOBUF_STUBS_PORT_H_ + +#include <util/generic/string.h> +#include <util/stream/input.h> +#include <util/stream/output.h> +#include <util/system/types.h> +#include <assert.h> +#include <cstdint> +#include <stdlib.h> +#include <cstddef> +#include <string> +#include <string.h> + +#include <google/protobuf/stubs/platform_macros.h> + +#include <google/protobuf/port_def.inc> + +#undef PROTOBUF_LITTLE_ENDIAN +#ifdef _WIN32 + // Assuming windows is always little-endian. + // TODO(xiaofeng): The PROTOBUF_LITTLE_ENDIAN is not only used for + // optimization but also for correctness. We should define an + // different macro to test the big-endian code path in coded_stream. + #if !defined(PROTOBUF_DISABLE_LITTLE_ENDIAN_OPT_FOR_TEST) + #define PROTOBUF_LITTLE_ENDIAN 1 + #endif +#if defined(_MSC_VER) && _MSC_VER >= 1300 && !defined(__INTEL_COMPILER) +// If MSVC has "/RTCc" set, it will complain about truncating casts at +// runtime. This file contains some intentional truncating casts. +#pragma runtime_checks("c", off) +#endif +#else +#ifdef __APPLE__ +#include <machine/endian.h> // __BYTE_ORDER +#elif defined(__FreeBSD__) +#include <sys/endian.h> // __BYTE_ORDER +#elif (defined(sun) || defined(__sun)) && (defined(__SVR4) || defined(__svr4__)) +#error #include <sys/isa_defs.h> // __BYTE_ORDER +#elif defined(_AIX) || defined(__TOS_AIX__) +#include <sys/machine.h> // BYTE_ORDER +#else +#if !defined(__QNX__) +#include <endian.h> // __BYTE_ORDER +#endif +#endif +#if ((defined(__LITTLE_ENDIAN__) && !defined(__BIG_ENDIAN__)) || \ + (defined(__BYTE_ORDER) && __BYTE_ORDER == __LITTLE_ENDIAN) || \ + (defined(BYTE_ORDER) && BYTE_ORDER == LITTLE_ENDIAN)) && \ + !defined(PROTOBUF_DISABLE_LITTLE_ENDIAN_OPT_FOR_TEST) +#define PROTOBUF_LITTLE_ENDIAN 1 +#endif +#endif + +// These #includes are for the byte swap functions declared later on. +#ifdef _MSC_VER +#include <stdlib.h> // NOLINT(build/include) +#include <intrin.h> +#elif defined(__APPLE__) +#include <libkern/OSByteOrder.h> +#elif defined(__linux__) || defined(__ANDROID__) || defined(__CYGWIN__) +#include <byteswap.h> // IWYU pragma: export +#endif + +// Legacy: some users reference these (internal-only) macros even though we +// don't need them any more. +#if defined(_MSC_VER) && defined(PROTOBUF_USE_DLLS) + #ifdef LIBPROTOBUF_EXPORTS + #define LIBPROTOBUF_EXPORT __declspec(dllexport) + #else + #define LIBPROTOBUF_EXPORT __declspec(dllimport) + #endif + #ifdef LIBPROTOC_EXPORTS + #define LIBPROTOC_EXPORT __declspec(dllexport) + #else + #define LIBPROTOC_EXPORT __declspec(dllimport) + #endif +#else + #define LIBPROTOBUF_EXPORT + #define LIBPROTOC_EXPORT +#endif + +#define PROTOBUF_RUNTIME_DEPRECATED(message) PROTOBUF_DEPRECATED_MSG(message) +#define GOOGLE_PROTOBUF_RUNTIME_DEPRECATED(message) \ + PROTOBUF_DEPRECATED_MSG(message) + +// =================================================================== +// from google3/base/port.h + +#if (defined(__GXX_EXPERIMENTAL_CXX0X__) || __cplusplus >= 201103L || \ + (defined(_MSC_VER) && _MSC_VER >= 1900)) +// Define this to 1 if the code is compiled in C++11 mode; leave it +// undefined otherwise. Do NOT define it to 0 -- that causes +// '#ifdef LANG_CXX11' to behave differently from '#if LANG_CXX11'. +#define LANG_CXX11 1 +#else +#error "Protobuf requires at least C++11." +#endif + +using TProtoStringType = TString; + +namespace google { +namespace protobuf { + +using ConstStringParam = const TProtoStringType &; + +typedef unsigned int uint; + +typedef int8_t int8; +typedef int16_t int16; +typedef arc_i32 int32; +typedef arc_i64 int64; + +typedef uint8_t uint8; +typedef uint16_t uint16; +typedef arc_ui32 uint32; +typedef arc_ui64 uint64; + +static const int32 kint32max = 0x7FFFFFFF; +static const int32 kint32min = -kint32max - 1; +static const int64 kint64max = arc_i64{0x7FFFFFFFFFFFFFFF}; +static const int64 kint64min = -kint64max - 1; +static const uint32 kuint32max = 0xFFFFFFFFu; +static const uint64 kuint64max = arc_ui64{0xFFFFFFFFFFFFFFFFu}; + +#if defined(ADDRESS_SANITIZER) || defined(THREAD_SANITIZER) ||\ + defined(MEMORY_SANITIZER) + +#ifdef __cplusplus +extern "C" { +#endif // __cplusplus +uint16_t __sanitizer_unaligned_load16(const void *p); +arc_ui32 __sanitizer_unaligned_load32(const void *p); +arc_ui64 __sanitizer_unaligned_load64(const void *p); +void __sanitizer_unaligned_store16(void *p, uint16_t v); +void __sanitizer_unaligned_store32(void *p, arc_ui32 v); +void __sanitizer_unaligned_store64(void *p, arc_ui64 v); +#ifdef __cplusplus +} // extern "C" +#endif // __cplusplus + +inline uint16 GOOGLE_UNALIGNED_LOAD16(const void *p) { + return __sanitizer_unaligned_load16(p); +} + +inline uint32 GOOGLE_UNALIGNED_LOAD32(const void *p) { + return __sanitizer_unaligned_load32(p); +} + +inline uint64 GOOGLE_UNALIGNED_LOAD64(const void *p) { + return __sanitizer_unaligned_load64(p); +} + +inline void GOOGLE_UNALIGNED_STORE16(void *p, uint16 v) { + __sanitizer_unaligned_store16(p, v); +} + +inline void GOOGLE_UNALIGNED_STORE32(void *p, uint32 v) { + __sanitizer_unaligned_store32(p, v); +} + +inline void GOOGLE_UNALIGNED_STORE64(void *p, uint64 v) { + __sanitizer_unaligned_store64(p, v); +} + +#elif defined(GOOGLE_PROTOBUF_USE_UNALIGNED) && GOOGLE_PROTOBUF_USE_UNALIGNED + +#define GOOGLE_UNALIGNED_LOAD16(_p) (*reinterpret_cast<const uint16 *>(_p)) +#define GOOGLE_UNALIGNED_LOAD32(_p) (*reinterpret_cast<const uint32 *>(_p)) +#define GOOGLE_UNALIGNED_LOAD64(_p) (*reinterpret_cast<const uint64 *>(_p)) + +#define GOOGLE_UNALIGNED_STORE16(_p, _val) (*reinterpret_cast<uint16 *>(_p) = (_val)) +#define GOOGLE_UNALIGNED_STORE32(_p, _val) (*reinterpret_cast<uint32 *>(_p) = (_val)) +#define GOOGLE_UNALIGNED_STORE64(_p, _val) (*reinterpret_cast<uint64 *>(_p) = (_val)) + +#else +inline uint16 GOOGLE_UNALIGNED_LOAD16(const void *p) { + uint16 t; + memcpy(&t, p, sizeof t); + return t; +} + +inline uint32 GOOGLE_UNALIGNED_LOAD32(const void *p) { + uint32 t; + memcpy(&t, p, sizeof t); + return t; +} + +inline uint64 GOOGLE_UNALIGNED_LOAD64(const void *p) { + uint64 t; + memcpy(&t, p, sizeof t); + return t; +} + +inline void GOOGLE_UNALIGNED_STORE16(void *p, uint16 v) { + memcpy(p, &v, sizeof v); +} + +inline void GOOGLE_UNALIGNED_STORE32(void *p, uint32 v) { + memcpy(p, &v, sizeof v); +} + +inline void GOOGLE_UNALIGNED_STORE64(void *p, uint64 v) { + memcpy(p, &v, sizeof v); +} +#endif + +#if defined(GOOGLE_PROTOBUF_OS_NACL) \ + || (defined(__ANDROID__) && defined(__clang__) \ + && (__clang_major__ == 3 && __clang_minor__ == 8) \ + && (__clang_patchlevel__ < 275480)) +# define GOOGLE_PROTOBUF_USE_PORTABLE_LOG2 +#endif + +// The following guarantees declaration of the byte swap functions. +#ifdef _MSC_VER +#define bswap_16(x) _byteswap_ushort(x) +#define bswap_32(x) _byteswap_ulong(x) +#define bswap_64(x) _byteswap_uint64(x) + +#elif defined(__APPLE__) +// Mac OS X / Darwin features +#define bswap_16(x) OSSwapInt16(x) +#define bswap_32(x) OSSwapInt32(x) +#define bswap_64(x) OSSwapInt64(x) + +#elif !defined(__linux__) && !defined(__ANDROID__) && !defined(__CYGWIN__) + +#ifndef bswap_16 +static inline uint16 bswap_16(uint16 x) { + return static_cast<uint16>(((x & 0xFF) << 8) | ((x & 0xFF00) >> 8)); +} +#define bswap_16(x) bswap_16(x) +#endif + +#ifndef bswap_32 +static inline uint32 bswap_32(uint32 x) { + return (((x & 0xFF) << 24) | + ((x & 0xFF00) << 8) | + ((x & 0xFF0000) >> 8) | + ((x & 0xFF000000) >> 24)); +} +#define bswap_32(x) bswap_32(x) +#endif + +#ifndef bswap_64 +static inline uint64 bswap_64(uint64 x) { + return (((x & arc_ui64{0xFFu}) << 56) | ((x & arc_ui64{0xFF00u}) << 40) | + ((x & arc_ui64{0xFF0000u}) << 24) | + ((x & arc_ui64{0xFF000000u}) << 8) | + ((x & arc_ui64{0xFF00000000u}) >> 8) | + ((x & arc_ui64{0xFF0000000000u}) >> 24) | + ((x & arc_ui64{0xFF000000000000u}) >> 40) | + ((x & arc_ui64{0xFF00000000000000u}) >> 56)); +} +#define bswap_64(x) bswap_64(x) +#endif + +#endif + +// =================================================================== +// from google3/util/bits/bits.h + +class Bits { + public: + static uint32 Log2FloorNonZero(uint32 n) { +#if defined(__GNUC__) + return 31 ^ static_cast<uint32>(__builtin_clz(n)); +#elif defined(_MSC_VER) + unsigned long where; + _BitScanReverse(&where, n); + return where; +#else + return Log2FloorNonZero_Portable(n); +#endif + } + + static uint32 Log2FloorNonZero64(uint64 n) { + // Older versions of clang run into an instruction-selection failure when + // it encounters __builtin_clzll: + // https://bugs.chromium.org/p/nativeclient/issues/detail?id=4395 + // This includes arm-nacl-clang and clang in older Android NDK versions. + // To work around this, when we build with those we use the portable + // implementation instead. +#if defined(__GNUC__) && !defined(GOOGLE_PROTOBUF_USE_PORTABLE_LOG2) + return 63 ^ static_cast<uint32>(__builtin_clzll(n)); +#elif defined(_MSC_VER) && defined(_M_X64) + unsigned long where; + _BitScanReverse64(&where, n); + return where; +#else + return Log2FloorNonZero64_Portable(n); +#endif + } + private: + static int Log2FloorNonZero_Portable(uint32 n) { + if (n == 0) + return -1; + int log = 0; + uint32 value = n; + for (int i = 4; i >= 0; --i) { + int shift = (1 << i); + uint32 x = value >> shift; + if (x != 0) { + value = x; + log += shift; + } + } + assert(value == 1); + return log; + } + + static int Log2FloorNonZero64_Portable(uint64 n) { + const uint32 topbits = static_cast<uint32>(n >> 32); + if (topbits == 0) { + // Top bits are zero, so scan in bottom bits + return static_cast<int>(Log2FloorNonZero(static_cast<uint32>(n))); + } else { + return 32 + static_cast<int>(Log2FloorNonZero(topbits)); + } + } +}; + +// =================================================================== +// from google3/util/endian/endian.h +PROTOBUF_EXPORT uint32 ghtonl(uint32 x); + +class BigEndian { + public: +#ifdef PROTOBUF_LITTLE_ENDIAN + + static uint16 FromHost16(uint16 x) { return bswap_16(x); } + static uint16 ToHost16(uint16 x) { return bswap_16(x); } + + static uint32 FromHost32(uint32 x) { return bswap_32(x); } + static uint32 ToHost32(uint32 x) { return bswap_32(x); } + + static uint64 FromHost64(uint64 x) { return bswap_64(x); } + static uint64 ToHost64(uint64 x) { return bswap_64(x); } + + static bool IsLittleEndian() { return true; } + +#else + + static uint16 FromHost16(uint16 x) { return x; } + static uint16 ToHost16(uint16 x) { return x; } + + static uint32 FromHost32(uint32 x) { return x; } + static uint32 ToHost32(uint32 x) { return x; } + + static uint64 FromHost64(uint64 x) { return x; } + static uint64 ToHost64(uint64 x) { return x; } + + static bool IsLittleEndian() { return false; } + +#endif /* ENDIAN */ + + // Functions to do unaligned loads and stores in big-endian order. + static uint16 Load16(const void *p) { + return ToHost16(GOOGLE_UNALIGNED_LOAD16(p)); + } + + static void Store16(void *p, uint16 v) { + GOOGLE_UNALIGNED_STORE16(p, FromHost16(v)); + } + + static uint32 Load32(const void *p) { + return ToHost32(GOOGLE_UNALIGNED_LOAD32(p)); + } + + static void Store32(void *p, uint32 v) { + GOOGLE_UNALIGNED_STORE32(p, FromHost32(v)); + } + + static uint64 Load64(const void *p) { + return ToHost64(GOOGLE_UNALIGNED_LOAD64(p)); + } + + static void Store64(void *p, uint64 v) { + GOOGLE_UNALIGNED_STORE64(p, FromHost64(v)); + } +}; + +} // namespace protobuf +} // namespace google + +#include <google/protobuf/port_undef.inc> + +#endif // GOOGLE_PROTOBUF_STUBS_PORT_H_ diff --git a/contrib/libs/protobuf_old/src/google/protobuf/stubs/status.cc b/contrib/libs/protobuf_old/src/google/protobuf/stubs/status.cc new file mode 100644 index 0000000000..bb2b119aa4 --- /dev/null +++ b/contrib/libs/protobuf_old/src/google/protobuf/stubs/status.cc @@ -0,0 +1,262 @@ +// 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 <google/protobuf/stubs/status.h> + +#include <ostream> +#include <stdio.h> +#include <string> +#include <utility> + +namespace google { +namespace protobuf { +namespace util { +namespace status_internal { +namespace { + +inline TProtoStringType StatusCodeToString(StatusCode code) { + switch (code) { + case StatusCode::kOk: + return "OK"; + case StatusCode::kCancelled: + return "CANCELLED"; + case StatusCode::kUnknown: + return "UNKNOWN"; + case StatusCode::kInvalidArgument: + return "INVALID_ARGUMENT"; + case StatusCode::kDeadlineExceeded: + return "DEADLINE_EXCEEDED"; + case StatusCode::kNotFound: + return "NOT_FOUND"; + case StatusCode::kAlreadyExists: + return "ALREADY_EXISTS"; + case StatusCode::kPermissionDenied: + return "PERMISSION_DENIED"; + case StatusCode::kUnauthenticated: + return "UNAUTHENTICATED"; + case StatusCode::kResourceExhausted: + return "RESOURCE_EXHAUSTED"; + case StatusCode::kFailedPrecondition: + return "FAILED_PRECONDITION"; + case StatusCode::kAborted: + return "ABORTED"; + case StatusCode::kOutOfRange: + return "OUT_OF_RANGE"; + case StatusCode::kUnimplemented: + return "UNIMPLEMENTED"; + case StatusCode::kInternal: + return "INTERNAL"; + case StatusCode::kUnavailable: + return "UNAVAILABLE"; + case StatusCode::kDataLoss: + return "DATA_LOSS"; + } + + // No default clause, clang will abort if a code is missing from + // above switch. + return "UNKNOWN"; +} + +} // namespace + +Status::Status() : error_code_(StatusCode::kOk) {} + +Status::Status(StatusCode error_code, StringPiece error_message) + : error_code_(error_code) { + if (error_code != StatusCode::kOk) { + error_message_ = error_message.ToString(); + } +} + +Status::Status(const Status& other) + : error_code_(other.error_code_), error_message_(other.error_message_) { +} + +Status& Status::operator=(const Status& other) { + error_code_ = other.error_code_; + error_message_ = other.error_message_; + return *this; +} + +bool Status::operator==(const Status& x) const { + return error_code_ == x.error_code_ && + error_message_ == x.error_message_; +} + +TProtoStringType Status::ToString() const { + if (error_code_ == StatusCode::kOk) { + return "OK"; + } else { + if (error_message_.empty()) { + return StatusCodeToString(error_code_); + } else { + return StatusCodeToString(error_code_) + ":" + error_message_; + } + } +} + +Status OkStatus() { return Status(); } + +std::ostream& operator<<(std::ostream& os, const Status& x) { + os << x.ToString(); + return os; +} + +bool IsAborted(const Status& status) { + return status.code() == StatusCode::kAborted; +} + +bool IsAlreadyExists(const Status& status) { + return status.code() == StatusCode::kAlreadyExists; +} + +bool IsCancelled(const Status& status) { + return status.code() == StatusCode::kCancelled; +} + +bool IsDataLoss(const Status& status) { + return status.code() == StatusCode::kDataLoss; +} + +bool IsDeadlineExceeded(const Status& status) { + return status.code() == StatusCode::kDeadlineExceeded; +} + +bool IsFailedPrecondition(const Status& status) { + return status.code() == StatusCode::kFailedPrecondition; +} + +bool IsInternal(const Status& status) { + return status.code() == StatusCode::kInternal; +} + +bool IsInvalidArgument(const Status& status) { + return status.code() == StatusCode::kInvalidArgument; +} + +bool IsNotFound(const Status& status) { + return status.code() == StatusCode::kNotFound; +} + +bool IsOutOfRange(const Status& status) { + return status.code() == StatusCode::kOutOfRange; +} + +bool IsPermissionDenied(const Status& status) { + return status.code() == StatusCode::kPermissionDenied; +} + +bool IsResourceExhausted(const Status& status) { + return status.code() == StatusCode::kResourceExhausted; +} + +bool IsUnauthenticated(const Status& status) { + return status.code() == StatusCode::kUnauthenticated; +} + +bool IsUnavailable(const Status& status) { + return status.code() == StatusCode::kUnavailable; +} + +bool IsUnimplemented(const Status& status) { + return status.code() == StatusCode::kUnimplemented; +} + +bool IsUnknown(const Status& status) { + return status.code() == StatusCode::kUnknown; +} + +Status AbortedError(StringPiece message) { + return Status(StatusCode::kAborted, message); +} + +Status AlreadyExistsError(StringPiece message) { + return Status(StatusCode::kAlreadyExists, message); +} + +Status CancelledError(StringPiece message) { + return Status(StatusCode::kCancelled, message); +} + +Status DataLossError(StringPiece message) { + return Status(StatusCode::kDataLoss, message); +} + +Status DeadlineExceededError(StringPiece message) { + return Status(StatusCode::kDeadlineExceeded, message); +} + +Status FailedPreconditionError(StringPiece message) { + return Status(StatusCode::kFailedPrecondition, message); +} + +Status InternalError(StringPiece message) { + return Status(StatusCode::kInternal, message); +} + +Status InvalidArgumentError(StringPiece message) { + return Status(StatusCode::kInvalidArgument, message); +} + +Status NotFoundError(StringPiece message) { + return Status(StatusCode::kNotFound, message); +} + +Status OutOfRangeError(StringPiece message) { + return Status(StatusCode::kOutOfRange, message); +} + +Status PermissionDeniedError(StringPiece message) { + return Status(StatusCode::kPermissionDenied, message); +} + +Status ResourceExhaustedError(StringPiece message) { + return Status(StatusCode::kResourceExhausted, message); +} + +Status UnauthenticatedError(StringPiece message) { + return Status(StatusCode::kUnauthenticated, message); +} + +Status UnavailableError(StringPiece message) { + return Status(StatusCode::kUnavailable, message); +} + +Status UnimplementedError(StringPiece message) { + return Status(StatusCode::kUnimplemented, message); +} + +Status UnknownError(StringPiece message) { + return Status(StatusCode::kUnknown, message); +} + +} // namespace status_internal +} // namespace util +} // namespace protobuf +} // namespace google diff --git a/contrib/libs/protobuf_old/src/google/protobuf/stubs/status.h b/contrib/libs/protobuf_old/src/google/protobuf/stubs/status.h new file mode 100644 index 0000000000..79821807a5 --- /dev/null +++ b/contrib/libs/protobuf_old/src/google/protobuf/stubs/status.h @@ -0,0 +1,196 @@ +// 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_STUBS_STATUS_H_ +#define GOOGLE_PROTOBUF_STUBS_STATUS_H_ + +#include <string> + +#include <google/protobuf/stubs/stringpiece.h> + +#include <google/protobuf/port_def.inc> + +namespace google { +namespace protobuf { +namespace util { +namespace status_internal { + +// These values must match error codes defined in google/rpc/code.proto. +enum class StatusCode : int { + kOk = 0, + kCancelled = 1, + kUnknown = 2, + kInvalidArgument = 3, + kDeadlineExceeded = 4, + kNotFound = 5, + kAlreadyExists = 6, + kPermissionDenied = 7, + kUnauthenticated = 16, + kResourceExhausted = 8, + kFailedPrecondition = 9, + kAborted = 10, + kOutOfRange = 11, + kUnimplemented = 12, + kInternal = 13, + kUnavailable = 14, + kDataLoss = 15, +}; + +class PROTOBUF_EXPORT Status { + public: + // Creates a "successful" status. + Status(); + + // Create a status in the canonical error space with the specified + // code, and error message. If "code == 0", error_message is + // ignored and a Status object identical to Status::kOk is + // constructed. + Status(StatusCode error_code, StringPiece error_message); + Status(const Status&); + Status& operator=(const Status& x); + ~Status() {} + + // Accessor + bool ok() const { return error_code_ == StatusCode::kOk; } + StatusCode code() const { return error_code_; } + StringPiece message() const { + return error_message_; + } + + bool operator==(const Status& x) const; + bool operator!=(const Status& x) const { + return !operator==(x); + } + + // Return a combination of the error code name and message. + TProtoStringType ToString() const; + + private: + StatusCode error_code_; + TProtoStringType error_message_; +}; + +// Returns an OK status, equivalent to a default constructed instance. Prefer +// usage of `OkStatus()` when constructing such an OK status. +PROTOBUF_EXPORT Status OkStatus(); + +// Prints a human-readable representation of 'x' to 'os'. +PROTOBUF_EXPORT std::ostream& operator<<(std::ostream& os, const Status& x); + +// These convenience functions return `true` if a given status matches the +// `StatusCode` error code of its associated function. +PROTOBUF_EXPORT bool IsAborted(const Status& status); +PROTOBUF_EXPORT bool IsAlreadyExists(const Status& status); +PROTOBUF_EXPORT bool IsCancelled(const Status& status); +PROTOBUF_EXPORT bool IsDataLoss(const Status& status); +PROTOBUF_EXPORT bool IsDeadlineExceeded(const Status& status); +PROTOBUF_EXPORT bool IsFailedPrecondition(const Status& status); +PROTOBUF_EXPORT bool IsInternal(const Status& status); +PROTOBUF_EXPORT bool IsInvalidArgument(const Status& status); +PROTOBUF_EXPORT bool IsNotFound(const Status& status); +PROTOBUF_EXPORT bool IsOutOfRange(const Status& status); +PROTOBUF_EXPORT bool IsPermissionDenied(const Status& status); +PROTOBUF_EXPORT bool IsResourceExhausted(const Status& status); +PROTOBUF_EXPORT bool IsUnauthenticated(const Status& status); +PROTOBUF_EXPORT bool IsUnavailable(const Status& status); +PROTOBUF_EXPORT bool IsUnimplemented(const Status& status); +PROTOBUF_EXPORT bool IsUnknown(const Status& status); + +// These convenience functions create an `Status` object with an error code as +// indicated by the associated function name, using the error message passed in +// `message`. +// +// These functions are intentionally named `*Error` rather than `*Status` to +// match the names from Abseil: +// https://github.com/abseil/abseil-cpp/blob/2e9532cc6c701a8323d0cffb468999ab804095ab/absl/status/status.h#L716 +PROTOBUF_EXPORT Status AbortedError(StringPiece message); +PROTOBUF_EXPORT Status AlreadyExistsError(StringPiece message); +PROTOBUF_EXPORT Status CancelledError(StringPiece message); +PROTOBUF_EXPORT Status DataLossError(StringPiece message); +PROTOBUF_EXPORT Status DeadlineExceededError(StringPiece message); +PROTOBUF_EXPORT Status FailedPreconditionError(StringPiece message); +PROTOBUF_EXPORT Status InternalError(StringPiece message); +PROTOBUF_EXPORT Status InvalidArgumentError(StringPiece message); +PROTOBUF_EXPORT Status NotFoundError(StringPiece message); +PROTOBUF_EXPORT Status OutOfRangeError(StringPiece message); +PROTOBUF_EXPORT Status PermissionDeniedError(StringPiece message); +PROTOBUF_EXPORT Status ResourceExhaustedError(StringPiece message); +PROTOBUF_EXPORT Status UnauthenticatedError(StringPiece message); +PROTOBUF_EXPORT Status UnavailableError(StringPiece message); +PROTOBUF_EXPORT Status UnimplementedError(StringPiece message); +PROTOBUF_EXPORT Status UnknownError(StringPiece message); + +} // namespace status_internal + +using ::google::protobuf::util::status_internal::Status; +using ::google::protobuf::util::status_internal::StatusCode; + +using ::google::protobuf::util::status_internal::IsAborted; +using ::google::protobuf::util::status_internal::IsAlreadyExists; +using ::google::protobuf::util::status_internal::IsCancelled; +using ::google::protobuf::util::status_internal::IsDataLoss; +using ::google::protobuf::util::status_internal::IsDeadlineExceeded; +using ::google::protobuf::util::status_internal::IsFailedPrecondition; +using ::google::protobuf::util::status_internal::IsInternal; +using ::google::protobuf::util::status_internal::IsInvalidArgument; +using ::google::protobuf::util::status_internal::IsNotFound; +using ::google::protobuf::util::status_internal::IsOutOfRange; +using ::google::protobuf::util::status_internal::IsPermissionDenied; +using ::google::protobuf::util::status_internal::IsResourceExhausted; +using ::google::protobuf::util::status_internal::IsUnauthenticated; +using ::google::protobuf::util::status_internal::IsUnavailable; +using ::google::protobuf::util::status_internal::IsUnimplemented; +using ::google::protobuf::util::status_internal::IsUnknown; + +using ::google::protobuf::util::status_internal::AbortedError; +using ::google::protobuf::util::status_internal::AlreadyExistsError; +using ::google::protobuf::util::status_internal::CancelledError; +using ::google::protobuf::util::status_internal::DataLossError; +using ::google::protobuf::util::status_internal::DeadlineExceededError; +using ::google::protobuf::util::status_internal::FailedPreconditionError; +using ::google::protobuf::util::status_internal::InternalError; +using ::google::protobuf::util::status_internal::InvalidArgumentError; +using ::google::protobuf::util::status_internal::NotFoundError; +using ::google::protobuf::util::status_internal::OkStatus; +using ::google::protobuf::util::status_internal::OutOfRangeError; +using ::google::protobuf::util::status_internal::PermissionDeniedError; +using ::google::protobuf::util::status_internal::ResourceExhaustedError; +using ::google::protobuf::util::status_internal::UnauthenticatedError; +using ::google::protobuf::util::status_internal::UnavailableError; +using ::google::protobuf::util::status_internal::UnimplementedError; +using ::google::protobuf::util::status_internal::UnknownError; + +} // namespace util +} // namespace protobuf +} // namespace google + +#include <google/protobuf/port_undef.inc> + +#endif // GOOGLE_PROTOBUF_STUBS_STATUS_H_ diff --git a/contrib/libs/protobuf_old/src/google/protobuf/stubs/status_macros.h b/contrib/libs/protobuf_old/src/google/protobuf/stubs/status_macros.h new file mode 100644 index 0000000000..407ff4c280 --- /dev/null +++ b/contrib/libs/protobuf_old/src/google/protobuf/stubs/status_macros.h @@ -0,0 +1,89 @@ +// 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. + +// From: util/task/contrib/status_macros/status_macros.h + +#ifndef GOOGLE_PROTOBUF_STUBS_STATUS_MACROS_H_ +#define GOOGLE_PROTOBUF_STUBS_STATUS_MACROS_H_ + +#include <google/protobuf/stubs/common.h> +#include <google/protobuf/stubs/status.h> +#include <google/protobuf/stubs/statusor.h> + +namespace google { +namespace protobuf { +namespace util { + +// Run a command that returns a util::Status. If the called code returns an +// error status, return that status up out of this method too. +// +// Example: +// RETURN_IF_ERROR(DoThings(4)); +#define RETURN_IF_ERROR(expr) \ + do { \ + /* Using _status below to avoid capture problems if expr is "status". */ \ + const PROTOBUF_NAMESPACE_ID::util::Status _status = (expr); \ + if (PROTOBUF_PREDICT_FALSE(!_status.ok())) return _status; \ + } while (0) + +// Internal helper for concatenating macro values. +#define STATUS_MACROS_CONCAT_NAME_INNER(x, y) x##y +#define STATUS_MACROS_CONCAT_NAME(x, y) STATUS_MACROS_CONCAT_NAME_INNER(x, y) + +template<typename T> +Status DoAssignOrReturn(T& lhs, StatusOr<T> result) { + if (result.ok()) { + lhs = result.value(); + } + return result.status(); +} + +#define ASSIGN_OR_RETURN_IMPL(status, lhs, rexpr) \ + Status status = DoAssignOrReturn(lhs, (rexpr)); \ + if (PROTOBUF_PREDICT_FALSE(!status.ok())) return status; + +// Executes an expression that returns a util::StatusOr, extracting its value +// into the variable defined by lhs (or returning on error). +// +// Example: Assigning to an existing value +// ValueType value; +// ASSIGN_OR_RETURN(value, MaybeGetValue(arg)); +// +// WARNING: ASSIGN_OR_RETURN expands into multiple statements; it cannot be used +// in a single statement (e.g. as the body of an if statement without {})! +#define ASSIGN_OR_RETURN(lhs, rexpr) \ + ASSIGN_OR_RETURN_IMPL( \ + STATUS_MACROS_CONCAT_NAME(_status_or_value, __COUNTER__), lhs, rexpr); + +} // namespace util +} // namespace protobuf +} // namespace google + +#endif // GOOGLE_PROTOBUF_STUBS_STATUS_H_ diff --git a/contrib/libs/protobuf_old/src/google/protobuf/stubs/statusor.cc b/contrib/libs/protobuf_old/src/google/protobuf/stubs/statusor.cc new file mode 100644 index 0000000000..9c0a1782a8 --- /dev/null +++ b/contrib/libs/protobuf_old/src/google/protobuf/stubs/statusor.cc @@ -0,0 +1,48 @@ +// 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 <google/protobuf/stubs/statusor.h> + +#include <google/protobuf/stubs/logging.h> + +namespace google { +namespace protobuf { +namespace util { +namespace statusor_internal { + +void StatusOrHelper::Crash(const Status& status) { + GOOGLE_LOG(FATAL) << "Attempting to fetch value instead of handling error " + << status.ToString(); +} + +} // namespace statusor_internal +} // namespace util +} // namespace protobuf +} // namespace google diff --git a/contrib/libs/protobuf_old/src/google/protobuf/stubs/statusor.h b/contrib/libs/protobuf_old/src/google/protobuf/stubs/statusor.h new file mode 100644 index 0000000000..20e603ea04 --- /dev/null +++ b/contrib/libs/protobuf_old/src/google/protobuf/stubs/statusor.h @@ -0,0 +1,253 @@ +// 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. + +// StatusOr<T> is the union of a Status object and a T +// object. StatusOr models the concept of an object that is either a +// usable value, or an error Status explaining why such a value is +// not present. To this end, StatusOr<T> does not allow its Status +// value to be OkStatus(). Further, StatusOr<T*> does not allow the +// contained pointer to be nullptr. +// +// The primary use-case for StatusOr<T> is as the return value of a +// function which may fail. +// +// Example client usage for a StatusOr<T>, where T is not a pointer: +// +// StatusOr<float> result = DoBigCalculationThatCouldFail(); +// if (result.ok()) { +// float answer = result.value(); +// printf("Big calculation yielded: %f", answer); +// } else { +// LOG(ERROR) << result.status(); +// } +// +// Example client usage for a StatusOr<T*>: +// +// StatusOr<Foo*> result = FooFactory::MakeNewFoo(arg); +// if (result.ok()) { +// std::unique_ptr<Foo> foo(result.value()); +// foo->DoSomethingCool(); +// } else { +// LOG(ERROR) << result.status(); +// } +// +// Example factory implementation returning StatusOr<T*>: +// +// StatusOr<Foo*> FooFactory::MakeNewFoo(int arg) { +// if (arg <= 0) { +// return InvalidArgumentError("Arg must be positive"); +// } else { +// return new Foo(arg); +// } +// } +// + +#ifndef GOOGLE_PROTOBUF_STUBS_STATUSOR_H_ +#define GOOGLE_PROTOBUF_STUBS_STATUSOR_H_ + +#include <new> +#include <string> +#include <utility> + +#include <google/protobuf/stubs/status.h> + +#include <google/protobuf/port_def.inc> + +namespace google { +namespace protobuf { +namespace util { +namespace statusor_internal { + +template<typename T> +class StatusOr { + template<typename U> friend class StatusOr; + + public: + using value_type = T; + + // Construct a new StatusOr with Status::UNKNOWN status. + // Construct a new StatusOr with UnknownError() status. + explicit StatusOr(); + + // Construct a new StatusOr with the given non-ok status. After calling + // this constructor, calls to value() will CHECK-fail. + // + // NOTE: Not explicit - we want to use StatusOr<T> as a return + // value, so it is convenient and sensible to be able to do 'return + // Status()' when the return type is StatusOr<T>. + // + // REQUIRES: status != OkStatus(). This requirement is DCHECKed. + // In optimized builds, passing OkStatus() here will have the effect + // of passing PosixErrorSpace::EINVAL as a fallback. + StatusOr(const Status& status); // NOLINT + + // Construct a new StatusOr with the given value. If T is a plain pointer, + // value must not be nullptr. After calling this constructor, calls to + // value() will succeed, and calls to status() will return OK. + // + // NOTE: Not explicit - we want to use StatusOr<T> as a return type + // so it is convenient and sensible to be able to do 'return T()' + // when when the return type is StatusOr<T>. + // + // REQUIRES: if T is a plain pointer, value != nullptr. This requirement is + // DCHECKed. In optimized builds, passing a null pointer here will have + // the effect of passing PosixErrorSpace::EINVAL as a fallback. + StatusOr(const T& value); // NOLINT + + // Copy constructor. + StatusOr(const StatusOr& other); + + // Conversion copy constructor, T must be copy constructible from U + template<typename U> + StatusOr(const StatusOr<U>& other); + + // Assignment operator. + StatusOr& operator=(const StatusOr& other); + + // Conversion assignment operator, T must be assignable from U + template<typename U> + StatusOr& operator=(const StatusOr<U>& other); + + // Returns a reference to our status. If this contains a T, then + // returns OkStatus(). + const Status& status() const; + + // Returns this->status().ok() + bool ok() const; + + // Returns a reference to our current value, or CHECK-fails if !this->ok(). + const T& value () const; + + private: + Status status_; + T value_; +}; + +//////////////////////////////////////////////////////////////////////////////// +// Implementation details for StatusOr<T> + +class PROTOBUF_EXPORT StatusOrHelper { + public: + // Move type-agnostic error handling to the .cc. + static void Crash(const util::Status& status); + + // Customized behavior for StatusOr<T> vs. StatusOr<T*> + template<typename T> + struct Specialize; +}; + +template<typename T> +struct StatusOrHelper::Specialize { + // For non-pointer T, a reference can never be nullptr. + static inline bool IsValueNull(const T& /*t*/) { return false; } +}; + +template<typename T> +struct StatusOrHelper::Specialize<T*> { + static inline bool IsValueNull(const T* t) { return t == nullptr; } +}; + +template <typename T> +inline StatusOr<T>::StatusOr() : status_(util::UnknownError("")) {} + +template<typename T> +inline StatusOr<T>::StatusOr(const Status& status) { + if (status.ok()) { + status_ = util::InternalError("OkStatus() is not a valid argument."); + } else { + status_ = status; + } +} + +template<typename T> +inline StatusOr<T>::StatusOr(const T& value) { + if (StatusOrHelper::Specialize<T>::IsValueNull(value)) { + status_ = util::InternalError("nullptr is not a valid argument."); + } else { + status_ = util::OkStatus(); + value_ = value; + } +} + +template<typename T> +inline StatusOr<T>::StatusOr(const StatusOr<T>& other) + : status_(other.status_), value_(other.value_) { +} + +template<typename T> +inline StatusOr<T>& StatusOr<T>::operator=(const StatusOr<T>& other) { + status_ = other.status_; + value_ = other.value_; + return *this; +} + +template<typename T> +template<typename U> +inline StatusOr<T>::StatusOr(const StatusOr<U>& other) + : status_(other.status_), value_(other.status_.ok() ? other.value_ : T()) { +} + +template<typename T> +template<typename U> +inline StatusOr<T>& StatusOr<T>::operator=(const StatusOr<U>& other) { + status_ = other.status_; + if (status_.ok()) value_ = other.value_; + return *this; +} + +template<typename T> +inline const Status& StatusOr<T>::status() const { + return status_; +} + +template<typename T> +inline bool StatusOr<T>::ok() const { + return status().ok(); +} + +template<typename T> +inline const T& StatusOr<T>::value() const { + if (!status_.ok()) { + StatusOrHelper::Crash(status_); + } + return value_; +} + +} // namespace statusor_internal + +using ::google::protobuf::util::statusor_internal::StatusOr; + +} // namespace util +} // namespace protobuf +} // namespace google + +#include <google/protobuf/port_undef.inc> + +#endif // GOOGLE_PROTOBUF_STUBS_STATUSOR_H_ diff --git a/contrib/libs/protobuf_old/src/google/protobuf/stubs/stl_util.h b/contrib/libs/protobuf_old/src/google/protobuf/stubs/stl_util.h new file mode 100644 index 0000000000..7b44c9593f --- /dev/null +++ b/contrib/libs/protobuf_old/src/google/protobuf/stubs/stl_util.h @@ -0,0 +1,85 @@ +// 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. + +// from google3/util/gtl/stl_util.h + +#ifndef GOOGLE_PROTOBUF_STUBS_STL_UTIL_H__ +#define GOOGLE_PROTOBUF_STUBS_STL_UTIL_H__ + +#include <google/protobuf/stubs/common.h> + +#include <algorithm> + +namespace google { +namespace protobuf { + +// Inside Google, this function implements a horrible, disgusting hack in which +// we reach into the string's private implementation and resize it without +// initializing the new bytes. In some cases doing this can significantly +// improve performance. However, since it's totally non-portable it has no +// place in open source code. Feel free to fill this function in with your +// own disgusting hack if you want the perf boost. +inline void STLStringResizeUninitialized(TProtoStringType* s, size_t new_size) { + s->ReserveAndResize(new_size); +} + +// As above, but we make sure to follow amortized growth in which we always +// increase the capacity by at least a constant factor >1. +inline void STLStringResizeUninitializedAmortized(TProtoStringType* s, + size_t new_size) { + const size_t cap = s->capacity(); + if (new_size > cap) { + // Make sure to always grow by at least a factor of 2x. + s->reserve(std::max(new_size, 2 * cap)); + } + STLStringResizeUninitialized(s, new_size); +} + +// Return a mutable char* pointing to a string's internal buffer, +// which may not be null-terminated. Writing through this pointer will +// modify the string. +// +// string_as_array(&str)[i] is valid for 0 <= i < str.size() until the +// next call to a string method that invalidates iterators. +// +// As of 2006-04, there is no standard-blessed way of getting a +// mutable reference to a string's internal buffer. However, issue 530 +// (http://www.open-std.org/JTC1/SC22/WG21/docs/lwg-active.html#530) +// proposes this as the method. According to Matt Austern, this should +// already work on all current implementations. +inline char* string_as_array(TProtoStringType* str) { + // DO NOT USE const_cast<char*>(str->data())! See the unittest for why. + return str->empty() ? nullptr : &*str->begin(); +} + +} // namespace protobuf +} // namespace google + +#endif // GOOGLE_PROTOBUF_STUBS_STL_UTIL_H__ diff --git a/contrib/libs/protobuf_old/src/google/protobuf/stubs/stringpiece.cc b/contrib/libs/protobuf_old/src/google/protobuf/stubs/stringpiece.cc new file mode 100644 index 0000000000..52416cee61 --- /dev/null +++ b/contrib/libs/protobuf_old/src/google/protobuf/stubs/stringpiece.cc @@ -0,0 +1,256 @@ +// 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 <google/protobuf/stubs/stringpiece.h> + +#include <string.h> +#include <algorithm> +#include <climits> +#include <string> +#include <ostream> + +#include <google/protobuf/stubs/logging.h> + +namespace google { +namespace protobuf { +namespace stringpiece_internal { + +std::ostream& operator<<(std::ostream& o, StringPiece piece) { + o.write(piece.data(), piece.size()); + return o; +} + +void StringPiece::LogFatalSizeTooBig(size_t size, const char* details) { + GOOGLE_LOG(FATAL) << "size too big: " << size << " details: " << details; +} + +void StringPiece::CopyToString(TProtoStringType* target) const { + target->assign(ptr_, length_); +} + +void StringPiece::AppendToString(TProtoStringType* target) const { + target->append(ptr_, length_); +} + +bool StringPiece::Consume(StringPiece x) { + if (starts_with(x)) { + ptr_ += x.length_; + length_ -= x.length_; + return true; + } + return false; +} + +bool StringPiece::ConsumeFromEnd(StringPiece x) { + if (ends_with(x)) { + length_ -= x.length_; + return true; + } + return false; +} + +StringPiece::size_type StringPiece::copy(char* buf, size_type n, + size_type pos) const { + size_type ret = std::min(length_ - pos, n); + memcpy(buf, ptr_ + pos, ret); + return ret; +} + +bool StringPiece::contains(StringPiece s) const { + return find(s, 0) != npos; +} + +StringPiece::size_type StringPiece::find(StringPiece s, size_type pos) const { + if (length_ <= 0 || pos > static_cast<size_type>(length_)) { + if (length_ == 0 && pos == 0 && s.length_ == 0) return 0; + return npos; + } + const char *result = std::search(ptr_ + pos, ptr_ + length_, + s.ptr_, s.ptr_ + s.length_); + return result == ptr_ + length_ ? npos : result - ptr_; +} + +StringPiece::size_type StringPiece::find(char c, size_type pos) const { + if (length_ <= 0 || pos >= static_cast<size_type>(length_)) { + return npos; + } + const char* result = static_cast<const char*>( + memchr(ptr_ + pos, c, length_ - pos)); + return result != nullptr ? result - ptr_ : npos; +} + +StringPiece::size_type StringPiece::rfind(StringPiece s, size_type pos) const { + if (length_ < s.length_) return npos; + const size_t ulen = length_; + if (s.length_ == 0) return std::min(ulen, pos); + + const char* last = ptr_ + std::min(ulen - s.length_, pos) + s.length_; + const char* result = std::find_end(ptr_, last, s.ptr_, s.ptr_ + s.length_); + return result != last ? result - ptr_ : npos; +} + +// Search range is [0..pos] inclusive. If pos == npos, search everything. +StringPiece::size_type StringPiece::rfind(char c, size_type pos) const { + // Note: memrchr() is not available on Windows. + if (empty()) return npos; + for (size_type i = std::min(pos, length_ - 1);; --i) { + if (ptr_[i] == c) { + return i; + } + if (i == 0) break; + } + return npos; +} + +// For each character in characters_wanted, sets the index corresponding +// to the ASCII code of that character to 1 in table. This is used by +// the find_.*_of methods below to tell whether or not a character is in +// the lookup table in constant time. +// The argument `table' must be an array that is large enough to hold all +// the possible values of an unsigned char. Thus it should be be declared +// as follows: +// bool table[UCHAR_MAX + 1] +static inline void BuildLookupTable(StringPiece characters_wanted, + bool* table) { + const StringPiece::size_type length = characters_wanted.length(); + const char* const data = characters_wanted.data(); + for (StringPiece::size_type i = 0; i < length; ++i) { + table[static_cast<unsigned char>(data[i])] = true; + } +} + +StringPiece::size_type StringPiece::find_first_of(StringPiece s, + size_type pos) const { + if (empty() || s.empty()) { + return npos; + } + // Avoid the cost of BuildLookupTable() for a single-character search. + if (s.length_ == 1) return find_first_of(s.ptr_[0], pos); + + bool lookup[UCHAR_MAX + 1] = { false }; + BuildLookupTable(s, lookup); + for (size_type i = pos; i < length_; ++i) { + if (lookup[static_cast<unsigned char>(ptr_[i])]) { + return i; + } + } + return npos; +} + +StringPiece::size_type StringPiece::find_first_not_of(StringPiece s, + size_type pos) const { + if (empty()) return npos; + if (s.empty()) return 0; + // Avoid the cost of BuildLookupTable() for a single-character search. + if (s.length_ == 1) return find_first_not_of(s.ptr_[0], pos); + + bool lookup[UCHAR_MAX + 1] = { false }; + BuildLookupTable(s, lookup); + for (size_type i = pos; i < length_; ++i) { + if (!lookup[static_cast<unsigned char>(ptr_[i])]) { + return i; + } + } + return npos; +} + +StringPiece::size_type StringPiece::find_first_not_of(char c, + size_type pos) const { + if (empty()) return npos; + + for (; pos < static_cast<size_type>(length_); ++pos) { + if (ptr_[pos] != c) { + return pos; + } + } + return npos; +} + +StringPiece::size_type StringPiece::find_last_of(StringPiece s, + size_type pos) const { + if (empty() || s.empty()) return npos; + // Avoid the cost of BuildLookupTable() for a single-character search. + if (s.length_ == 1) return find_last_of(s.ptr_[0], pos); + + bool lookup[UCHAR_MAX + 1] = { false }; + BuildLookupTable(s, lookup); + for (size_type i = std::min(pos, length_ - 1);; --i) { + if (lookup[static_cast<unsigned char>(ptr_[i])]) { + return i; + } + if (i == 0) break; + } + return npos; +} + +StringPiece::size_type StringPiece::find_last_not_of(StringPiece s, + size_type pos) const { + if (empty()) return npos; + + size_type i = std::min(pos, length() - 1); + if (s.empty()) return i; + + // Avoid the cost of BuildLookupTable() for a single-character search. + if (s.length_ == 1) return find_last_not_of(s.ptr_[0], pos); + + bool lookup[UCHAR_MAX + 1] = { false }; + BuildLookupTable(s, lookup); + for (;; --i) { + if (!lookup[static_cast<unsigned char>(ptr_[i])]) { + return i; + } + if (i == 0) break; + } + return npos; +} + +StringPiece::size_type StringPiece::find_last_not_of(char c, + size_type pos) const { + if (empty()) return npos; + size_type i = std::min(pos, length_ - 1); + for (;; --i) { + if (ptr_[i] != c) { + return i; + } + if (i == 0) break; + } + return npos; +} + +StringPiece StringPiece::substr(size_type pos, size_type n) const { + if (pos > length()) pos = length(); + if (n > length_ - pos) n = length() - pos; + return StringPiece(ptr_ + pos, n); +} + +const StringPiece::size_type StringPiece::npos = size_type(-1); + +} // namespace stringpiece_internal +} // namespace protobuf +} // namespace google diff --git a/contrib/libs/protobuf_old/src/google/protobuf/stubs/stringpiece.h b/contrib/libs/protobuf_old/src/google/protobuf/stubs/stringpiece.h new file mode 100644 index 0000000000..44a296bd8d --- /dev/null +++ b/contrib/libs/protobuf_old/src/google/protobuf/stubs/stringpiece.h @@ -0,0 +1,400 @@ +// 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. + +// A StringPiece points to part or all of a string, Cord, double-quoted string +// literal, or other string-like object. A StringPiece does *not* own the +// string to which it points. A StringPiece is not null-terminated. +// +// You can use StringPiece as a function or method parameter. A StringPiece +// parameter can receive a double-quoted string literal argument, a "const +// char*" argument, a string argument, or a StringPiece argument with no data +// copying. Systematic use of StringPiece for arguments reduces data +// copies and strlen() calls. +// +// Prefer passing StringPieces by value: +// void MyFunction(StringPiece arg); +// If circumstances require, you may also pass by const reference: +// void MyFunction(const StringPiece& arg); // not preferred +// Both of these have the same lifetime semantics. Passing by value +// generates slightly smaller code. For more discussion, see the thread +// go/stringpiecebyvalue on c-users. +// +// StringPiece is also suitable for local variables if you know that +// the lifetime of the underlying object is longer than the lifetime +// of your StringPiece variable. +// +// Beware of binding a StringPiece to a temporary: +// StringPiece sp = obj.MethodReturningString(); // BAD: lifetime problem +// +// This code is okay: +// string str = obj.MethodReturningString(); // str owns its contents +// StringPiece sp(str); // GOOD, because str outlives sp +// +// StringPiece is sometimes a poor choice for a return value and usually a poor +// choice for a data member. If you do use a StringPiece this way, it is your +// responsibility to ensure that the object pointed to by the StringPiece +// outlives the StringPiece. +// +// A StringPiece may represent just part of a string; thus the name "Piece". +// For example, when splitting a string, vector<StringPiece> is a natural data +// type for the output. For another example, a Cord is a non-contiguous, +// potentially very long string-like object. The Cord class has an interface +// that iteratively provides StringPiece objects that point to the +// successive pieces of a Cord object. +// +// A StringPiece is not null-terminated. If you write code that scans a +// StringPiece, you must check its length before reading any characters. +// Common idioms that work on null-terminated strings do not work on +// StringPiece objects. +// +// There are several ways to create a null StringPiece: +// StringPiece() +// StringPiece(nullptr) +// StringPiece(nullptr, 0) +// For all of the above, sp.data() == nullptr, sp.length() == 0, +// and sp.empty() == true. Also, if you create a StringPiece with +// a non-null pointer then sp.data() != nullptr. Once created, +// sp.data() will stay either nullptr or not-nullptr, except if you call +// sp.clear() or sp.set(). +// +// Thus, you can use StringPiece(nullptr) to signal an out-of-band value +// that is different from other StringPiece values. This is similar +// to the way that const char* p1 = nullptr; is different from +// const char* p2 = "";. +// +// There are many ways to create an empty StringPiece: +// StringPiece() +// StringPiece(nullptr) +// StringPiece(nullptr, 0) +// StringPiece("") +// StringPiece("", 0) +// StringPiece("abcdef", 0) +// StringPiece("abcdef"+6, 0) +// For all of the above, sp.length() will be 0 and sp.empty() will be true. +// For some empty StringPiece values, sp.data() will be nullptr. +// For some empty StringPiece values, sp.data() will not be nullptr. +// +// Be careful not to confuse: null StringPiece and empty StringPiece. +// The set of empty StringPieces properly includes the set of null StringPieces. +// That is, every null StringPiece is an empty StringPiece, +// but some non-null StringPieces are empty Stringpieces too. +// +// All empty StringPiece values compare equal to each other. +// Even a null StringPieces compares equal to a non-null empty StringPiece: +// StringPiece() == StringPiece("", 0) +// StringPiece(nullptr) == StringPiece("abc", 0) +// StringPiece(nullptr, 0) == StringPiece("abcdef"+6, 0) +// +// Look carefully at this example: +// StringPiece("") == nullptr +// True or false? TRUE, because StringPiece::operator== converts +// the right-hand side from nullptr to StringPiece(nullptr), +// and then compares two zero-length spans of characters. +// However, we are working to make this example produce a compile error. +// +// Suppose you want to write: +// bool TestWhat?(StringPiece sp) { return sp == nullptr; } // BAD +// Do not do that. Write one of these instead: +// bool TestNull(StringPiece sp) { return sp.data() == nullptr; } +// bool TestEmpty(StringPiece sp) { return sp.empty(); } +// The intent of TestWhat? is unclear. Did you mean TestNull or TestEmpty? +// Right now, TestWhat? behaves likes TestEmpty. +// We are working to make TestWhat? produce a compile error. +// TestNull is good to test for an out-of-band signal. +// TestEmpty is good to test for an empty StringPiece. +// +// Caveats (again): +// (1) The lifetime of the pointed-to string (or piece of a string) +// must be longer than the lifetime of the StringPiece. +// (2) There may or may not be a '\0' character after the end of +// StringPiece data. +// (3) A null StringPiece is empty. +// An empty StringPiece may or may not be a null StringPiece. + +#ifndef GOOGLE_PROTOBUF_STUBS_STRINGPIECE_H_ +#define GOOGLE_PROTOBUF_STUBS_STRINGPIECE_H_ + +#include <assert.h> +#include <stddef.h> +#include <string.h> +#include <iosfwd> +#include <limits> +#include <string> + +#if defined(__cpp_lib_string_view) +#include <string_view> +#endif + +#include <google/protobuf/stubs/hash.h> + +#include <google/protobuf/port_def.inc> + +namespace google { +namespace protobuf { +namespace stringpiece_internal { + +class PROTOBUF_EXPORT StringPiece { + public: + using traits_type = std::char_traits<char>; + using value_type = char; + using pointer = char*; + using const_pointer = const char*; + using reference = char&; + using const_reference = const char&; + using const_iterator = const char*; + using iterator = const_iterator; + using const_reverse_iterator = std::reverse_iterator<const_iterator>; + using reverse_iterator = const_reverse_iterator; + using size_type = size_t; + using difference_type = std::ptrdiff_t; + + private: + const char* ptr_; + size_type length_; + + static constexpr size_type kMaxSize = + (std::numeric_limits<difference_type>::max)(); + + static size_type CheckSize(size_type size) { +#if !defined(NDEBUG) || defined(_FORTIFY_SOURCE) && _FORTIFY_SOURCE > 0 + if (PROTOBUF_PREDICT_FALSE(size > kMaxSize)) { + // Some people grep for this message in logs + // so take care if you ever change it. + LogFatalSizeTooBig(size, "string length exceeds max size"); + } +#endif + return size; + } + + // Out-of-line error path. + static void LogFatalSizeTooBig(size_type size, const char* details); + + public: + // We provide non-explicit singleton constructors so users can pass + // in a "const char*" or a "string" wherever a "StringPiece" is + // expected. + // + // Style guide exception granted: + // http://goto/style-guide-exception-20978288 + StringPiece() : ptr_(nullptr), length_(0) {} + + StringPiece(const char* str) // NOLINT(runtime/explicit) + : ptr_(str), length_(0) { + if (str != nullptr) { + length_ = CheckSize(strlen(str)); + } + } + + StringPiece(const TProtoStringType& str) + : ptr_(str.data()), length_(str.size()) + { + } + +#if defined(__cpp_lib_string_view) + StringPiece( // NOLINT(runtime/explicit) + std::string_view str) + : ptr_(str.data()), length_(0) { + length_ = CheckSize(str.size()); + } +#endif + + StringPiece(const char* offset, size_type len) + : ptr_(offset), length_(CheckSize(len)) {} + + // data() may return a pointer to a buffer with embedded NULs, and the + // returned buffer may or may not be null terminated. Therefore it is + // typically a mistake to pass data() to a routine that expects a NUL + // terminated string. + const_pointer data() const { return ptr_; } + size_type size() const { return length_; } + size_type length() const { return length_; } + bool empty() const { return length_ == 0; } + + char operator[](size_type i) const { + assert(i < length_); + return ptr_[i]; + } + + void remove_prefix(size_type n) { + assert(length_ >= n); + ptr_ += n; + length_ -= n; + } + + void remove_suffix(size_type n) { + assert(length_ >= n); + length_ -= n; + } + + // returns {-1, 0, 1} + int compare(StringPiece x) const { + size_type min_size = length_ < x.length_ ? length_ : x.length_; + int r = memcmp(ptr_, x.ptr_, static_cast<size_t>(min_size)); + if (r < 0) return -1; + if (r > 0) return 1; + if (length_ < x.length_) return -1; + if (length_ > x.length_) return 1; + return 0; + } + + TProtoStringType as_string() const { return ToString(); } + // We also define ToString() here, since many other string-like + // interfaces name the routine that converts to a C++ string + // "ToString", and it's confusing to have the method that does that + // for a StringPiece be called "as_string()". We also leave the + // "as_string()" method defined here for existing code. + TProtoStringType ToString() const { + if (ptr_ == nullptr) return ""; + return TProtoStringType(data(), static_cast<size_type>(size())); + } + + explicit operator TProtoStringType() const { return ToString(); } + + void CopyToString(TProtoStringType* target) const; + void AppendToString(TProtoStringType* target) const; + + bool starts_with(StringPiece x) const { + return (length_ >= x.length_) && + (memcmp(ptr_, x.ptr_, static_cast<size_t>(x.length_)) == 0); + } + + bool ends_with(StringPiece x) const { + return ((length_ >= x.length_) && + (memcmp(ptr_ + (length_-x.length_), x.ptr_, + static_cast<size_t>(x.length_)) == 0)); + } + + // Checks whether StringPiece starts with x and if so advances the beginning + // of it to past the match. It's basically a shortcut for starts_with + // followed by remove_prefix. + bool Consume(StringPiece x); + // Like above but for the end of the string. + bool ConsumeFromEnd(StringPiece x); + + // standard STL container boilerplate + static const size_type npos; + const_iterator begin() const { return ptr_; } + const_iterator end() const { return ptr_ + length_; } + const_reverse_iterator rbegin() const { + return const_reverse_iterator(ptr_ + length_); + } + const_reverse_iterator rend() const { + return const_reverse_iterator(ptr_); + } + size_type max_size() const { return length_; } + size_type capacity() const { return length_; } + + // cpplint.py emits a false positive [build/include_what_you_use] + size_type copy(char* buf, size_type n, size_type pos = 0) const; // NOLINT + + bool contains(StringPiece s) const; + + size_type find(StringPiece s, size_type pos = 0) const; + size_type find(char c, size_type pos = 0) const; + size_type rfind(StringPiece s, size_type pos = npos) const; + size_type rfind(char c, size_type pos = npos) const; + + size_type find_first_of(StringPiece s, size_type pos = 0) const; + size_type find_first_of(char c, size_type pos = 0) const { + return find(c, pos); + } + size_type find_first_not_of(StringPiece s, size_type pos = 0) const; + size_type find_first_not_of(char c, size_type pos = 0) const; + size_type find_last_of(StringPiece s, size_type pos = npos) const; + size_type find_last_of(char c, size_type pos = npos) const { + return rfind(c, pos); + } + size_type find_last_not_of(StringPiece s, size_type pos = npos) const; + size_type find_last_not_of(char c, size_type pos = npos) const; + + StringPiece substr(size_type pos, size_type n = npos) const; +}; + +// This large function is defined inline so that in a fairly common case where +// one of the arguments is a literal, the compiler can elide a lot of the +// following comparisons. +inline bool operator==(StringPiece x, StringPiece y) { + StringPiece::size_type len = x.size(); + if (len != y.size()) { + return false; + } + + return x.data() == y.data() || len <= 0 || + memcmp(x.data(), y.data(), static_cast<size_t>(len)) == 0; +} + +inline bool operator!=(StringPiece x, StringPiece y) { + return !(x == y); +} + +inline bool operator<(StringPiece x, StringPiece y) { + const StringPiece::size_type min_size = + x.size() < y.size() ? x.size() : y.size(); + const int r = memcmp(x.data(), y.data(), static_cast<size_t>(min_size)); + return (r < 0) || (r == 0 && x.size() < y.size()); +} + +inline bool operator>(StringPiece x, StringPiece y) { + return y < x; +} + +inline bool operator<=(StringPiece x, StringPiece y) { + return !(x > y); +} + +inline bool operator>=(StringPiece x, StringPiece y) { + return !(x < y); +} + +// allow StringPiece to be logged +extern std::ostream& operator<<(std::ostream& o, StringPiece piece); + +} // namespace stringpiece_internal + +using ::google::protobuf::stringpiece_internal::StringPiece; + +} // namespace protobuf +} // namespace google + +GOOGLE_PROTOBUF_HASH_NAMESPACE_DECLARATION_START +template<> struct hash<StringPiece> { + size_t operator()(const StringPiece& s) const { + size_t result = 0; + for (const char *str = s.data(), *end = str + s.size(); str < end; str++) { + result = 5 * result + static_cast<size_t>(*str); + } + return result; + } +}; +GOOGLE_PROTOBUF_HASH_NAMESPACE_DECLARATION_END + +#include <google/protobuf/port_undef.inc> + +#endif // STRINGS_STRINGPIECE_H_ diff --git a/contrib/libs/protobuf_old/src/google/protobuf/stubs/stringprintf.cc b/contrib/libs/protobuf_old/src/google/protobuf/stubs/stringprintf.cc new file mode 100644 index 0000000000..413578c918 --- /dev/null +++ b/contrib/libs/protobuf_old/src/google/protobuf/stubs/stringprintf.cc @@ -0,0 +1,175 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2012 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. + +// from google3/base/stringprintf.cc + +#include <google/protobuf/stubs/stringprintf.h> + +#include <errno.h> +#include <stdarg.h> // For va_list and related operations +#include <stdio.h> // MSVC requires this for _vsnprintf +#include <vector> + +#include <google/protobuf/stubs/common.h> +#include <google/protobuf/stubs/logging.h> + +namespace google { +namespace protobuf { + +#ifdef _MSC_VER +#ifndef va_copy +// Define va_copy for MSVC. This is a hack, assuming va_list is simply a +// pointer into the stack and is safe to copy. +#define va_copy(dest, src) ((dest) = (src)) +#endif +#endif + +void StringAppendV(TProtoStringType* dst, const char* format, va_list ap) { + // First try with a small fixed size buffer + static const int kSpaceLength = 1024; + char space[kSpaceLength]; + + // It's possible for methods that use a va_list to invalidate + // the data in it upon use. The fix is to make a copy + // of the structure before using it and use that copy instead. + va_list backup_ap; + va_copy(backup_ap, ap); + int result = vsnprintf(space, kSpaceLength, format, backup_ap); + va_end(backup_ap); + + if (result < kSpaceLength) { + if (result >= 0) { + // Normal case -- everything fit. + dst->append(space, result); + return; + } + +#ifdef _MSC_VER + { + // Error or MSVC running out of space. MSVC 8.0 and higher + // can be asked about space needed with the special idiom below: + va_copy(backup_ap, ap); + result = vsnprintf(nullptr, 0, format, backup_ap); + va_end(backup_ap); + } +#endif + + if (result < 0) { + // Just an error. + return; + } + } + + // Increase the buffer size to the size requested by vsnprintf, + // plus one for the closing \0. + int length = result+1; + char* buf = new char[length]; + + // Restore the va_list before we use it again + va_copy(backup_ap, ap); + result = vsnprintf(buf, length, format, backup_ap); + va_end(backup_ap); + + if (result >= 0 && result < length) { + // It fit + dst->append(buf, result); + } + delete[] buf; +} + +TProtoStringType StringPrintf(const char* format, ...) { + va_list ap; + va_start(ap, format); + TProtoStringType result; + StringAppendV(&result, format, ap); + va_end(ap); + return result; +} + +const TProtoStringType& SStringPrintf(TProtoStringType* dst, const char* format, ...) { + va_list ap; + va_start(ap, format); + dst->clear(); + StringAppendV(dst, format, ap); + va_end(ap); + return *dst; +} + +void StringAppendF(TProtoStringType* dst, const char* format, ...) { + va_list ap; + va_start(ap, format); + StringAppendV(dst, format, ap); + va_end(ap); +} + +// Max arguments supported by StringPrintVector +const int kStringPrintfVectorMaxArgs = 32; + +// An empty block of zero for filler arguments. This is const so that if +// printf tries to write to it (via %n) then the program gets a SIGSEGV +// and we can fix the problem or protect against an attack. +static const char string_printf_empty_block[256] = { '\0' }; + +TProtoStringType StringPrintfVector(const char* format, + const std::vector<TProtoStringType>& v) { + GOOGLE_CHECK_LE(v.size(), kStringPrintfVectorMaxArgs) + << "StringPrintfVector currently only supports up to " + << kStringPrintfVectorMaxArgs << " arguments. " + << "Feel free to add support for more if you need it."; + + // Add filler arguments so that bogus format+args have a harder time + // crashing the program, corrupting the program (%n), + // or displaying random chunks of memory to users. + + const char* cstr[kStringPrintfVectorMaxArgs]; + for (int i = 0; i < v.size(); ++i) { + cstr[i] = v[i].c_str(); + } + for (int i = v.size(); i < GOOGLE_ARRAYSIZE(cstr); ++i) { + cstr[i] = &string_printf_empty_block[0]; + } + + // I do not know any way to pass kStringPrintfVectorMaxArgs arguments, + // or any way to build a va_list by hand, or any API for printf + // that accepts an array of arguments. The best I can do is stick + // this COMPILE_ASSERT right next to the actual statement. + + static_assert(kStringPrintfVectorMaxArgs == 32, "arg_count_mismatch"); + return StringPrintf(format, + cstr[0], cstr[1], cstr[2], cstr[3], cstr[4], + cstr[5], cstr[6], cstr[7], cstr[8], cstr[9], + cstr[10], cstr[11], cstr[12], cstr[13], cstr[14], + cstr[15], cstr[16], cstr[17], cstr[18], cstr[19], + cstr[20], cstr[21], cstr[22], cstr[23], cstr[24], + cstr[25], cstr[26], cstr[27], cstr[28], cstr[29], + cstr[30], cstr[31]); +} +} // namespace protobuf +} // namespace google diff --git a/contrib/libs/protobuf_old/src/google/protobuf/stubs/stringprintf.h b/contrib/libs/protobuf_old/src/google/protobuf/stubs/stringprintf.h new file mode 100644 index 0000000000..b8f457f5ad --- /dev/null +++ b/contrib/libs/protobuf_old/src/google/protobuf/stubs/stringprintf.h @@ -0,0 +1,85 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2012 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. + +// from google3/base/stringprintf.h +// +// Printf variants that place their output in a C++ string. +// +// Usage: +// string result = StringPrintf("%d %s\n", 10, "hello"); +// SStringPrintf(&result, "%d %s\n", 10, "hello"); +// StringAppendF(&result, "%d %s\n", 20, "there"); + +#ifndef GOOGLE_PROTOBUF_STUBS_STRINGPRINTF_H +#define GOOGLE_PROTOBUF_STUBS_STRINGPRINTF_H + +#include <stdarg.h> +#include <string> +#include <vector> + +#include <google/protobuf/stubs/common.h> + +#include <google/protobuf/port_def.inc> + +namespace google { +namespace protobuf { + +// Return a C++ string +PROTOBUF_EXPORT extern TProtoStringType StringPrintf(const char* format, ...); + +// Store result into a supplied string and return it +PROTOBUF_EXPORT extern const TProtoStringType& SStringPrintf(TProtoStringType* dst, + const char* format, + ...); + +// Append result to a supplied string +PROTOBUF_EXPORT extern void StringAppendF(TProtoStringType* dst, const char* format, + ...); + +// Lower-level routine that takes a va_list and appends to a specified +// string. All other routines are just convenience wrappers around it. +PROTOBUF_EXPORT extern void StringAppendV(TProtoStringType* dst, const char* format, + va_list ap); + +// The max arguments supported by StringPrintfVector +PROTOBUF_EXPORT extern const int kStringPrintfVectorMaxArgs; + +// You can use this version when all your arguments are strings, but +// you don't know how many arguments you'll have at compile time. +// StringPrintfVector will LOG(FATAL) if v.size() > kStringPrintfVectorMaxArgs +PROTOBUF_EXPORT extern TProtoStringType StringPrintfVector( + const char* format, const std::vector<TProtoStringType>& v); + +} // namespace protobuf +} // namespace google + +#include <google/protobuf/port_undef.inc> + +#endif // GOOGLE_PROTOBUF_STUBS_STRINGPRINTF_H diff --git a/contrib/libs/protobuf_old/src/google/protobuf/stubs/structurally_valid.cc b/contrib/libs/protobuf_old/src/google/protobuf/stubs/structurally_valid.cc new file mode 100644 index 0000000000..9a476c3b4c --- /dev/null +++ b/contrib/libs/protobuf_old/src/google/protobuf/stubs/structurally_valid.cc @@ -0,0 +1,615 @@ +// 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: jrm@google.com (Jim Meehan) + +#include <google/protobuf/stubs/common.h> + +#include <google/protobuf/stubs/stringpiece.h> + +namespace google { +namespace protobuf { +namespace internal { + +// These four-byte entries compactly encode how many bytes 0..255 to delete +// in making a string replacement, how many bytes to add 0..255, and the offset +// 0..64k-1 of the replacement string in remap_string. +struct RemapEntry { + uint8 delete_bytes; + uint8 add_bytes; + uint16 bytes_offset; +}; + +// Exit type codes for state tables. All but the first get stuffed into +// signed one-byte entries. The first is only generated by executable code. +// To distinguish from next-state entries, these must be contiguous and +// all <= kExitNone +typedef enum { + kExitDstSpaceFull = 239, + kExitIllegalStructure, // 240 + kExitOK, // 241 + kExitReject, // ... + kExitReplace1, + kExitReplace2, + kExitReplace3, + kExitReplace21, + kExitReplace31, + kExitReplace32, + kExitReplaceOffset1, + kExitReplaceOffset2, + kExitReplace1S0, + kExitSpecial, + kExitDoAgain, + kExitRejectAlt, + kExitNone // 255 +} ExitReason; + + +// This struct represents one entire state table. The three initialized byte +// areas are state_table, remap_base, and remap_string. state0 and state0_size +// give the byte offset and length within state_table of the initial state -- +// table lookups are expected to start and end in this state, but for +// truncated UTF-8 strings, may end in a different state. These allow a quick +// test for that condition. entry_shift is 8 for tables subscripted by a full +// byte value and 6 for space-optimized tables subscripted by only six +// significant bits in UTF-8 continuation bytes. +typedef struct { + const uint32 state0; + const uint32 state0_size; + const uint32 total_size; + const int max_expand; + const int entry_shift; + const int bytes_per_entry; + const uint32 losub; + const uint32 hiadd; + const uint8* state_table; + const RemapEntry* remap_base; + const uint8* remap_string; + const uint8* fast_state; +} UTF8StateMachineObj; + +typedef UTF8StateMachineObj UTF8ScanObj; + +#define X__ (kExitIllegalStructure) +#define RJ_ (kExitReject) +#define S1_ (kExitReplace1) +#define S2_ (kExitReplace2) +#define S3_ (kExitReplace3) +#define S21 (kExitReplace21) +#define S31 (kExitReplace31) +#define S32 (kExitReplace32) +#define T1_ (kExitReplaceOffset1) +#define T2_ (kExitReplaceOffset2) +#define S11 (kExitReplace1S0) +#define SP_ (kExitSpecial) +#define D__ (kExitDoAgain) +#define RJA (kExitRejectAlt) + +// Entire table has 9 state blocks of 256 entries each +static const unsigned int utf8acceptnonsurrogates_STATE0 = 0; // state[0] +static const unsigned int utf8acceptnonsurrogates_STATE0_SIZE = 256; // =[1] +static const unsigned int utf8acceptnonsurrogates_TOTAL_SIZE = 2304; +static const unsigned int utf8acceptnonsurrogates_MAX_EXPAND_X4 = 0; +static const unsigned int utf8acceptnonsurrogates_SHIFT = 8; +static const unsigned int utf8acceptnonsurrogates_BYTES = 1; +static const unsigned int utf8acceptnonsurrogates_LOSUB = 0x20202020; +static const unsigned int utf8acceptnonsurrogates_HIADD = 0x00000000; + +static const uint8 utf8acceptnonsurrogates[] = { +// state[0] 0x000000 Byte 1 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + +X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, +X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, +X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, +X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, + +X__, X__, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 7, 3, 3, + 4, 5, 5, 5, 6, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, + +// state[1] 0x000080 Byte 2 of 2 +X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, +X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, +X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, +X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, + +X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, +X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, +X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, +X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, + + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + +X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, +X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, +X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, +X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, + +// state[2] 0x000000 Byte 2 of 3 +X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, +X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, +X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, +X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, + +X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, +X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, +X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, +X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, + +X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, +X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + +X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, +X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, +X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, +X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, + +// state[3] 0x001000 Byte 2 of 3 +X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, +X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, +X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, +X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, + +X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, +X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, +X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, +X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, + + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + +X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, +X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, +X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, +X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, + +// state[4] 0x000000 Byte 2 of 4 +X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, +X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, +X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, +X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, + +X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, +X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, +X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, +X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, + +X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + +X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, +X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, +X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, +X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, + +// state[5] 0x040000 Byte 2 of 4 +X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, +X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, +X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, +X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, + +X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, +X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, +X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, +X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, + + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + +X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, +X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, +X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, +X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, + +// state[6] 0x100000 Byte 2 of 4 +X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, +X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, +X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, +X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, + +X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, +X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, +X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, +X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, + + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, +X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, +X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, +X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, + +X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, +X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, +X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, +X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, + +// state[7] 0x00d000 Byte 2 of 3 +X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, +X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, +X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, +X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, + +X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, +X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, +X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, +X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, + + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, + +X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, +X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, +X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, +X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, + +// state[8] 0x00d800 Byte 3 of 3 +X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, +X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, +X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, +X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, + +X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, +X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, +X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, +X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, + +RJ_, RJ_, RJ_, RJ_, RJ_, RJ_, RJ_, RJ_, RJ_, RJ_, RJ_, RJ_, RJ_, RJ_, RJ_, RJ_, +RJ_, RJ_, RJ_, RJ_, RJ_, RJ_, RJ_, RJ_, RJ_, RJ_, RJ_, RJ_, RJ_, RJ_, RJ_, RJ_, +RJ_, RJ_, RJ_, RJ_, RJ_, RJ_, RJ_, RJ_, RJ_, RJ_, RJ_, RJ_, RJ_, RJ_, RJ_, RJ_, +RJ_, RJ_, RJ_, RJ_, RJ_, RJ_, RJ_, RJ_, RJ_, RJ_, RJ_, RJ_, RJ_, RJ_, RJ_, RJ_, + +X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, +X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, +X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, +X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, +}; + +// Remap base[0] = (del, add, string_offset) +static const RemapEntry utf8acceptnonsurrogates_remap_base[] = { +{0, 0, 0} }; + +// Remap string[0] +static const unsigned char utf8acceptnonsurrogates_remap_string[] = { +0 }; + +static const unsigned char utf8acceptnonsurrogates_fast[256] = { +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + +1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, +1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, +1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, +1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + +1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, +1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, +1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, +1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, +}; + +static const UTF8ScanObj utf8acceptnonsurrogates_obj = { + utf8acceptnonsurrogates_STATE0, + utf8acceptnonsurrogates_STATE0_SIZE, + utf8acceptnonsurrogates_TOTAL_SIZE, + utf8acceptnonsurrogates_MAX_EXPAND_X4, + utf8acceptnonsurrogates_SHIFT, + utf8acceptnonsurrogates_BYTES, + utf8acceptnonsurrogates_LOSUB, + utf8acceptnonsurrogates_HIADD, + utf8acceptnonsurrogates, + utf8acceptnonsurrogates_remap_base, + utf8acceptnonsurrogates_remap_string, + utf8acceptnonsurrogates_fast +}; + + +#undef X__ +#undef RJ_ +#undef S1_ +#undef S2_ +#undef S3_ +#undef S21 +#undef S31 +#undef S32 +#undef T1_ +#undef T2_ +#undef S11 +#undef SP_ +#undef D__ +#undef RJA + +// Return true if current Tbl pointer is within state0 range +// Note that unsigned compare checks both ends of range simultaneously +static inline bool InStateZero(const UTF8ScanObj* st, const uint8* Tbl) { + const uint8* Tbl0 = &st->state_table[st->state0]; + return (static_cast<uint32>(Tbl - Tbl0) < st->state0_size); +} + +// Scan a UTF-8 string based on state table. +// Always scan complete UTF-8 characters +// Set number of bytes scanned. Return reason for exiting +int UTF8GenericScan(const UTF8ScanObj* st, + const char * str, + int str_length, + int* bytes_consumed) { + *bytes_consumed = 0; + if (str_length == 0) return kExitOK; + + int eshift = st->entry_shift; + const uint8* isrc = reinterpret_cast<const uint8*>(str); + const uint8* src = isrc; + const uint8* srclimit = isrc + str_length; + const uint8* srclimit8 = str_length < 7 ? isrc : srclimit - 7; + const uint8* Tbl_0 = &st->state_table[st->state0]; + + DoAgain: + // Do state-table scan + int e = 0; + uint8 c; + const uint8* Tbl2 = &st->fast_state[0]; + const uint32 losub = st->losub; + const uint32 hiadd = st->hiadd; + // Check initial few bytes one at a time until 8-byte aligned + //---------------------------- + while ((((uintptr_t)src & 0x07) != 0) && + (src < srclimit) && + Tbl2[src[0]] == 0) { + src++; + } + if (((uintptr_t)src & 0x07) == 0) { + // Do fast for groups of 8 identity bytes. + // This covers a lot of 7-bit ASCII ~8x faster then the 1-byte loop, + // including slowing slightly on cr/lf/ht + //---------------------------- + while (src < srclimit8) { + uint32 s0123 = (reinterpret_cast<const uint32 *>(src))[0]; + uint32 s4567 = (reinterpret_cast<const uint32 *>(src))[1]; + src += 8; + // This is a fast range check for all bytes in [lowsub..0x80-hiadd) + uint32 temp = (s0123 - losub) | (s0123 + hiadd) | + (s4567 - losub) | (s4567 + hiadd); + if ((temp & 0x80808080) != 0) { + // We typically end up here on cr/lf/ht; src was incremented + int e0123 = (Tbl2[src[-8]] | Tbl2[src[-7]]) | + (Tbl2[src[-6]] | Tbl2[src[-5]]); + if (e0123 != 0) { + src -= 8; + break; + } // Exit on Non-interchange + e0123 = (Tbl2[src[-4]] | Tbl2[src[-3]]) | + (Tbl2[src[-2]] | Tbl2[src[-1]]); + if (e0123 != 0) { + src -= 4; + break; + } // Exit on Non-interchange + // Else OK, go around again + } + } + } + //---------------------------- + + // Byte-at-a-time scan + //---------------------------- + const uint8* Tbl = Tbl_0; + while (src < srclimit) { + c = *src; + e = Tbl[c]; + src++; + if (e >= kExitIllegalStructure) {break;} + Tbl = &Tbl_0[e << eshift]; + } + //---------------------------- + + // Exit possibilities: + // Some exit code, !state0, back up over last char + // Some exit code, state0, back up one byte exactly + // source consumed, !state0, back up over partial char + // source consumed, state0, exit OK + // For illegal byte in state0, avoid backup up over PREVIOUS char + // For truncated last char, back up to beginning of it + + if (e >= kExitIllegalStructure) { + // Back up over exactly one byte of rejected/illegal UTF-8 character + src--; + // Back up more if needed + if (!InStateZero(st, Tbl)) { + do { + src--; + } while ((src > isrc) && ((src[0] & 0xc0) == 0x80)); + } + } else if (!InStateZero(st, Tbl)) { + // Back up over truncated UTF-8 character + e = kExitIllegalStructure; + do { + src--; + } while ((src > isrc) && ((src[0] & 0xc0) == 0x80)); + } else { + // Normal termination, source fully consumed + e = kExitOK; + } + + if (e == kExitDoAgain) { + // Loop back up to the fast scan + goto DoAgain; + } + + *bytes_consumed = src - isrc; + return e; +} + +int UTF8GenericScanFastAscii(const UTF8ScanObj* st, + const char * str, + int str_length, + int* bytes_consumed) { + *bytes_consumed = 0; + if (str_length == 0) return kExitOK; + + const uint8* isrc = reinterpret_cast<const uint8*>(str); + const uint8* src = isrc; + const uint8* srclimit = isrc + str_length; + const uint8* srclimit8 = str_length < 7 ? isrc : srclimit - 7; + int n; + int rest_consumed; + int exit_reason; + do { + // Check initial few bytes one at a time until 8-byte aligned + while ((((uintptr_t)src & 0x07) != 0) && + (src < srclimit) && (src[0] < 0x80)) { + src++; + } + if (((uintptr_t)src & 0x07) == 0) { + while ((src < srclimit8) && + (((reinterpret_cast<const uint32*>(src)[0] | + reinterpret_cast<const uint32*>(src)[1]) & 0x80808080) == 0)) { + src += 8; + } + } + while ((src < srclimit) && (src[0] < 0x80)) { + src++; + } + // Run state table on the rest + n = src - isrc; + exit_reason = UTF8GenericScan(st, str + n, str_length - n, &rest_consumed); + src += rest_consumed; + } while ( exit_reason == kExitDoAgain ); + + *bytes_consumed = src - isrc; + return exit_reason; +} + +// Hack: On some compilers the static tables are initialized at startup. +// We can't use them until they are initialized. However, some Protocol +// Buffer parsing happens at static init time and may try to validate +// UTF-8 strings. Since UTF-8 validation is only used for debugging +// anyway, we simply always return success if initialization hasn't +// occurred yet. +namespace { + +bool module_initialized_ = false; + +struct InitDetector { + InitDetector() { + module_initialized_ = true; + } +}; +InitDetector init_detector; + +} // namespace + +bool IsStructurallyValidUTF8(const char* buf, int len) { + if (!module_initialized_) return true; + + int bytes_consumed = 0; + UTF8GenericScanFastAscii(&utf8acceptnonsurrogates_obj, + buf, len, &bytes_consumed); + return (bytes_consumed == len); +} + +int UTF8SpnStructurallyValid(StringPiece str) { + if (!module_initialized_) return str.size(); + + int bytes_consumed = 0; + UTF8GenericScanFastAscii(&utf8acceptnonsurrogates_obj, + str.data(), str.size(), &bytes_consumed); + return bytes_consumed; +} + +// Coerce UTF-8 byte string in src_str to be +// a structurally-valid equal-length string by selectively +// overwriting illegal bytes with replace_char (typically blank). +// replace_char must be legal printable 7-bit Ascii 0x20..0x7e. +// src_str is read-only. If any overwriting is needed, a modified byte string +// is created in idst, length isrclen. +// +// Returns pointer to output buffer, isrc if no changes were made, +// or idst if some bytes were changed. +// +// Fast case: all is structurally valid and no byte copying is done. +// +char* UTF8CoerceToStructurallyValid(StringPiece src_str, char* idst, + const char replace_char) { + const char* isrc = src_str.data(); + const int len = src_str.length(); + int n = UTF8SpnStructurallyValid(src_str); + if (n == len) { // Normal case -- all is cool, return + return const_cast<char*>(isrc); + } else { // Unusual case -- copy w/o bad bytes + const char* src = isrc; + const char* srclimit = isrc + len; + char* dst = idst; + memmove(dst, src, n); // Copy initial good chunk + src += n; + dst += n; + while (src < srclimit) { // src points to bogus byte or is off the end + dst[0] = replace_char; // replace one bad byte + src++; + dst++; + StringPiece str2(src, srclimit - src); + n = UTF8SpnStructurallyValid(str2); // scan the remainder + memmove(dst, src, n); // copy next good chunk + src += n; + dst += n; + } + } + return idst; +} + +} // namespace internal +} // namespace protobuf +} // namespace google diff --git a/contrib/libs/protobuf_old/src/google/protobuf/stubs/strutil.cc b/contrib/libs/protobuf_old/src/google/protobuf/stubs/strutil.cc new file mode 100644 index 0000000000..b72f10a3da --- /dev/null +++ b/contrib/libs/protobuf_old/src/google/protobuf/stubs/strutil.cc @@ -0,0 +1,2479 @@ +// 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. + +// from google3/strings/strutil.cc + +#include <google/protobuf/stubs/strutil.h> + +#include <errno.h> +#include <float.h> // FLT_DIG and DBL_DIG +#include <limits.h> +#include <stdio.h> +#include <cmath> +#include <iterator> +#include <limits> + +#include <google/protobuf/stubs/logging.h> +#include <google/protobuf/stubs/stl_util.h> + +#ifdef _WIN32 +// MSVC has only _snprintf, not snprintf. +// +// MinGW has both snprintf and _snprintf, but they appear to be different +// functions. The former is buggy. When invoked like so: +// char buffer[32]; +// snprintf(buffer, 32, "%.*g\n", FLT_DIG, 1.23e10f); +// it prints "1.23000e+10". This is plainly wrong: %g should never print +// trailing zeros after the decimal point. For some reason this bug only +// occurs with some input values, not all. In any case, _snprintf does the +// right thing, so we use it. +#define snprintf _snprintf +#endif + +namespace google { +namespace protobuf { + +// These are defined as macros on some platforms. #undef them so that we can +// redefine them. +#undef isxdigit +#undef isprint + +// The definitions of these in ctype.h change based on locale. Since our +// string manipulation is all in relation to the protocol buffer and C++ +// languages, we always want to use the C locale. So, we re-define these +// exactly as we want them. +inline bool isxdigit(char c) { + return ('0' <= c && c <= '9') || + ('a' <= c && c <= 'f') || + ('A' <= c && c <= 'F'); +} + +inline bool isprint(char c) { + return c >= 0x20 && c <= 0x7E; +} + +// ---------------------------------------------------------------------- +// ReplaceCharacters +// Replaces any occurrence of the character 'remove' (or the characters +// in 'remove') with the character 'replacewith'. +// ---------------------------------------------------------------------- +void ReplaceCharacters(TProtoStringType *s, const char *remove, char replacewith) { + const char *str_start = s->c_str(); + const char *str = str_start; + for (str = strpbrk(str, remove); + str != nullptr; + str = strpbrk(str + 1, remove)) { + (*s)[str - str_start] = replacewith; + } +} + +void StripWhitespace(TProtoStringType *str) { + int str_length = str->length(); + + // Strip off leading whitespace. + int first = 0; + while (first < str_length && ascii_isspace(str->at(first))) { + ++first; + } + // If entire string is white space. + if (first == str_length) { + str->clear(); + return; + } + if (first > 0) { + str->erase(0, first); + str_length -= first; + } + + // Strip off trailing whitespace. + int last = str_length - 1; + while (last >= 0 && ascii_isspace(str->at(last))) { + --last; + } + if (last != (str_length - 1) && last >= 0) { + str->erase(last + 1, TProtoStringType::npos); + } +} + +// ---------------------------------------------------------------------- +// StringReplace() +// Replace the "old" pattern with the "new" pattern in a string, +// and append the result to "res". If replace_all is false, +// it only replaces the first instance of "old." +// ---------------------------------------------------------------------- + +void StringReplace(const TProtoStringType &s, const TProtoStringType &oldsub, + const TProtoStringType &newsub, bool replace_all, + TProtoStringType *res) { + if (oldsub.empty()) { + res->append(s); // if empty, append the given string. + return; + } + + TProtoStringType::size_type start_pos = 0; + TProtoStringType::size_type pos; + do { + pos = s.find(oldsub, start_pos); + if (pos == TProtoStringType::npos) { + break; + } + res->append(s, start_pos, pos - start_pos); + res->append(newsub); + start_pos = pos + oldsub.size(); // start searching again after the "old" + } while (replace_all); + res->append(s, start_pos, s.length() - start_pos); +} + +// ---------------------------------------------------------------------- +// StringReplace() +// Give me a string and two patterns "old" and "new", and I replace +// the first instance of "old" in the string with "new", if it +// exists. If "global" is true; call this repeatedly until it +// fails. RETURN a new string, regardless of whether the replacement +// happened or not. +// ---------------------------------------------------------------------- + +TProtoStringType StringReplace(const TProtoStringType &s, const TProtoStringType &oldsub, + const TProtoStringType &newsub, bool replace_all) { + TProtoStringType ret; + StringReplace(s, oldsub, newsub, replace_all, &ret); + return ret; +} + +// ---------------------------------------------------------------------- +// SplitStringUsing() +// Split a string using a character delimiter. Append the components +// to 'result'. +// +// Note: For multi-character delimiters, this routine will split on *ANY* of +// the characters in the string, not the entire string as a single delimiter. +// ---------------------------------------------------------------------- +template <typename ITR> +static inline void SplitStringToIteratorUsing(StringPiece full, + const char *delim, ITR &result) { + // Optimize the common case where delim is a single character. + if (delim[0] != '\0' && delim[1] == '\0') { + char c = delim[0]; + const char* p = full.data(); + const char* end = p + full.size(); + while (p != end) { + if (*p == c) { + ++p; + } else { + const char* start = p; + while (++p != end && *p != c); + *result++ = TProtoStringType(start, p - start); + } + } + return; + } + + TProtoStringType::size_type begin_index, end_index; + begin_index = full.find_first_not_of(delim); + while (begin_index != TProtoStringType::npos) { + end_index = full.find_first_of(delim, begin_index); + if (end_index == TProtoStringType::npos) { + *result++ = TProtoStringType(full.substr(begin_index)); + return; + } + *result++ = + TProtoStringType(full.substr(begin_index, (end_index - begin_index))); + begin_index = full.find_first_not_of(delim, end_index); + } +} + +void SplitStringUsing(StringPiece full, const char *delim, + std::vector<TProtoStringType> *result) { + std::back_insert_iterator<std::vector<TProtoStringType> > it(*result); + SplitStringToIteratorUsing(full, delim, it); +} + +// Split a string using a character delimiter. Append the components +// to 'result'. If there are consecutive delimiters, this function +// will return corresponding empty strings. The string is split into +// at most the specified number of pieces greedily. This means that the +// last piece may possibly be split further. To split into as many pieces +// as possible, specify 0 as the number of pieces. +// +// If "full" is the empty string, yields an empty string as the only value. +// +// If "pieces" is negative for some reason, it returns the whole string +// ---------------------------------------------------------------------- +template <typename ITR> +static inline void SplitStringToIteratorAllowEmpty(StringPiece full, + const char *delim, + int pieces, ITR &result) { + TProtoStringType::size_type begin_index, end_index; + begin_index = 0; + + for (int i = 0; (i < pieces-1) || (pieces == 0); i++) { + end_index = full.find_first_of(delim, begin_index); + if (end_index == TProtoStringType::npos) { + *result++ = TProtoStringType(full.substr(begin_index)); + return; + } + *result++ = + TProtoStringType(full.substr(begin_index, (end_index - begin_index))); + begin_index = end_index + 1; + } + *result++ = TProtoStringType(full.substr(begin_index)); +} + +void SplitStringAllowEmpty(StringPiece full, const char *delim, + std::vector<TProtoStringType> *result) { + std::back_insert_iterator<std::vector<TProtoStringType> > it(*result); + SplitStringToIteratorAllowEmpty(full, delim, 0, it); +} + +// ---------------------------------------------------------------------- +// JoinStrings() +// This merges a vector of string components with delim inserted +// as separaters between components. +// +// ---------------------------------------------------------------------- +template <class ITERATOR> +static void JoinStringsIterator(const ITERATOR &start, const ITERATOR &end, + const char *delim, TProtoStringType *result) { + GOOGLE_CHECK(result != nullptr); + result->clear(); + int delim_length = strlen(delim); + + // Precompute resulting length so we can reserve() memory in one shot. + int length = 0; + for (ITERATOR iter = start; iter != end; ++iter) { + if (iter != start) { + length += delim_length; + } + length += iter->size(); + } + result->reserve(length); + + // Now combine everything. + for (ITERATOR iter = start; iter != end; ++iter) { + if (iter != start) { + result->append(delim, delim_length); + } + result->append(iter->data(), iter->size()); + } +} + +void JoinStrings(const std::vector<TProtoStringType> &components, const char *delim, + TProtoStringType *result) { + JoinStringsIterator(components.begin(), components.end(), delim, result); +} + +// ---------------------------------------------------------------------- +// UnescapeCEscapeSequences() +// This does all the unescaping that C does: \ooo, \r, \n, etc +// Returns length of resulting string. +// The implementation of \x parses any positive number of hex digits, +// but it is an error if the value requires more than 8 bits, and the +// result is truncated to 8 bits. +// +// The second call stores its errors in a supplied string vector. +// If the string vector pointer is nullptr, it reports the errors with LOG(). +// ---------------------------------------------------------------------- + +#define IS_OCTAL_DIGIT(c) (((c) >= '0') && ((c) <= '7')) + +// Protocol buffers doesn't ever care about errors, but I don't want to remove +// the code. +#define LOG_STRING(LEVEL, VECTOR) GOOGLE_LOG_IF(LEVEL, false) + +int UnescapeCEscapeSequences(const char* source, char* dest) { + return UnescapeCEscapeSequences(source, dest, nullptr); +} + +int UnescapeCEscapeSequences(const char *source, char *dest, + std::vector<TProtoStringType> *errors) { + GOOGLE_DCHECK(errors == nullptr) << "Error reporting not implemented."; + + char* d = dest; + const char* p = source; + + // Small optimization for case where source = dest and there's no escaping + while ( p == d && *p != '\0' && *p != '\\' ) + p++, d++; + + while (*p != '\0') { + if (*p != '\\') { + *d++ = *p++; + } else { + switch ( *++p ) { // skip past the '\\' + case '\0': + LOG_STRING(ERROR, errors) << "String cannot end with \\"; + *d = '\0'; + return d - dest; // we're done with p + case 'a': *d++ = '\a'; break; + case 'b': *d++ = '\b'; break; + case 'f': *d++ = '\f'; break; + case 'n': *d++ = '\n'; break; + case 'r': *d++ = '\r'; break; + case 't': *d++ = '\t'; break; + case 'v': *d++ = '\v'; break; + case '\\': *d++ = '\\'; break; + case '?': *d++ = '\?'; break; // \? Who knew? + case '\'': *d++ = '\''; break; + case '"': *d++ = '\"'; break; + case '0': case '1': case '2': case '3': // octal digit: 1 to 3 digits + case '4': case '5': case '6': case '7': { + char ch = *p - '0'; + if ( IS_OCTAL_DIGIT(p[1]) ) + ch = ch * 8 + *++p - '0'; + if ( IS_OCTAL_DIGIT(p[1]) ) // safe (and easy) to do this twice + ch = ch * 8 + *++p - '0'; // now points at last digit + *d++ = ch; + break; + } + case 'x': case 'X': { + if (!isxdigit(p[1])) { + if (p[1] == '\0') { + LOG_STRING(ERROR, errors) << "String cannot end with \\x"; + } else { + LOG_STRING(ERROR, errors) << + "\\x cannot be followed by non-hex digit: \\" << *p << p[1]; + } + break; + } + unsigned int ch = 0; + const char *hex_start = p; + while (isxdigit(p[1])) // arbitrarily many hex digits + ch = (ch << 4) + hex_digit_to_int(*++p); + if (ch > 0xFF) + LOG_STRING(ERROR, errors) + << "Value of " + << "\\" << TProtoStringType(hex_start, p + 1 - hex_start) + << " exceeds 8 bits"; + *d++ = ch; + break; + } +#if 0 // TODO(kenton): Support \u and \U? Requires runetochar(). + case 'u': { + // \uhhhh => convert 4 hex digits to UTF-8 + char32 rune = 0; + const char *hex_start = p; + for (int i = 0; i < 4; ++i) { + if (isxdigit(p[1])) { // Look one char ahead. + rune = (rune << 4) + hex_digit_to_int(*++p); // Advance p. + } else { + LOG_STRING(ERROR, errors) + << "\\u must be followed by 4 hex digits: \\" + << TProtoStringType(hex_start, p+1-hex_start); + break; + } + } + d += runetochar(d, &rune); + break; + } + case 'U': { + // \Uhhhhhhhh => convert 8 hex digits to UTF-8 + char32 rune = 0; + const char *hex_start = p; + for (int i = 0; i < 8; ++i) { + if (isxdigit(p[1])) { // Look one char ahead. + // Don't change rune until we're sure this + // is within the Unicode limit, but do advance p. + char32 newrune = (rune << 4) + hex_digit_to_int(*++p); + if (newrune > 0x10FFFF) { + LOG_STRING(ERROR, errors) + << "Value of \\" + << TProtoStringType(hex_start, p + 1 - hex_start) + << " exceeds Unicode limit (0x10FFFF)"; + break; + } else { + rune = newrune; + } + } else { + LOG_STRING(ERROR, errors) + << "\\U must be followed by 8 hex digits: \\" + << TProtoStringType(hex_start, p+1-hex_start); + break; + } + } + d += runetochar(d, &rune); + break; + } +#endif + default: + LOG_STRING(ERROR, errors) << "Unknown escape sequence: \\" << *p; + } + p++; // read past letter we escaped + } + } + *d = '\0'; + return d - dest; +} + +// ---------------------------------------------------------------------- +// UnescapeCEscapeString() +// This does the same thing as UnescapeCEscapeSequences, but creates +// a new string. The caller does not need to worry about allocating +// a dest buffer. This should be used for non performance critical +// tasks such as printing debug messages. It is safe for src and dest +// to be the same. +// +// The second call stores its errors in a supplied string vector. +// If the string vector pointer is nullptr, it reports the errors with LOG(). +// +// In the first and second calls, the length of dest is returned. In the +// the third call, the new string is returned. +// ---------------------------------------------------------------------- +int UnescapeCEscapeString(const TProtoStringType &src, TProtoStringType *dest) { + return UnescapeCEscapeString(src, dest, nullptr); +} + +int UnescapeCEscapeString(const TProtoStringType &src, TProtoStringType *dest, + std::vector<TProtoStringType> *errors) { + std::unique_ptr<char[]> unescaped(new char[src.size() + 1]); + int len = UnescapeCEscapeSequences(src.c_str(), unescaped.get(), errors); + GOOGLE_CHECK(dest); + dest->assign(unescaped.get(), len); + return len; +} + +TProtoStringType UnescapeCEscapeString(const TProtoStringType &src) { + std::unique_ptr<char[]> unescaped(new char[src.size() + 1]); + int len = UnescapeCEscapeSequences(src.c_str(), unescaped.get(), nullptr); + return TProtoStringType(unescaped.get(), len); +} + +// ---------------------------------------------------------------------- +// CEscapeString() +// CHexEscapeString() +// Copies 'src' to 'dest', escaping dangerous characters using +// C-style escape sequences. This is very useful for preparing query +// flags. 'src' and 'dest' should not overlap. The 'Hex' version uses +// hexadecimal rather than octal sequences. +// Returns the number of bytes written to 'dest' (not including the \0) +// or -1 if there was insufficient space. +// +// Currently only \n, \r, \t, ", ', \ and !isprint() chars are escaped. +// ---------------------------------------------------------------------- +int CEscapeInternal(const char* src, int src_len, char* dest, + int dest_len, bool use_hex, bool utf8_safe) { + const char* src_end = src + src_len; + int used = 0; + bool last_hex_escape = false; // true if last output char was \xNN + + for (; src < src_end; src++) { + if (dest_len - used < 2) // Need space for two letter escape + return -1; + + bool is_hex_escape = false; + switch (*src) { + case '\n': dest[used++] = '\\'; dest[used++] = 'n'; break; + case '\r': dest[used++] = '\\'; dest[used++] = 'r'; break; + case '\t': dest[used++] = '\\'; dest[used++] = 't'; break; + case '\"': dest[used++] = '\\'; dest[used++] = '\"'; break; + case '\'': dest[used++] = '\\'; dest[used++] = '\''; break; + case '\\': dest[used++] = '\\'; dest[used++] = '\\'; break; + default: + // Note that if we emit \xNN and the src character after that is a hex + // digit then that digit must be escaped too to prevent it being + // interpreted as part of the character code by C. + if ((!utf8_safe || static_cast<uint8>(*src) < 0x80) && + (!isprint(*src) || + (last_hex_escape && isxdigit(*src)))) { + if (dest_len - used < 4) // need space for 4 letter escape + return -1; + sprintf(dest + used, (use_hex ? "\\x%02x" : "\\%03o"), + static_cast<uint8>(*src)); + is_hex_escape = use_hex; + used += 4; + } else { + dest[used++] = *src; break; + } + } + last_hex_escape = is_hex_escape; + } + + if (dest_len - used < 1) // make sure that there is room for \0 + return -1; + + dest[used] = '\0'; // doesn't count towards return value though + return used; +} + +// Calculates the length of the C-style escaped version of 'src'. +// Assumes that non-printable characters are escaped using octal sequences, and +// that UTF-8 bytes are not handled specially. +static inline size_t CEscapedLength(StringPiece src) { + static char c_escaped_len[256] = { + 4, 4, 4, 4, 4, 4, 4, 4, 4, 2, 2, 4, 4, 2, 4, 4, // \t, \n, \r + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 1, 1, 2, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, // ", ' + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // '0'..'9' + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 'A'..'O' + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, // 'P'..'Z', '\' + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 'a'..'o' + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 4, // 'p'..'z', DEL + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + }; + + size_t escaped_len = 0; + for (StringPiece::size_type i = 0; i < src.size(); ++i) { + unsigned char c = static_cast<unsigned char>(src[i]); + escaped_len += c_escaped_len[c]; + } + return escaped_len; +} + +// ---------------------------------------------------------------------- +// Escapes 'src' using C-style escape sequences, and appends the escaped string +// to 'dest'. This version is faster than calling CEscapeInternal as it computes +// the required space using a lookup table, and also does not do any special +// handling for Hex or UTF-8 characters. +// ---------------------------------------------------------------------- +void CEscapeAndAppend(StringPiece src, TProtoStringType *dest) { + size_t escaped_len = CEscapedLength(src); + if (escaped_len == src.size()) { + dest->append(src.data(), src.size()); + return; + } + + size_t cur_dest_len = dest->size(); + dest->resize(cur_dest_len + escaped_len); + char* append_ptr = &(*dest)[cur_dest_len]; + + for (StringPiece::size_type i = 0; i < src.size(); ++i) { + unsigned char c = static_cast<unsigned char>(src[i]); + switch (c) { + case '\n': *append_ptr++ = '\\'; *append_ptr++ = 'n'; break; + case '\r': *append_ptr++ = '\\'; *append_ptr++ = 'r'; break; + case '\t': *append_ptr++ = '\\'; *append_ptr++ = 't'; break; + case '\"': *append_ptr++ = '\\'; *append_ptr++ = '\"'; break; + case '\'': *append_ptr++ = '\\'; *append_ptr++ = '\''; break; + case '\\': *append_ptr++ = '\\'; *append_ptr++ = '\\'; break; + default: + if (!isprint(c)) { + *append_ptr++ = '\\'; + *append_ptr++ = '0' + c / 64; + *append_ptr++ = '0' + (c % 64) / 8; + *append_ptr++ = '0' + c % 8; + } else { + *append_ptr++ = c; + } + break; + } + } +} + +TProtoStringType CEscape(const TProtoStringType &src) { + TProtoStringType dest; + CEscapeAndAppend(src, &dest); + return dest; +} + +namespace strings { + +TProtoStringType Utf8SafeCEscape(const TProtoStringType &src) { + const int dest_length = src.size() * 4 + 1; // Maximum possible expansion + std::unique_ptr<char[]> dest(new char[dest_length]); + const int len = CEscapeInternal(src.data(), src.size(), + dest.get(), dest_length, false, true); + GOOGLE_DCHECK_GE(len, 0); + return TProtoStringType(dest.get(), len); +} + +TProtoStringType CHexEscape(const TProtoStringType &src) { + const int dest_length = src.size() * 4 + 1; // Maximum possible expansion + std::unique_ptr<char[]> dest(new char[dest_length]); + const int len = CEscapeInternal(src.data(), src.size(), + dest.get(), dest_length, true, false); + GOOGLE_DCHECK_GE(len, 0); + return TProtoStringType(dest.get(), len); +} + +} // namespace strings + +// ---------------------------------------------------------------------- +// strto32_adaptor() +// strtou32_adaptor() +// Implementation of strto[u]l replacements that have identical +// overflow and underflow characteristics for both ILP-32 and LP-64 +// platforms, including errno preservation in error-free calls. +// ---------------------------------------------------------------------- + +int32 strto32_adaptor(const char *nptr, char **endptr, int base) { + const int saved_errno = errno; + errno = 0; + const long result = strtol(nptr, endptr, base); + if (errno == ERANGE && result == LONG_MIN) { + return kint32min; + } else if (errno == ERANGE && result == LONG_MAX) { + return kint32max; + } else if (errno == 0 && result < kint32min) { + errno = ERANGE; + return kint32min; + } else if (errno == 0 && result > kint32max) { + errno = ERANGE; + return kint32max; + } + if (errno == 0) + errno = saved_errno; + return static_cast<int32>(result); +} + +uint32 strtou32_adaptor(const char *nptr, char **endptr, int base) { + const int saved_errno = errno; + errno = 0; + const unsigned long result = strtoul(nptr, endptr, base); + if (errno == ERANGE && result == ULONG_MAX) { + return kuint32max; + } else if (errno == 0 && result > kuint32max) { + errno = ERANGE; + return kuint32max; + } + if (errno == 0) + errno = saved_errno; + return static_cast<uint32>(result); +} + +inline bool safe_parse_sign(TProtoStringType *text /*inout*/, + bool *negative_ptr /*output*/) { + const char* start = text->data(); + const char* end = start + text->size(); + + // Consume whitespace. + while (start < end && (start[0] == ' ')) { + ++start; + } + while (start < end && (end[-1] == ' ')) { + --end; + } + if (start >= end) { + return false; + } + + // Consume sign. + *negative_ptr = (start[0] == '-'); + if (*negative_ptr || start[0] == '+') { + ++start; + if (start >= end) { + return false; + } + } + *text = text->substr(start - text->data(), end - start); + return true; +} + +template <typename IntType> +bool safe_parse_positive_int(TProtoStringType text, IntType *value_p) { + int base = 10; + IntType value = 0; + const IntType vmax = std::numeric_limits<IntType>::max(); + assert(vmax > 0); + assert(vmax >= base); + const IntType vmax_over_base = vmax / base; + const char* start = text.data(); + const char* end = start + text.size(); + // loop over digits + for (; start < end; ++start) { + unsigned char c = static_cast<unsigned char>(start[0]); + int digit = c - '0'; + if (digit >= base || digit < 0) { + *value_p = value; + return false; + } + if (value > vmax_over_base) { + *value_p = vmax; + return false; + } + value *= base; + if (value > vmax - digit) { + *value_p = vmax; + return false; + } + value += digit; + } + *value_p = value; + return true; +} + +template <typename IntType> +bool safe_parse_negative_int(const TProtoStringType &text, IntType *value_p) { + int base = 10; + IntType value = 0; + const IntType vmin = std::numeric_limits<IntType>::min(); + assert(vmin < 0); + assert(vmin <= 0 - base); + IntType vmin_over_base = vmin / base; + // 2003 c++ standard [expr.mul] + // "... the sign of the remainder is implementation-defined." + // Although (vmin/base)*base + vmin%base is always vmin. + // 2011 c++ standard tightens the spec but we cannot rely on it. + if (vmin % base > 0) { + vmin_over_base += 1; + } + const char* start = text.data(); + const char* end = start + text.size(); + // loop over digits + for (; start < end; ++start) { + unsigned char c = static_cast<unsigned char>(start[0]); + int digit = c - '0'; + if (digit >= base || digit < 0) { + *value_p = value; + return false; + } + if (value < vmin_over_base) { + *value_p = vmin; + return false; + } + value *= base; + if (value < vmin + digit) { + *value_p = vmin; + return false; + } + value -= digit; + } + *value_p = value; + return true; +} + +template <typename IntType> +bool safe_int_internal(TProtoStringType text, IntType *value_p) { + *value_p = 0; + bool negative; + if (!safe_parse_sign(&text, &negative)) { + return false; + } + if (!negative) { + return safe_parse_positive_int(text, value_p); + } else { + return safe_parse_negative_int(text, value_p); + } +} + +template <typename IntType> +bool safe_uint_internal(TProtoStringType text, IntType *value_p) { + *value_p = 0; + bool negative; + if (!safe_parse_sign(&text, &negative) || negative) { + return false; + } + return safe_parse_positive_int(text, value_p); +} + +// ---------------------------------------------------------------------- +// FastIntToBuffer() +// FastInt64ToBuffer() +// FastHexToBuffer() +// FastHex64ToBuffer() +// FastHex32ToBuffer() +// ---------------------------------------------------------------------- + +// Offset into buffer where FastInt64ToBuffer places the end of string +// null character. Also used by FastInt64ToBufferLeft. +static const int kFastInt64ToBufferOffset = 21; + +char *FastInt64ToBuffer(int64 i, char* buffer) { + // We could collapse the positive and negative sections, but that + // would be slightly slower for positive numbers... + // 22 bytes is enough to store -2**64, -18446744073709551616. + char* p = buffer + kFastInt64ToBufferOffset; + *p-- = '\0'; + if (i >= 0) { + do { + *p-- = '0' + i % 10; + i /= 10; + } while (i > 0); + return p + 1; + } else { + // On different platforms, % and / have different behaviors for + // negative numbers, so we need to jump through hoops to make sure + // we don't divide negative numbers. + if (i > -10) { + i = -i; + *p-- = '0' + i; + *p = '-'; + return p; + } else { + // Make sure we aren't at MIN_INT, in which case we can't say i = -i + i = i + 10; + i = -i; + *p-- = '0' + i % 10; + // Undo what we did a moment ago + i = i / 10 + 1; + do { + *p-- = '0' + i % 10; + i /= 10; + } while (i > 0); + *p = '-'; + return p; + } + } +} + +// Offset into buffer where FastInt32ToBuffer places the end of string +// null character. Also used by FastInt32ToBufferLeft +static const int kFastInt32ToBufferOffset = 11; + +// Yes, this is a duplicate of FastInt64ToBuffer. But, we need this for the +// compiler to generate 32 bit arithmetic instructions. It's much faster, at +// least with 32 bit binaries. +char *FastInt32ToBuffer(int32 i, char* buffer) { + // We could collapse the positive and negative sections, but that + // would be slightly slower for positive numbers... + // 12 bytes is enough to store -2**32, -4294967296. + char* p = buffer + kFastInt32ToBufferOffset; + *p-- = '\0'; + if (i >= 0) { + do { + *p-- = '0' + i % 10; + i /= 10; + } while (i > 0); + return p + 1; + } else { + // On different platforms, % and / have different behaviors for + // negative numbers, so we need to jump through hoops to make sure + // we don't divide negative numbers. + if (i > -10) { + i = -i; + *p-- = '0' + i; + *p = '-'; + return p; + } else { + // Make sure we aren't at MIN_INT, in which case we can't say i = -i + i = i + 10; + i = -i; + *p-- = '0' + i % 10; + // Undo what we did a moment ago + i = i / 10 + 1; + do { + *p-- = '0' + i % 10; + i /= 10; + } while (i > 0); + *p = '-'; + return p; + } + } +} + +char *FastHexToBuffer(int i, char* buffer) { + GOOGLE_CHECK(i >= 0) << "FastHexToBuffer() wants non-negative integers, not " << i; + + static const char *hexdigits = "0123456789abcdef"; + char *p = buffer + 21; + *p-- = '\0'; + do { + *p-- = hexdigits[i & 15]; // mod by 16 + i >>= 4; // divide by 16 + } while (i > 0); + return p + 1; +} + +char *InternalFastHexToBuffer(uint64 value, char* buffer, int num_byte) { + static const char *hexdigits = "0123456789abcdef"; + buffer[num_byte] = '\0'; + for (int i = num_byte - 1; i >= 0; i--) { +#ifdef _M_X64 + // MSVC x64 platform has a bug optimizing the uint32(value) in the #else + // block. Given that the uint32 cast was to improve performance on 32-bit + // platforms, we use 64-bit '&' directly. + buffer[i] = hexdigits[value & 0xf]; +#else + buffer[i] = hexdigits[uint32(value) & 0xf]; +#endif + value >>= 4; + } + return buffer; +} + +char *FastHex64ToBuffer(uint64 value, char* buffer) { + return InternalFastHexToBuffer(value, buffer, 16); +} + +char *FastHex32ToBuffer(uint32 value, char* buffer) { + return InternalFastHexToBuffer(value, buffer, 8); +} + +// ---------------------------------------------------------------------- +// FastInt32ToBufferLeft() +// FastUInt32ToBufferLeft() +// FastInt64ToBufferLeft() +// FastUInt64ToBufferLeft() +// +// Like the Fast*ToBuffer() functions above, these are intended for speed. +// Unlike the Fast*ToBuffer() functions, however, these functions write +// their output to the beginning of the buffer (hence the name, as the +// output is left-aligned). The caller is responsible for ensuring that +// the buffer has enough space to hold the output. +// +// Returns a pointer to the end of the string (i.e. the null character +// terminating the string). +// ---------------------------------------------------------------------- + +static const char two_ASCII_digits[100][2] = { + {'0','0'}, {'0','1'}, {'0','2'}, {'0','3'}, {'0','4'}, + {'0','5'}, {'0','6'}, {'0','7'}, {'0','8'}, {'0','9'}, + {'1','0'}, {'1','1'}, {'1','2'}, {'1','3'}, {'1','4'}, + {'1','5'}, {'1','6'}, {'1','7'}, {'1','8'}, {'1','9'}, + {'2','0'}, {'2','1'}, {'2','2'}, {'2','3'}, {'2','4'}, + {'2','5'}, {'2','6'}, {'2','7'}, {'2','8'}, {'2','9'}, + {'3','0'}, {'3','1'}, {'3','2'}, {'3','3'}, {'3','4'}, + {'3','5'}, {'3','6'}, {'3','7'}, {'3','8'}, {'3','9'}, + {'4','0'}, {'4','1'}, {'4','2'}, {'4','3'}, {'4','4'}, + {'4','5'}, {'4','6'}, {'4','7'}, {'4','8'}, {'4','9'}, + {'5','0'}, {'5','1'}, {'5','2'}, {'5','3'}, {'5','4'}, + {'5','5'}, {'5','6'}, {'5','7'}, {'5','8'}, {'5','9'}, + {'6','0'}, {'6','1'}, {'6','2'}, {'6','3'}, {'6','4'}, + {'6','5'}, {'6','6'}, {'6','7'}, {'6','8'}, {'6','9'}, + {'7','0'}, {'7','1'}, {'7','2'}, {'7','3'}, {'7','4'}, + {'7','5'}, {'7','6'}, {'7','7'}, {'7','8'}, {'7','9'}, + {'8','0'}, {'8','1'}, {'8','2'}, {'8','3'}, {'8','4'}, + {'8','5'}, {'8','6'}, {'8','7'}, {'8','8'}, {'8','9'}, + {'9','0'}, {'9','1'}, {'9','2'}, {'9','3'}, {'9','4'}, + {'9','5'}, {'9','6'}, {'9','7'}, {'9','8'}, {'9','9'} +}; + +char* FastUInt32ToBufferLeft(uint32 u, char* buffer) { + uint32 digits; + const char *ASCII_digits = nullptr; + // The idea of this implementation is to trim the number of divides to as few + // as possible by using multiplication and subtraction rather than mod (%), + // and by outputting two digits at a time rather than one. + // The huge-number case is first, in the hopes that the compiler will output + // that case in one branch-free block of code, and only output conditional + // branches into it from below. + if (u >= 1000000000) { // >= 1,000,000,000 + digits = u / 100000000; // 100,000,000 + ASCII_digits = two_ASCII_digits[digits]; + buffer[0] = ASCII_digits[0]; + buffer[1] = ASCII_digits[1]; + buffer += 2; +sublt100_000_000: + u -= digits * 100000000; // 100,000,000 +lt100_000_000: + digits = u / 1000000; // 1,000,000 + ASCII_digits = two_ASCII_digits[digits]; + buffer[0] = ASCII_digits[0]; + buffer[1] = ASCII_digits[1]; + buffer += 2; +sublt1_000_000: + u -= digits * 1000000; // 1,000,000 +lt1_000_000: + digits = u / 10000; // 10,000 + ASCII_digits = two_ASCII_digits[digits]; + buffer[0] = ASCII_digits[0]; + buffer[1] = ASCII_digits[1]; + buffer += 2; +sublt10_000: + u -= digits * 10000; // 10,000 +lt10_000: + digits = u / 100; + ASCII_digits = two_ASCII_digits[digits]; + buffer[0] = ASCII_digits[0]; + buffer[1] = ASCII_digits[1]; + buffer += 2; +sublt100: + u -= digits * 100; +lt100: + digits = u; + ASCII_digits = two_ASCII_digits[digits]; + buffer[0] = ASCII_digits[0]; + buffer[1] = ASCII_digits[1]; + buffer += 2; +done: + *buffer = 0; + return buffer; + } + + if (u < 100) { + digits = u; + if (u >= 10) goto lt100; + *buffer++ = '0' + digits; + goto done; + } + if (u < 10000) { // 10,000 + if (u >= 1000) goto lt10_000; + digits = u / 100; + *buffer++ = '0' + digits; + goto sublt100; + } + if (u < 1000000) { // 1,000,000 + if (u >= 100000) goto lt1_000_000; + digits = u / 10000; // 10,000 + *buffer++ = '0' + digits; + goto sublt10_000; + } + if (u < 100000000) { // 100,000,000 + if (u >= 10000000) goto lt100_000_000; + digits = u / 1000000; // 1,000,000 + *buffer++ = '0' + digits; + goto sublt1_000_000; + } + // we already know that u < 1,000,000,000 + digits = u / 100000000; // 100,000,000 + *buffer++ = '0' + digits; + goto sublt100_000_000; +} + +char* FastInt32ToBufferLeft(int32 i, char* buffer) { + uint32 u = 0; + if (i < 0) { + *buffer++ = '-'; + u -= i; + } else { + u = i; + } + return FastUInt32ToBufferLeft(u, buffer); +} + +char* FastUInt64ToBufferLeft(uint64 u64, char* buffer) { + int digits; + const char *ASCII_digits = nullptr; + + uint32 u = static_cast<uint32>(u64); + if (u == u64) return FastUInt32ToBufferLeft(u, buffer); + + uint64 top_11_digits = u64 / 1000000000; + buffer = FastUInt64ToBufferLeft(top_11_digits, buffer); + u = u64 - (top_11_digits * 1000000000); + + digits = u / 10000000; // 10,000,000 + GOOGLE_DCHECK_LT(digits, 100); + ASCII_digits = two_ASCII_digits[digits]; + buffer[0] = ASCII_digits[0]; + buffer[1] = ASCII_digits[1]; + buffer += 2; + u -= digits * 10000000; // 10,000,000 + digits = u / 100000; // 100,000 + ASCII_digits = two_ASCII_digits[digits]; + buffer[0] = ASCII_digits[0]; + buffer[1] = ASCII_digits[1]; + buffer += 2; + u -= digits * 100000; // 100,000 + digits = u / 1000; // 1,000 + ASCII_digits = two_ASCII_digits[digits]; + buffer[0] = ASCII_digits[0]; + buffer[1] = ASCII_digits[1]; + buffer += 2; + u -= digits * 1000; // 1,000 + digits = u / 10; + ASCII_digits = two_ASCII_digits[digits]; + buffer[0] = ASCII_digits[0]; + buffer[1] = ASCII_digits[1]; + buffer += 2; + u -= digits * 10; + digits = u; + *buffer++ = '0' + digits; + *buffer = 0; + return buffer; +} + +char* FastInt64ToBufferLeft(int64 i, char* buffer) { + uint64 u = 0; + if (i < 0) { + *buffer++ = '-'; + u -= i; + } else { + u = i; + } + return FastUInt64ToBufferLeft(u, buffer); +} + +// ---------------------------------------------------------------------- +// SimpleItoa() +// Description: converts an integer to a string. +// +// Return value: string +// ---------------------------------------------------------------------- + +TProtoStringType SimpleItoa(int i) { + char buffer[kFastToBufferSize]; + return (sizeof(i) == 4) ? + FastInt32ToBuffer(i, buffer) : + FastInt64ToBuffer(i, buffer); +} + +TProtoStringType SimpleItoa(unsigned int i) { + char buffer[kFastToBufferSize]; + return TProtoStringType(buffer, (sizeof(i) == 4) + ? FastUInt32ToBufferLeft(i, buffer) + : FastUInt64ToBufferLeft(i, buffer)); +} + +TProtoStringType SimpleItoa(long i) { + char buffer[kFastToBufferSize]; + return (sizeof(i) == 4) ? + FastInt32ToBuffer(i, buffer) : + FastInt64ToBuffer(i, buffer); +} + +TProtoStringType SimpleItoa(unsigned long i) { + char buffer[kFastToBufferSize]; + return TProtoStringType(buffer, (sizeof(i) == 4) + ? FastUInt32ToBufferLeft(i, buffer) + : FastUInt64ToBufferLeft(i, buffer)); +} + +TProtoStringType SimpleItoa(long long i) { + char buffer[kFastToBufferSize]; + return (sizeof(i) == 4) ? + FastInt32ToBuffer(i, buffer) : + FastInt64ToBuffer(i, buffer); +} + +TProtoStringType SimpleItoa(unsigned long long i) { + char buffer[kFastToBufferSize]; + return TProtoStringType(buffer, (sizeof(i) == 4) + ? FastUInt32ToBufferLeft(i, buffer) + : FastUInt64ToBufferLeft(i, buffer)); +} + +// ---------------------------------------------------------------------- +// SimpleDtoa() +// SimpleFtoa() +// DoubleToBuffer() +// FloatToBuffer() +// We want to print the value without losing precision, but we also do +// not want to print more digits than necessary. This turns out to be +// trickier than it sounds. Numbers like 0.2 cannot be represented +// exactly in binary. If we print 0.2 with a very large precision, +// e.g. "%.50g", we get "0.2000000000000000111022302462515654042363167". +// On the other hand, if we set the precision too low, we lose +// significant digits when printing numbers that actually need them. +// It turns out there is no precision value that does the right thing +// for all numbers. +// +// Our strategy is to first try printing with a precision that is never +// over-precise, then parse the result with strtod() to see if it +// matches. If not, we print again with a precision that will always +// give a precise result, but may use more digits than necessary. +// +// An arguably better strategy would be to use the algorithm described +// in "How to Print Floating-Point Numbers Accurately" by Steele & +// White, e.g. as implemented by David M. Gay's dtoa(). It turns out, +// however, that the following implementation is about as fast as +// DMG's code. Furthermore, DMG's code locks mutexes, which means it +// will not scale well on multi-core machines. DMG's code is slightly +// more accurate (in that it will never use more digits than +// necessary), but this is probably irrelevant for most users. +// +// Rob Pike and Ken Thompson also have an implementation of dtoa() in +// third_party/fmt/fltfmt.cc. Their implementation is similar to this +// one in that it makes guesses and then uses strtod() to check them. +// Their implementation is faster because they use their own code to +// generate the digits in the first place rather than use snprintf(), +// thus avoiding format string parsing overhead. However, this makes +// it considerably more complicated than the following implementation, +// and it is embedded in a larger library. If speed turns out to be +// an issue, we could re-implement this in terms of their +// implementation. +// ---------------------------------------------------------------------- + +TProtoStringType SimpleDtoa(double value) { + char buffer[kDoubleToBufferSize]; + return DoubleToBuffer(value, buffer); +} + +TProtoStringType SimpleFtoa(float value) { + char buffer[kFloatToBufferSize]; + return FloatToBuffer(value, buffer); +} + +static inline bool IsValidFloatChar(char c) { + return ('0' <= c && c <= '9') || + c == 'e' || c == 'E' || + c == '+' || c == '-'; +} + +void DelocalizeRadix(char* buffer) { + // Fast check: if the buffer has a normal decimal point, assume no + // translation is needed. + if (strchr(buffer, '.') != nullptr) return; + + // Find the first unknown character. + while (IsValidFloatChar(*buffer)) ++buffer; + + if (*buffer == '\0') { + // No radix character found. + return; + } + + // We are now pointing at the locale-specific radix character. Replace it + // with '.'. + *buffer = '.'; + ++buffer; + + if (!IsValidFloatChar(*buffer) && *buffer != '\0') { + // It appears the radix was a multi-byte character. We need to remove the + // extra bytes. + char* target = buffer; + do { ++buffer; } while (!IsValidFloatChar(*buffer) && *buffer != '\0'); + memmove(target, buffer, strlen(buffer) + 1); + } +} + +char* DoubleToBuffer(double value, char* buffer) { + // DBL_DIG is 15 for IEEE-754 doubles, which are used on almost all + // platforms these days. Just in case some system exists where DBL_DIG + // is significantly larger -- and risks overflowing our buffer -- we have + // this assert. + static_assert(DBL_DIG < 20, "DBL_DIG_is_too_big"); + + if (value == std::numeric_limits<double>::infinity()) { + strcpy(buffer, "inf"); + return buffer; + } else if (value == -std::numeric_limits<double>::infinity()) { + strcpy(buffer, "-inf"); + return buffer; + } else if (std::isnan(value)) { + strcpy(buffer, "nan"); + return buffer; + } + + int snprintf_result = + snprintf(buffer, kDoubleToBufferSize, "%.*g", DBL_DIG, value); + + // The snprintf should never overflow because the buffer is significantly + // larger than the precision we asked for. + GOOGLE_DCHECK(snprintf_result > 0 && snprintf_result < kDoubleToBufferSize); + + // We need to make parsed_value volatile in order to force the compiler to + // write it out to the stack. Otherwise, it may keep the value in a + // register, and if it does that, it may keep it as a long double instead + // of a double. This long double may have extra bits that make it compare + // unequal to "value" even though it would be exactly equal if it were + // truncated to a double. + volatile double parsed_value = internal::NoLocaleStrtod(buffer, nullptr); + if (parsed_value != value) { + snprintf_result = + snprintf(buffer, kDoubleToBufferSize, "%.*g", DBL_DIG + 2, value); + + // Should never overflow; see above. + GOOGLE_DCHECK(snprintf_result > 0 && snprintf_result < kDoubleToBufferSize); + } + + DelocalizeRadix(buffer); + return buffer; +} + +static int memcasecmp(const char *s1, const char *s2, size_t len) { + const unsigned char *us1 = reinterpret_cast<const unsigned char *>(s1); + const unsigned char *us2 = reinterpret_cast<const unsigned char *>(s2); + + for (size_t i = 0; i < len; i++) { + const int diff = + static_cast<int>(static_cast<unsigned char>(ascii_tolower(us1[i]))) - + static_cast<int>(static_cast<unsigned char>(ascii_tolower(us2[i]))); + if (diff != 0) return diff; + } + return 0; +} + +inline bool CaseEqual(StringPiece s1, StringPiece s2) { + if (s1.size() != s2.size()) return false; + return memcasecmp(s1.data(), s2.data(), s1.size()) == 0; +} + +bool safe_strtob(StringPiece str, bool* value) { + GOOGLE_CHECK(value != nullptr) << "nullptr output boolean given."; + if (CaseEqual(str, "true") || CaseEqual(str, "t") || + CaseEqual(str, "yes") || CaseEqual(str, "y") || + CaseEqual(str, "1")) { + *value = true; + return true; + } + if (CaseEqual(str, "false") || CaseEqual(str, "f") || + CaseEqual(str, "no") || CaseEqual(str, "n") || + CaseEqual(str, "0")) { + *value = false; + return true; + } + return false; +} + +bool safe_strtof(const char* str, float* value) { + char* endptr; + errno = 0; // errno only gets set on errors +#if defined(_WIN32) || defined (__hpux) // has no strtof() + *value = internal::NoLocaleStrtod(str, &endptr); +#else + *value = strtof(str, &endptr); +#endif + return *str != 0 && *endptr == 0 && errno == 0; +} + +bool safe_strtod(const char* str, double* value) { + char* endptr; + *value = internal::NoLocaleStrtod(str, &endptr); + if (endptr != str) { + while (ascii_isspace(*endptr)) ++endptr; + } + // Ignore range errors from strtod. The values it + // returns on underflow and overflow are the right + // fallback in a robust setting. + return *str != '\0' && *endptr == '\0'; +} + +bool safe_strto32(const TProtoStringType &str, int32 *value) { + return safe_int_internal(str, value); +} + +bool safe_strtou32(const TProtoStringType &str, uint32 *value) { + return safe_uint_internal(str, value); +} + +bool safe_strto64(const TProtoStringType &str, int64 *value) { + return safe_int_internal(str, value); +} + +bool safe_strtou64(const TProtoStringType &str, uint64 *value) { + return safe_uint_internal(str, value); +} + +char* FloatToBuffer(float value, char* buffer) { + // FLT_DIG is 6 for IEEE-754 floats, which are used on almost all + // platforms these days. Just in case some system exists where FLT_DIG + // is significantly larger -- and risks overflowing our buffer -- we have + // this assert. + static_assert(FLT_DIG < 10, "FLT_DIG_is_too_big"); + + if (value == std::numeric_limits<double>::infinity()) { + strcpy(buffer, "inf"); + return buffer; + } else if (value == -std::numeric_limits<double>::infinity()) { + strcpy(buffer, "-inf"); + return buffer; + } else if (std::isnan(value)) { + strcpy(buffer, "nan"); + return buffer; + } + + int snprintf_result = + snprintf(buffer, kFloatToBufferSize, "%.*g", FLT_DIG, value); + + // The snprintf should never overflow because the buffer is significantly + // larger than the precision we asked for. + GOOGLE_DCHECK(snprintf_result > 0 && snprintf_result < kFloatToBufferSize); + + float parsed_value; + if (!safe_strtof(buffer, &parsed_value) || parsed_value != value) { + snprintf_result = + snprintf(buffer, kFloatToBufferSize, "%.*g", FLT_DIG + 3, value); + + // Should never overflow; see above. + GOOGLE_DCHECK(snprintf_result > 0 && snprintf_result < kFloatToBufferSize); + } + + DelocalizeRadix(buffer); + return buffer; +} + +namespace strings { + +AlphaNum::AlphaNum(strings::Hex hex) { + char *const end = &digits[kFastToBufferSize]; + char *writer = end; + uint64 value = hex.value; + uint64 width = hex.spec; + // We accomplish minimum width by OR'ing in 0x10000 to the user's value, + // where 0x10000 is the smallest hex number that is as wide as the user + // asked for. + uint64 mask = ((static_cast<uint64>(1) << (width - 1) * 4)) | value; + static const char hexdigits[] = "0123456789abcdef"; + do { + *--writer = hexdigits[value & 0xF]; + value >>= 4; + mask >>= 4; + } while (mask != 0); + piece_data_ = writer; + piece_size_ = end - writer; +} + +} // namespace strings + +// ---------------------------------------------------------------------- +// StrCat() +// This merges the given strings or integers, with no delimiter. This +// is designed to be the fastest possible way to construct a string out +// of a mix of raw C strings, C++ strings, and integer values. +// ---------------------------------------------------------------------- + +// Append is merely a version of memcpy that returns the address of the byte +// after the area just overwritten. It comes in multiple flavors to minimize +// call overhead. +static char *Append1(char *out, const AlphaNum &x) { + if (x.size() > 0) { + memcpy(out, x.data(), x.size()); + out += x.size(); + } + return out; +} + +static char *Append2(char *out, const AlphaNum &x1, const AlphaNum &x2) { + if (x1.size() > 0) { + memcpy(out, x1.data(), x1.size()); + out += x1.size(); + } + if (x2.size() > 0) { + memcpy(out, x2.data(), x2.size()); + out += x2.size(); + } + return out; +} + +static char *Append4(char *out, const AlphaNum &x1, const AlphaNum &x2, + const AlphaNum &x3, const AlphaNum &x4) { + if (x1.size() > 0) { + memcpy(out, x1.data(), x1.size()); + out += x1.size(); + } + if (x2.size() > 0) { + memcpy(out, x2.data(), x2.size()); + out += x2.size(); + } + if (x3.size() > 0) { + memcpy(out, x3.data(), x3.size()); + out += x3.size(); + } + if (x4.size() > 0) { + memcpy(out, x4.data(), x4.size()); + out += x4.size(); + } + return out; +} + +TProtoStringType StrCat(const AlphaNum &a, const AlphaNum &b) { + TProtoStringType result; + result.resize(a.size() + b.size()); + char *const begin = &*result.begin(); + char *out = Append2(begin, a, b); + GOOGLE_DCHECK_EQ(out, begin + result.size()); + return result; +} + +TProtoStringType StrCat(const AlphaNum &a, const AlphaNum &b, const AlphaNum &c) { + TProtoStringType result; + result.resize(a.size() + b.size() + c.size()); + char *const begin = &*result.begin(); + char *out = Append2(begin, a, b); + out = Append1(out, c); + GOOGLE_DCHECK_EQ(out, begin + result.size()); + return result; +} + +TProtoStringType StrCat(const AlphaNum &a, const AlphaNum &b, const AlphaNum &c, + const AlphaNum &d) { + TProtoStringType result; + result.resize(a.size() + b.size() + c.size() + d.size()); + char *const begin = &*result.begin(); + char *out = Append4(begin, a, b, c, d); + GOOGLE_DCHECK_EQ(out, begin + result.size()); + return result; +} + +TProtoStringType StrCat(const AlphaNum &a, const AlphaNum &b, const AlphaNum &c, + const AlphaNum &d, const AlphaNum &e) { + TProtoStringType result; + result.resize(a.size() + b.size() + c.size() + d.size() + e.size()); + char *const begin = &*result.begin(); + char *out = Append4(begin, a, b, c, d); + out = Append1(out, e); + GOOGLE_DCHECK_EQ(out, begin + result.size()); + return result; +} + +TProtoStringType StrCat(const AlphaNum &a, const AlphaNum &b, const AlphaNum &c, + const AlphaNum &d, const AlphaNum &e, const AlphaNum &f) { + TProtoStringType result; + result.resize(a.size() + b.size() + c.size() + d.size() + e.size() + + f.size()); + char *const begin = &*result.begin(); + char *out = Append4(begin, a, b, c, d); + out = Append2(out, e, f); + GOOGLE_DCHECK_EQ(out, begin + result.size()); + return result; +} + +TProtoStringType StrCat(const AlphaNum &a, const AlphaNum &b, const AlphaNum &c, + const AlphaNum &d, const AlphaNum &e, const AlphaNum &f, + const AlphaNum &g) { + TProtoStringType result; + result.resize(a.size() + b.size() + c.size() + d.size() + e.size() + + f.size() + g.size()); + char *const begin = &*result.begin(); + char *out = Append4(begin, a, b, c, d); + out = Append2(out, e, f); + out = Append1(out, g); + GOOGLE_DCHECK_EQ(out, begin + result.size()); + return result; +} + +TProtoStringType StrCat(const AlphaNum &a, const AlphaNum &b, const AlphaNum &c, + const AlphaNum &d, const AlphaNum &e, const AlphaNum &f, + const AlphaNum &g, const AlphaNum &h) { + TProtoStringType result; + result.resize(a.size() + b.size() + c.size() + d.size() + e.size() + + f.size() + g.size() + h.size()); + char *const begin = &*result.begin(); + char *out = Append4(begin, a, b, c, d); + out = Append4(out, e, f, g, h); + GOOGLE_DCHECK_EQ(out, begin + result.size()); + return result; +} + +TProtoStringType StrCat(const AlphaNum &a, const AlphaNum &b, const AlphaNum &c, + const AlphaNum &d, const AlphaNum &e, const AlphaNum &f, + const AlphaNum &g, const AlphaNum &h, const AlphaNum &i) { + TProtoStringType result; + result.resize(a.size() + b.size() + c.size() + d.size() + e.size() + + f.size() + g.size() + h.size() + i.size()); + char *const begin = &*result.begin(); + char *out = Append4(begin, a, b, c, d); + out = Append4(out, e, f, g, h); + out = Append1(out, i); + GOOGLE_DCHECK_EQ(out, begin + result.size()); + return result; +} + +// It's possible to call StrAppend with a char * pointer that is partway into +// the string we're appending to. However the results of this are random. +// Therefore, check for this in debug mode. Use unsigned math so we only have +// to do one comparison. +#define GOOGLE_DCHECK_NO_OVERLAP(dest, src) \ + GOOGLE_DCHECK_GT(uintptr_t((src).data() - (dest).data()), \ + uintptr_t((dest).size())) + +void StrAppend(TProtoStringType *result, const AlphaNum &a) { + GOOGLE_DCHECK_NO_OVERLAP(*result, a); + result->append(a.data(), a.size()); +} + +void StrAppend(TProtoStringType *result, const AlphaNum &a, const AlphaNum &b) { + GOOGLE_DCHECK_NO_OVERLAP(*result, a); + GOOGLE_DCHECK_NO_OVERLAP(*result, b); + TProtoStringType::size_type old_size = result->size(); + result->resize(old_size + a.size() + b.size()); + char *const begin = &*result->begin(); + char *out = Append2(begin + old_size, a, b); + GOOGLE_DCHECK_EQ(out, begin + result->size()); +} + +void StrAppend(TProtoStringType *result, const AlphaNum &a, const AlphaNum &b, + const AlphaNum &c) { + GOOGLE_DCHECK_NO_OVERLAP(*result, a); + GOOGLE_DCHECK_NO_OVERLAP(*result, b); + GOOGLE_DCHECK_NO_OVERLAP(*result, c); + TProtoStringType::size_type old_size = result->size(); + result->resize(old_size + a.size() + b.size() + c.size()); + char *const begin = &*result->begin(); + char *out = Append2(begin + old_size, a, b); + out = Append1(out, c); + GOOGLE_DCHECK_EQ(out, begin + result->size()); +} + +void StrAppend(TProtoStringType *result, const AlphaNum &a, const AlphaNum &b, + const AlphaNum &c, const AlphaNum &d) { + GOOGLE_DCHECK_NO_OVERLAP(*result, a); + GOOGLE_DCHECK_NO_OVERLAP(*result, b); + GOOGLE_DCHECK_NO_OVERLAP(*result, c); + GOOGLE_DCHECK_NO_OVERLAP(*result, d); + TProtoStringType::size_type old_size = result->size(); + result->resize(old_size + a.size() + b.size() + c.size() + d.size()); + char *const begin = &*result->begin(); + char *out = Append4(begin + old_size, a, b, c, d); + GOOGLE_DCHECK_EQ(out, begin + result->size()); +} + +int GlobalReplaceSubstring(const TProtoStringType &substring, + const TProtoStringType &replacement, TProtoStringType *s) { + GOOGLE_CHECK(s != nullptr); + if (s->empty() || substring.empty()) + return 0; + TProtoStringType tmp; + int num_replacements = 0; + int pos = 0; + for (StringPiece::size_type match_pos = + s->find(substring.data(), pos, substring.length()); + match_pos != TProtoStringType::npos; pos = match_pos + substring.length(), + match_pos = s->find(substring.data(), pos, + substring.length())) { + ++num_replacements; + // Append the original content before the match. + tmp.append(*s, pos, match_pos - pos); + // Append the replacement for the match. + tmp.append(replacement.begin(), replacement.end()); + } + // Append the content after the last match. If no replacements were made, the + // original string is left untouched. + if (num_replacements > 0) { + tmp.append(*s, pos, s->length() - pos); + s->swap(tmp); + } + return num_replacements; +} + +int CalculateBase64EscapedLen(int input_len, bool do_padding) { + // Base64 encodes three bytes of input at a time. If the input is not + // divisible by three, we pad as appropriate. + // + // (from http://tools.ietf.org/html/rfc3548) + // Special processing is performed if fewer than 24 bits are available + // at the end of the data being encoded. A full encoding quantum is + // always completed at the end of a quantity. When fewer than 24 input + // bits are available in an input group, zero bits are added (on the + // right) to form an integral number of 6-bit groups. Padding at the + // end of the data is performed using the '=' character. Since all base + // 64 input is an integral number of octets, only the following cases + // can arise: + + + // Base64 encodes each three bytes of input into four bytes of output. + int len = (input_len / 3) * 4; + + if (input_len % 3 == 0) { + // (from http://tools.ietf.org/html/rfc3548) + // (1) the final quantum of encoding input is an integral multiple of 24 + // bits; here, the final unit of encoded output will be an integral + // multiple of 4 characters with no "=" padding, + } else if (input_len % 3 == 1) { + // (from http://tools.ietf.org/html/rfc3548) + // (2) the final quantum of encoding input is exactly 8 bits; here, the + // final unit of encoded output will be two characters followed by two + // "=" padding characters, or + len += 2; + if (do_padding) { + len += 2; + } + } else { // (input_len % 3 == 2) + // (from http://tools.ietf.org/html/rfc3548) + // (3) the final quantum of encoding input is exactly 16 bits; here, the + // final unit of encoded output will be three characters followed by one + // "=" padding character. + len += 3; + if (do_padding) { + len += 1; + } + } + + assert(len >= input_len); // make sure we didn't overflow + return len; +} + +// Base64Escape does padding, so this calculation includes padding. +int CalculateBase64EscapedLen(int input_len) { + return CalculateBase64EscapedLen(input_len, true); +} + +// ---------------------------------------------------------------------- +// int Base64Unescape() - base64 decoder +// int Base64Escape() - base64 encoder +// int WebSafeBase64Unescape() - Google's variation of base64 decoder +// int WebSafeBase64Escape() - Google's variation of base64 encoder +// +// Check out +// http://tools.ietf.org/html/rfc2045 for formal description, but what we +// care about is that... +// Take the encoded stuff in groups of 4 characters and turn each +// character into a code 0 to 63 thus: +// A-Z map to 0 to 25 +// a-z map to 26 to 51 +// 0-9 map to 52 to 61 +// +(- for WebSafe) maps to 62 +// /(_ for WebSafe) maps to 63 +// There will be four numbers, all less than 64 which can be represented +// by a 6 digit binary number (aaaaaa, bbbbbb, cccccc, dddddd respectively). +// Arrange the 6 digit binary numbers into three bytes as such: +// aaaaaabb bbbbcccc ccdddddd +// Equals signs (one or two) are used at the end of the encoded block to +// indicate that the text was not an integer multiple of three bytes long. +// ---------------------------------------------------------------------- + +int Base64UnescapeInternal(const char *src_param, int szsrc, + char *dest, int szdest, + const signed char* unbase64) { + static const char kPad64Equals = '='; + static const char kPad64Dot = '.'; + + int decode = 0; + int destidx = 0; + int state = 0; + unsigned int ch = 0; + unsigned int temp = 0; + + // If "char" is signed by default, using *src as an array index results in + // accessing negative array elements. Treat the input as a pointer to + // unsigned char to avoid this. + const unsigned char *src = reinterpret_cast<const unsigned char*>(src_param); + + // The GET_INPUT macro gets the next input character, skipping + // over any whitespace, and stopping when we reach the end of the + // string or when we read any non-data character. The arguments are + // an arbitrary identifier (used as a label for goto) and the number + // of data bytes that must remain in the input to avoid aborting the + // loop. +#define GET_INPUT(label, remain) \ + label: \ + --szsrc; \ + ch = *src++; \ + decode = unbase64[ch]; \ + if (decode < 0) { \ + if (ascii_isspace(ch) && szsrc >= remain) \ + goto label; \ + state = 4 - remain; \ + break; \ + } + + // if dest is null, we're just checking to see if it's legal input + // rather than producing output. (I suspect this could just be done + // with a regexp...). We duplicate the loop so this test can be + // outside it instead of in every iteration. + + if (dest) { + // This loop consumes 4 input bytes and produces 3 output bytes + // per iteration. We can't know at the start that there is enough + // data left in the string for a full iteration, so the loop may + // break out in the middle; if so 'state' will be set to the + // number of input bytes read. + + while (szsrc >= 4) { + // We'll start by optimistically assuming that the next four + // bytes of the string (src[0..3]) are four good data bytes + // (that is, no nulls, whitespace, padding chars, or illegal + // chars). We need to test src[0..2] for nulls individually + // before constructing temp to preserve the property that we + // never read past a null in the string (no matter how long + // szsrc claims the string is). + + if (!src[0] || !src[1] || !src[2] || + (temp = ((unsigned(unbase64[src[0]]) << 18) | + (unsigned(unbase64[src[1]]) << 12) | + (unsigned(unbase64[src[2]]) << 6) | + (unsigned(unbase64[src[3]])))) & 0x80000000) { + // Iff any of those four characters was bad (null, illegal, + // whitespace, padding), then temp's high bit will be set + // (because unbase64[] is -1 for all bad characters). + // + // We'll back up and resort to the slower decoder, which knows + // how to handle those cases. + + GET_INPUT(first, 4); + temp = decode; + GET_INPUT(second, 3); + temp = (temp << 6) | decode; + GET_INPUT(third, 2); + temp = (temp << 6) | decode; + GET_INPUT(fourth, 1); + temp = (temp << 6) | decode; + } else { + // We really did have four good data bytes, so advance four + // characters in the string. + + szsrc -= 4; + src += 4; + decode = -1; + ch = '\0'; + } + + // temp has 24 bits of input, so write that out as three bytes. + + if (destidx+3 > szdest) return -1; + dest[destidx+2] = temp; + temp >>= 8; + dest[destidx+1] = temp; + temp >>= 8; + dest[destidx] = temp; + destidx += 3; + } + } else { + while (szsrc >= 4) { + if (!src[0] || !src[1] || !src[2] || + (temp = ((unsigned(unbase64[src[0]]) << 18) | + (unsigned(unbase64[src[1]]) << 12) | + (unsigned(unbase64[src[2]]) << 6) | + (unsigned(unbase64[src[3]])))) & 0x80000000) { + GET_INPUT(first_no_dest, 4); + GET_INPUT(second_no_dest, 3); + GET_INPUT(third_no_dest, 2); + GET_INPUT(fourth_no_dest, 1); + } else { + szsrc -= 4; + src += 4; + decode = -1; + ch = '\0'; + } + destidx += 3; + } + } + +#undef GET_INPUT + + // if the loop terminated because we read a bad character, return + // now. + if (decode < 0 && ch != '\0' && + ch != kPad64Equals && ch != kPad64Dot && !ascii_isspace(ch)) + return -1; + + if (ch == kPad64Equals || ch == kPad64Dot) { + // if we stopped by hitting an '=' or '.', un-read that character -- we'll + // look at it again when we count to check for the proper number of + // equals signs at the end. + ++szsrc; + --src; + } else { + // This loop consumes 1 input byte per iteration. It's used to + // clean up the 0-3 input bytes remaining when the first, faster + // loop finishes. 'temp' contains the data from 'state' input + // characters read by the first loop. + while (szsrc > 0) { + --szsrc; + ch = *src++; + decode = unbase64[ch]; + if (decode < 0) { + if (ascii_isspace(ch)) { + continue; + } else if (ch == '\0') { + break; + } else if (ch == kPad64Equals || ch == kPad64Dot) { + // back up one character; we'll read it again when we check + // for the correct number of pad characters at the end. + ++szsrc; + --src; + break; + } else { + return -1; + } + } + + // Each input character gives us six bits of output. + temp = (temp << 6) | decode; + ++state; + if (state == 4) { + // If we've accumulated 24 bits of output, write that out as + // three bytes. + if (dest) { + if (destidx+3 > szdest) return -1; + dest[destidx+2] = temp; + temp >>= 8; + dest[destidx+1] = temp; + temp >>= 8; + dest[destidx] = temp; + } + destidx += 3; + state = 0; + temp = 0; + } + } + } + + // Process the leftover data contained in 'temp' at the end of the input. + int expected_equals = 0; + switch (state) { + case 0: + // Nothing left over; output is a multiple of 3 bytes. + break; + + case 1: + // Bad input; we have 6 bits left over. + return -1; + + case 2: + // Produce one more output byte from the 12 input bits we have left. + if (dest) { + if (destidx+1 > szdest) return -1; + temp >>= 4; + dest[destidx] = temp; + } + ++destidx; + expected_equals = 2; + break; + + case 3: + // Produce two more output bytes from the 18 input bits we have left. + if (dest) { + if (destidx+2 > szdest) return -1; + temp >>= 2; + dest[destidx+1] = temp; + temp >>= 8; + dest[destidx] = temp; + } + destidx += 2; + expected_equals = 1; + break; + + default: + // state should have no other values at this point. + GOOGLE_LOG(FATAL) << "This can't happen; base64 decoder state = " << state; + } + + // The remainder of the string should be all whitespace, mixed with + // exactly 0 equals signs, or exactly 'expected_equals' equals + // signs. (Always accepting 0 equals signs is a google extension + // not covered in the RFC, as is accepting dot as the pad character.) + + int equals = 0; + while (szsrc > 0 && *src) { + if (*src == kPad64Equals || *src == kPad64Dot) + ++equals; + else if (!ascii_isspace(*src)) + return -1; + --szsrc; + ++src; + } + + return (equals == 0 || equals == expected_equals) ? destidx : -1; +} + +// The arrays below were generated by the following code +// #include <sys/time.h> +// #include <stdlib.h> +// #include <string.h> +// #include <stdio.h> +// main() +// { +// static const char Base64[] = +// "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; +// const char *pos; +// int idx, i, j; +// printf(" "); +// for (i = 0; i < 255; i += 8) { +// for (j = i; j < i + 8; j++) { +// pos = strchr(Base64, j); +// if ((pos == nullptr) || (j == 0)) +// idx = -1; +// else +// idx = pos - Base64; +// if (idx == -1) +// printf(" %2d, ", idx); +// else +// printf(" %2d/""*%c*""/,", idx, j); +// } +// printf("\n "); +// } +// } +// +// where the value of "Base64[]" was replaced by one of the base-64 conversion +// tables from the functions below. +static const signed char kUnBase64[] = { + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, 62/*+*/, -1, -1, -1, 63/*/ */, + 52/*0*/, 53/*1*/, 54/*2*/, 55/*3*/, 56/*4*/, 57/*5*/, 58/*6*/, 59/*7*/, + 60/*8*/, 61/*9*/, -1, -1, -1, -1, -1, -1, + -1, 0/*A*/, 1/*B*/, 2/*C*/, 3/*D*/, 4/*E*/, 5/*F*/, 6/*G*/, + 7/*H*/, 8/*I*/, 9/*J*/, 10/*K*/, 11/*L*/, 12/*M*/, 13/*N*/, 14/*O*/, + 15/*P*/, 16/*Q*/, 17/*R*/, 18/*S*/, 19/*T*/, 20/*U*/, 21/*V*/, 22/*W*/, + 23/*X*/, 24/*Y*/, 25/*Z*/, -1, -1, -1, -1, -1, + -1, 26/*a*/, 27/*b*/, 28/*c*/, 29/*d*/, 30/*e*/, 31/*f*/, 32/*g*/, + 33/*h*/, 34/*i*/, 35/*j*/, 36/*k*/, 37/*l*/, 38/*m*/, 39/*n*/, 40/*o*/, + 41/*p*/, 42/*q*/, 43/*r*/, 44/*s*/, 45/*t*/, 46/*u*/, 47/*v*/, 48/*w*/, + 49/*x*/, 50/*y*/, 51/*z*/, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1 +}; +static const signed char kUnWebSafeBase64[] = { + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, 62/*-*/, -1, -1, + 52/*0*/, 53/*1*/, 54/*2*/, 55/*3*/, 56/*4*/, 57/*5*/, 58/*6*/, 59/*7*/, + 60/*8*/, 61/*9*/, -1, -1, -1, -1, -1, -1, + -1, 0/*A*/, 1/*B*/, 2/*C*/, 3/*D*/, 4/*E*/, 5/*F*/, 6/*G*/, + 7/*H*/, 8/*I*/, 9/*J*/, 10/*K*/, 11/*L*/, 12/*M*/, 13/*N*/, 14/*O*/, + 15/*P*/, 16/*Q*/, 17/*R*/, 18/*S*/, 19/*T*/, 20/*U*/, 21/*V*/, 22/*W*/, + 23/*X*/, 24/*Y*/, 25/*Z*/, -1, -1, -1, -1, 63/*_*/, + -1, 26/*a*/, 27/*b*/, 28/*c*/, 29/*d*/, 30/*e*/, 31/*f*/, 32/*g*/, + 33/*h*/, 34/*i*/, 35/*j*/, 36/*k*/, 37/*l*/, 38/*m*/, 39/*n*/, 40/*o*/, + 41/*p*/, 42/*q*/, 43/*r*/, 44/*s*/, 45/*t*/, 46/*u*/, 47/*v*/, 48/*w*/, + 49/*x*/, 50/*y*/, 51/*z*/, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1 +}; + +int WebSafeBase64Unescape(const char *src, int szsrc, char *dest, int szdest) { + return Base64UnescapeInternal(src, szsrc, dest, szdest, kUnWebSafeBase64); +} + +static bool Base64UnescapeInternal(const char *src, int slen, TProtoStringType *dest, + const signed char *unbase64) { + // Determine the size of the output string. Base64 encodes every 3 bytes into + // 4 characters. any leftover chars are added directly for good measure. + // This is documented in the base64 RFC: http://tools.ietf.org/html/rfc3548 + const int dest_len = 3 * (slen / 4) + (slen % 4); + + dest->resize(dest_len); + + // We are getting the destination buffer by getting the beginning of the + // string and converting it into a char *. + const int len = Base64UnescapeInternal(src, slen, string_as_array(dest), + dest_len, unbase64); + if (len < 0) { + dest->clear(); + return false; + } + + // could be shorter if there was padding + GOOGLE_DCHECK_LE(len, dest_len); + dest->erase(len); + + return true; +} + +bool Base64Unescape(StringPiece src, TProtoStringType *dest) { + return Base64UnescapeInternal(src.data(), src.size(), dest, kUnBase64); +} + +bool WebSafeBase64Unescape(StringPiece src, TProtoStringType *dest) { + return Base64UnescapeInternal(src.data(), src.size(), dest, kUnWebSafeBase64); +} + +int Base64EscapeInternal(const unsigned char *src, int szsrc, + char *dest, int szdest, const char *base64, + bool do_padding) { + static const char kPad64 = '='; + + if (szsrc <= 0) return 0; + + if (szsrc * 4 > szdest * 3) return 0; + + char *cur_dest = dest; + const unsigned char *cur_src = src; + + char *limit_dest = dest + szdest; + const unsigned char *limit_src = src + szsrc; + + // Three bytes of data encodes to four characters of ciphertext. + // So we can pump through three-byte chunks atomically. + while (cur_src < limit_src - 3) { // keep going as long as we have >= 32 bits + uint32 in = BigEndian::Load32(cur_src) >> 8; + + cur_dest[0] = base64[in >> 18]; + in &= 0x3FFFF; + cur_dest[1] = base64[in >> 12]; + in &= 0xFFF; + cur_dest[2] = base64[in >> 6]; + in &= 0x3F; + cur_dest[3] = base64[in]; + + cur_dest += 4; + cur_src += 3; + } + // To save time, we didn't update szdest or szsrc in the loop. So do it now. + szdest = limit_dest - cur_dest; + szsrc = limit_src - cur_src; + + /* now deal with the tail (<=3 bytes) */ + switch (szsrc) { + case 0: + // Nothing left; nothing more to do. + break; + case 1: { + // One byte left: this encodes to two characters, and (optionally) + // two pad characters to round out the four-character cipherblock. + if ((szdest -= 2) < 0) return 0; + uint32 in = cur_src[0]; + cur_dest[0] = base64[in >> 2]; + in &= 0x3; + cur_dest[1] = base64[in << 4]; + cur_dest += 2; + if (do_padding) { + if ((szdest -= 2) < 0) return 0; + cur_dest[0] = kPad64; + cur_dest[1] = kPad64; + cur_dest += 2; + } + break; + } + case 2: { + // Two bytes left: this encodes to three characters, and (optionally) + // one pad character to round out the four-character cipherblock. + if ((szdest -= 3) < 0) return 0; + uint32 in = BigEndian::Load16(cur_src); + cur_dest[0] = base64[in >> 10]; + in &= 0x3FF; + cur_dest[1] = base64[in >> 4]; + in &= 0x00F; + cur_dest[2] = base64[in << 2]; + cur_dest += 3; + if (do_padding) { + if ((szdest -= 1) < 0) return 0; + cur_dest[0] = kPad64; + cur_dest += 1; + } + break; + } + case 3: { + // Three bytes left: same as in the big loop above. We can't do this in + // the loop because the loop above always reads 4 bytes, and the fourth + // byte is past the end of the input. + if ((szdest -= 4) < 0) return 0; + uint32 in = (cur_src[0] << 16) + BigEndian::Load16(cur_src + 1); + cur_dest[0] = base64[in >> 18]; + in &= 0x3FFFF; + cur_dest[1] = base64[in >> 12]; + in &= 0xFFF; + cur_dest[2] = base64[in >> 6]; + in &= 0x3F; + cur_dest[3] = base64[in]; + cur_dest += 4; + break; + } + default: + // Should not be reached: blocks of 4 bytes are handled + // in the while loop before this switch statement. + GOOGLE_LOG(FATAL) << "Logic problem? szsrc = " << szsrc; + break; + } + return (cur_dest - dest); +} + +static const char kBase64Chars[] = +"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; + +static const char kWebSafeBase64Chars[] = +"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_"; + +int Base64Escape(const unsigned char *src, int szsrc, char *dest, int szdest) { + return Base64EscapeInternal(src, szsrc, dest, szdest, kBase64Chars, true); +} +int WebSafeBase64Escape(const unsigned char *src, int szsrc, char *dest, + int szdest, bool do_padding) { + return Base64EscapeInternal(src, szsrc, dest, szdest, + kWebSafeBase64Chars, do_padding); +} + +void Base64EscapeInternal(const unsigned char *src, int szsrc, + TProtoStringType *dest, bool do_padding, + const char *base64_chars) { + const int calc_escaped_size = + CalculateBase64EscapedLen(szsrc, do_padding); + dest->resize(calc_escaped_size); + const int escaped_len = Base64EscapeInternal(src, szsrc, + string_as_array(dest), + dest->size(), + base64_chars, + do_padding); + GOOGLE_DCHECK_EQ(calc_escaped_size, escaped_len); + dest->erase(escaped_len); +} + +void Base64Escape(const unsigned char *src, int szsrc, TProtoStringType *dest, + bool do_padding) { + Base64EscapeInternal(src, szsrc, dest, do_padding, kBase64Chars); +} + +void WebSafeBase64Escape(const unsigned char *src, int szsrc, TProtoStringType *dest, + bool do_padding) { + Base64EscapeInternal(src, szsrc, dest, do_padding, kWebSafeBase64Chars); +} + +void Base64Escape(StringPiece src, TProtoStringType *dest) { + Base64Escape(reinterpret_cast<const unsigned char*>(src.data()), + src.size(), dest, true); +} + +void WebSafeBase64Escape(StringPiece src, TProtoStringType *dest) { + WebSafeBase64Escape(reinterpret_cast<const unsigned char*>(src.data()), + src.size(), dest, false); +} + +void WebSafeBase64EscapeWithPadding(StringPiece src, TProtoStringType *dest) { + WebSafeBase64Escape(reinterpret_cast<const unsigned char*>(src.data()), + src.size(), dest, true); +} + +// Helper to append a Unicode code point to a string as UTF8, without bringing +// in any external dependencies. +int EncodeAsUTF8Char(uint32 code_point, char* output) { + uint32 tmp = 0; + int len = 0; + if (code_point <= 0x7f) { + tmp = code_point; + len = 1; + } else if (code_point <= 0x07ff) { + tmp = 0x0000c080 | + ((code_point & 0x07c0) << 2) | + (code_point & 0x003f); + len = 2; + } else if (code_point <= 0xffff) { + tmp = 0x00e08080 | + ((code_point & 0xf000) << 4) | + ((code_point & 0x0fc0) << 2) | + (code_point & 0x003f); + len = 3; + } else { + // UTF-16 is only defined for code points up to 0x10FFFF, and UTF-8 is + // normally only defined up to there as well. + tmp = 0xf0808080 | + ((code_point & 0x1c0000) << 6) | + ((code_point & 0x03f000) << 4) | + ((code_point & 0x000fc0) << 2) | + (code_point & 0x003f); + len = 4; + } + tmp = ghtonl(tmp); + memcpy(output, reinterpret_cast<const char*>(&tmp) + sizeof(tmp) - len, len); + return len; +} + +// Table of UTF-8 character lengths, based on first byte +static const unsigned char kUTF8LenTbl[256] = { + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 4, 4, 4, 4, 4, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}; + +// Return length of a single UTF-8 source character +int UTF8FirstLetterNumBytes(const char* src, int len) { + if (len == 0) { + return 0; + } + return kUTF8LenTbl[*reinterpret_cast<const uint8*>(src)]; +} + +// ---------------------------------------------------------------------- +// CleanStringLineEndings() +// Clean up a multi-line string to conform to Unix line endings. +// Reads from src and appends to dst, so usually dst should be empty. +// +// If there is no line ending at the end of a non-empty string, it can +// be added automatically. +// +// Four different types of input are correctly handled: +// +// - Unix/Linux files: line ending is LF: pass through unchanged +// +// - DOS/Windows files: line ending is CRLF: convert to LF +// +// - Legacy Mac files: line ending is CR: convert to LF +// +// - Garbled files: random line endings: convert gracefully +// lonely CR, lonely LF, CRLF: convert to LF +// +// @param src The multi-line string to convert +// @param dst The converted string is appended to this string +// @param auto_end_last_line Automatically terminate the last line +// +// Limitations: +// +// This does not do the right thing for CRCRLF files created by +// broken programs that do another Unix->DOS conversion on files +// that are already in CRLF format. For this, a two-pass approach +// brute-force would be needed that +// +// (1) determines the presence of LF (first one is ok) +// (2) if yes, removes any CR, else convert every CR to LF + +void CleanStringLineEndings(const TProtoStringType &src, TProtoStringType *dst, + bool auto_end_last_line) { + if (dst->empty()) { + dst->append(src); + CleanStringLineEndings(dst, auto_end_last_line); + } else { + TProtoStringType tmp = src; + CleanStringLineEndings(&tmp, auto_end_last_line); + dst->append(tmp); + } +} + +void CleanStringLineEndings(TProtoStringType *str, bool auto_end_last_line) { + ptrdiff_t output_pos = 0; + bool r_seen = false; + ptrdiff_t len = str->size(); + + char *p = &(*str)[0]; + + for (ptrdiff_t input_pos = 0; input_pos < len;) { + if (!r_seen && input_pos + 8 < len) { + arc_ui64 v = GOOGLE_UNALIGNED_LOAD64(p + input_pos); + // Loop over groups of 8 bytes at a time until we come across + // a word that has a byte whose value is less than or equal to + // '\r' (i.e. could contain a \n (0x0a) or a \r (0x0d) ). + // + // We use a has_less macro that quickly tests a whole 64-bit + // word to see if any of the bytes has a value < N. + // + // For more details, see: + // http://graphics.stanford.edu/~seander/bithacks.html#HasLessInWord +#define has_less(x, n) (((x) - ~0ULL / 255 * (n)) & ~(x) & ~0ULL / 255 * 128) + if (!has_less(v, '\r' + 1)) { +#undef has_less + // No byte in this word has a value that could be a \r or a \n + if (output_pos != input_pos) { + GOOGLE_UNALIGNED_STORE64(p + output_pos, v); + } + input_pos += 8; + output_pos += 8; + continue; + } + } + TProtoStringType::const_reference in = p[input_pos]; + if (in == '\r') { + if (r_seen) p[output_pos++] = '\n'; + r_seen = true; + } else if (in == '\n') { + if (input_pos != output_pos) + p[output_pos++] = '\n'; + else + output_pos++; + r_seen = false; + } else { + if (r_seen) p[output_pos++] = '\n'; + r_seen = false; + if (input_pos != output_pos) + p[output_pos++] = in; + else + output_pos++; + } + input_pos++; + } + if (r_seen || + (auto_end_last_line && output_pos > 0 && p[output_pos - 1] != '\n')) { + str->resize(output_pos + 1); + str->operator[](output_pos) = '\n'; + } else if (output_pos < len) { + str->resize(output_pos); + } +} + +namespace internal { + +// ---------------------------------------------------------------------- +// NoLocaleStrtod() +// This code will make you cry. +// ---------------------------------------------------------------------- + +namespace { + +// Returns a string identical to *input except that the character pointed to +// by radix_pos (which should be '.') is replaced with the locale-specific +// radix character. +TProtoStringType LocalizeRadix(const char *input, const char *radix_pos) { + // Determine the locale-specific radix character by calling sprintf() to + // print the number 1.5, then stripping off the digits. As far as I can + // tell, this is the only portable, thread-safe way to get the C library + // to divuldge the locale's radix character. No, localeconv() is NOT + // thread-safe. + char temp[16]; + int size = snprintf(temp, sizeof(temp), "%.1f", 1.5); + GOOGLE_CHECK_EQ(temp[0], '1'); + GOOGLE_CHECK_EQ(temp[size - 1], '5'); + GOOGLE_CHECK_LE(size, 6); + + // Now replace the '.' in the input with it. + TProtoStringType result; + result.reserve(strlen(input) + size - 3); + result.append(input, radix_pos); + result.append(temp + 1, size - 2); + result.append(radix_pos + 1); + return result; +} + +} // namespace + +double NoLocaleStrtod(const char *str, char **endptr) { + // We cannot simply set the locale to "C" temporarily with setlocale() + // as this is not thread-safe. Instead, we try to parse in the current + // locale first. If parsing stops at a '.' character, then this is a + // pretty good hint that we're actually in some other locale in which + // '.' is not the radix character. + + char *temp_endptr; + double result = strtod(str, &temp_endptr); + if (endptr != NULL) *endptr = temp_endptr; + if (*temp_endptr != '.') return result; + + // Parsing halted on a '.'. Perhaps we're in a different locale? Let's + // try to replace the '.' with a locale-specific radix character and + // try again. + TProtoStringType localized = LocalizeRadix(str, temp_endptr); + const char *localized_cstr = localized.c_str(); + char *localized_endptr; + result = strtod(localized_cstr, &localized_endptr); + if ((localized_endptr - localized_cstr) > (temp_endptr - str)) { + // This attempt got further, so replacing the decimal must have helped. + // Update endptr to point at the right location. + if (endptr != NULL) { + // size_diff is non-zero if the localized radix has multiple bytes. + int size_diff = localized.size() - strlen(str); + // const_cast is necessary to match the strtod() interface. + *endptr = const_cast<char *>( + str + (localized_endptr - localized_cstr - size_diff)); + } + } + + return result; +} + +} // namespace internal + +} // namespace protobuf +} // namespace google diff --git a/contrib/libs/protobuf_old/src/google/protobuf/stubs/strutil.h b/contrib/libs/protobuf_old/src/google/protobuf/stubs/strutil.h new file mode 100644 index 0000000000..ad08ad8988 --- /dev/null +++ b/contrib/libs/protobuf_old/src/google/protobuf/stubs/strutil.h @@ -0,0 +1,942 @@ +// 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. + +// from google3/strings/strutil.h + +#ifndef GOOGLE_PROTOBUF_STUBS_STRUTIL_H__ +#define GOOGLE_PROTOBUF_STUBS_STRUTIL_H__ + +#include <google/protobuf/stubs/common.h> +#include <google/protobuf/stubs/stringpiece.h> +#include <stdlib.h> + +#include <cstring> +#include <google/protobuf/port_def.inc> +#include <vector> + +namespace google { +namespace protobuf { + +#if defined(_MSC_VER) && _MSC_VER < 1800 +#define strtoll _strtoi64 +#define strtoull _strtoui64 +#elif defined(__DECCXX) && defined(__osf__) +// HP C++ on Tru64 does not have strtoll, but strtol is already 64-bit. +#define strtoll strtol +#define strtoull strtoul +#endif + +// ---------------------------------------------------------------------- +// ascii_isalnum() +// Check if an ASCII character is alphanumeric. We can't use ctype's +// isalnum() because it is affected by locale. This function is applied +// to identifiers in the protocol buffer language, not to natural-language +// strings, so locale should not be taken into account. +// ascii_isdigit() +// Like above, but only accepts digits. +// ascii_isspace() +// Check if the character is a space character. +// ---------------------------------------------------------------------- + +inline bool ascii_isalnum(char c) { + return ('a' <= c && c <= 'z') || + ('A' <= c && c <= 'Z') || + ('0' <= c && c <= '9'); +} + +inline bool ascii_isdigit(char c) { + return ('0' <= c && c <= '9'); +} + +inline bool ascii_isspace(char c) { + return c == ' ' || c == '\t' || c == '\n' || c == '\v' || c == '\f' || + c == '\r'; +} + +inline bool ascii_isupper(char c) { + return c >= 'A' && c <= 'Z'; +} + +inline bool ascii_islower(char c) { + return c >= 'a' && c <= 'z'; +} + +inline char ascii_toupper(char c) { + return ascii_islower(c) ? c - ('a' - 'A') : c; +} + +inline char ascii_tolower(char c) { + return ascii_isupper(c) ? c + ('a' - 'A') : c; +} + +inline int hex_digit_to_int(char c) { + /* Assume ASCII. */ + int x = static_cast<unsigned char>(c); + if (x > '9') { + x += 9; + } + return x & 0xf; +} + +// ---------------------------------------------------------------------- +// HasPrefixString() +// Check if a string begins with a given prefix. +// StripPrefixString() +// Given a string and a putative prefix, returns the string minus the +// prefix string if the prefix matches, otherwise the original +// string. +// ---------------------------------------------------------------------- +inline bool HasPrefixString(StringPiece str, StringPiece prefix) { + return str.size() >= prefix.size() && + memcmp(str.data(), prefix.data(), prefix.size()) == 0; +} + +inline TProtoStringType StripPrefixString(const TProtoStringType& str, + const TProtoStringType& prefix) { + if (HasPrefixString(str, prefix)) { + return str.substr(prefix.size()); + } else { + return str; + } +} + +// ---------------------------------------------------------------------- +// HasSuffixString() +// Return true if str ends in suffix. +// StripSuffixString() +// Given a string and a putative suffix, returns the string minus the +// suffix string if the suffix matches, otherwise the original +// string. +// ---------------------------------------------------------------------- +inline bool HasSuffixString(StringPiece str, StringPiece suffix) { + return str.size() >= suffix.size() && + memcmp(str.data() + str.size() - suffix.size(), suffix.data(), + suffix.size()) == 0; +} + +inline TProtoStringType StripSuffixString(const TProtoStringType& str, + const TProtoStringType& suffix) { + if (HasSuffixString(str, suffix)) { + return str.substr(0, str.size() - suffix.size()); + } else { + return str; + } +} + +// ---------------------------------------------------------------------- +// ReplaceCharacters +// Replaces any occurrence of the character 'remove' (or the characters +// in 'remove') with the character 'replacewith'. +// Good for keeping html characters or protocol characters (\t) out +// of places where they might cause a problem. +// StripWhitespace +// Removes whitespaces from both ends of the given string. +// ---------------------------------------------------------------------- +PROTOBUF_EXPORT void ReplaceCharacters(TProtoStringType* s, const char* remove, + char replacewith); + +PROTOBUF_EXPORT void StripWhitespace(TProtoStringType* s); + +// ---------------------------------------------------------------------- +// LowerString() +// UpperString() +// ToUpper() +// Convert the characters in "s" to lowercase or uppercase. ASCII-only: +// these functions intentionally ignore locale because they are applied to +// identifiers used in the Protocol Buffer language, not to natural-language +// strings. +// ---------------------------------------------------------------------- + +inline void LowerString(TProtoStringType* s) { + s->to_lower(); +} + +inline void UpperString(TProtoStringType* s) { + s->to_upper(); +} + +inline void ToUpper(TProtoStringType* s) { UpperString(s); } + +inline TProtoStringType ToUpper(const TProtoStringType& s) { + TProtoStringType out = s; + UpperString(&out); + return out; +} + +// ---------------------------------------------------------------------- +// StringReplace() +// Give me a string and two patterns "old" and "new", and I replace +// the first instance of "old" in the string with "new", if it +// exists. RETURN a new string, regardless of whether the replacement +// happened or not. +// ---------------------------------------------------------------------- + +PROTOBUF_EXPORT TProtoStringType StringReplace(const TProtoStringType& s, + const TProtoStringType& oldsub, + const TProtoStringType& newsub, + bool replace_all); + +// ---------------------------------------------------------------------- +// SplitStringUsing() +// Split a string using a character delimiter. Append the components +// to 'result'. If there are consecutive delimiters, this function skips +// over all of them. +// ---------------------------------------------------------------------- +PROTOBUF_EXPORT void SplitStringUsing(StringPiece full, const char* delim, + std::vector<TProtoStringType>* res); + +// Split a string using one or more byte delimiters, presented +// as a nul-terminated c string. Append the components to 'result'. +// If there are consecutive delimiters, this function will return +// corresponding empty strings. If you want to drop the empty +// strings, try SplitStringUsing(). +// +// If "full" is the empty string, yields an empty string as the only value. +// ---------------------------------------------------------------------- +PROTOBUF_EXPORT void SplitStringAllowEmpty(StringPiece full, const char* delim, + std::vector<TProtoStringType>* result); + +// ---------------------------------------------------------------------- +// Split() +// Split a string using a character delimiter. +// ---------------------------------------------------------------------- +inline std::vector<TProtoStringType> Split(StringPiece full, const char* delim, + bool skip_empty = true) { + std::vector<TProtoStringType> result; + if (skip_empty) { + SplitStringUsing(full, delim, &result); + } else { + SplitStringAllowEmpty(full, delim, &result); + } + return result; +} + +// ---------------------------------------------------------------------- +// JoinStrings() +// These methods concatenate a vector of strings into a C++ string, using +// the C-string "delim" as a separator between components. There are two +// flavors of the function, one flavor returns the concatenated string, +// another takes a pointer to the target string. In the latter case the +// target string is cleared and overwritten. +// ---------------------------------------------------------------------- +PROTOBUF_EXPORT void JoinStrings(const std::vector<TProtoStringType>& components, + const char* delim, TProtoStringType* result); + +inline TProtoStringType JoinStrings(const std::vector<TProtoStringType>& components, + const char* delim) { + TProtoStringType result; + JoinStrings(components, delim, &result); + return result; +} + +// ---------------------------------------------------------------------- +// UnescapeCEscapeSequences() +// Copies "source" to "dest", rewriting C-style escape sequences +// -- '\n', '\r', '\\', '\ooo', etc -- to their ASCII +// equivalents. "dest" must be sufficiently large to hold all +// the characters in the rewritten string (i.e. at least as large +// as strlen(source) + 1 should be safe, since the replacements +// are always shorter than the original escaped sequences). It's +// safe for source and dest to be the same. RETURNS the length +// of dest. +// +// It allows hex sequences \xhh, or generally \xhhhhh with an +// arbitrary number of hex digits, but all of them together must +// specify a value of a single byte (e.g. \x0045 is equivalent +// to \x45, and \x1234 is erroneous). +// +// It also allows escape sequences of the form \uhhhh (exactly four +// hex digits, upper or lower case) or \Uhhhhhhhh (exactly eight +// hex digits, upper or lower case) to specify a Unicode code +// point. The dest array will contain the UTF8-encoded version of +// that code-point (e.g., if source contains \u2019, then dest will +// contain the three bytes 0xE2, 0x80, and 0x99). +// +// Errors: In the first form of the call, errors are reported with +// LOG(ERROR). The same is true for the second form of the call if +// the pointer to the string std::vector is nullptr; otherwise, error +// messages are stored in the std::vector. In either case, the effect on +// the dest array is not defined, but rest of the source will be +// processed. +// ---------------------------------------------------------------------- + +PROTOBUF_EXPORT int UnescapeCEscapeSequences(const char* source, char* dest); +PROTOBUF_EXPORT int UnescapeCEscapeSequences(const char* source, char* dest, + std::vector<TProtoStringType>* errors); + +// ---------------------------------------------------------------------- +// UnescapeCEscapeString() +// This does the same thing as UnescapeCEscapeSequences, but creates +// a new string. The caller does not need to worry about allocating +// a dest buffer. This should be used for non performance critical +// tasks such as printing debug messages. It is safe for src and dest +// to be the same. +// +// The second call stores its errors in a supplied string vector. +// If the string vector pointer is nullptr, it reports the errors with LOG(). +// +// In the first and second calls, the length of dest is returned. In the +// the third call, the new string is returned. +// ---------------------------------------------------------------------- + +PROTOBUF_EXPORT int UnescapeCEscapeString(const TProtoStringType& src, + TProtoStringType* dest); +PROTOBUF_EXPORT int UnescapeCEscapeString(const TProtoStringType& src, + TProtoStringType* dest, + std::vector<TProtoStringType>* errors); +PROTOBUF_EXPORT TProtoStringType UnescapeCEscapeString(const TProtoStringType& src); + +// ---------------------------------------------------------------------- +// CEscape() +// Escapes 'src' using C-style escape sequences and returns the resulting +// string. +// +// Escaped chars: \n, \r, \t, ", ', \, and !isprint(). +// ---------------------------------------------------------------------- +PROTOBUF_EXPORT TProtoStringType CEscape(const TProtoStringType& src); + +// ---------------------------------------------------------------------- +// CEscapeAndAppend() +// Escapes 'src' using C-style escape sequences, and appends the escaped +// string to 'dest'. +// ---------------------------------------------------------------------- +PROTOBUF_EXPORT void CEscapeAndAppend(StringPiece src, TProtoStringType* dest); + +namespace strings { +// Like CEscape() but does not escape bytes with the upper bit set. +PROTOBUF_EXPORT TProtoStringType Utf8SafeCEscape(const TProtoStringType& src); + +// Like CEscape() but uses hex (\x) escapes instead of octals. +PROTOBUF_EXPORT TProtoStringType CHexEscape(const TProtoStringType& src); +} // namespace strings + +// ---------------------------------------------------------------------- +// strto32() +// strtou32() +// strto64() +// strtou64() +// Architecture-neutral plug compatible replacements for strtol() and +// strtoul(). Long's have different lengths on ILP-32 and LP-64 +// platforms, so using these is safer, from the point of view of +// overflow behavior, than using the standard libc functions. +// ---------------------------------------------------------------------- +PROTOBUF_EXPORT int32 strto32_adaptor(const char* nptr, char** endptr, + int base); +PROTOBUF_EXPORT uint32 strtou32_adaptor(const char* nptr, char** endptr, + int base); + +inline int32 strto32(const char *nptr, char **endptr, int base) { + if (sizeof(int32) == sizeof(long)) + return strtol(nptr, endptr, base); + else + return strto32_adaptor(nptr, endptr, base); +} + +inline uint32 strtou32(const char *nptr, char **endptr, int base) { + if (sizeof(uint32) == sizeof(unsigned long)) + return strtoul(nptr, endptr, base); + else + return strtou32_adaptor(nptr, endptr, base); +} + +// For now, long long is 64-bit on all the platforms we care about, so these +// functions can simply pass the call to strto[u]ll. +inline int64 strto64(const char *nptr, char **endptr, int base) { + static_assert(sizeof(int64) == sizeof(long long), + "sizeof_int64_is_not_sizeof_long_long"); + return strtoll(nptr, endptr, base); +} + +inline uint64 strtou64(const char *nptr, char **endptr, int base) { + static_assert(sizeof(uint64) == sizeof(unsigned long long), + "sizeof_uint64_is_not_sizeof_long_long"); + return strtoull(nptr, endptr, base); +} + +// ---------------------------------------------------------------------- +// safe_strtob() +// safe_strto32() +// safe_strtou32() +// safe_strto64() +// safe_strtou64() +// safe_strtof() +// safe_strtod() +// ---------------------------------------------------------------------- +PROTOBUF_EXPORT bool safe_strtob(StringPiece str, bool* value); + +PROTOBUF_EXPORT bool safe_strto32(const TProtoStringType& str, int32* value); +PROTOBUF_EXPORT bool safe_strtou32(const TProtoStringType& str, uint32* value); +inline bool safe_strto32(const char* str, int32* value) { + return safe_strto32(TProtoStringType(str), value); +} +inline bool safe_strto32(StringPiece str, int32* value) { + return safe_strto32(str.ToString(), value); +} +inline bool safe_strtou32(const char* str, uint32* value) { + return safe_strtou32(TProtoStringType(str), value); +} +inline bool safe_strtou32(StringPiece str, uint32* value) { + return safe_strtou32(str.ToString(), value); +} + +PROTOBUF_EXPORT bool safe_strto64(const TProtoStringType& str, int64* value); +PROTOBUF_EXPORT bool safe_strtou64(const TProtoStringType& str, uint64* value); +inline bool safe_strto64(const char* str, int64* value) { + return safe_strto64(TProtoStringType(str), value); +} +inline bool safe_strto64(StringPiece str, int64* value) { + return safe_strto64(str.ToString(), value); +} +inline bool safe_strtou64(const char* str, uint64* value) { + return safe_strtou64(TProtoStringType(str), value); +} +inline bool safe_strtou64(StringPiece str, uint64* value) { + return safe_strtou64(str.ToString(), value); +} + +PROTOBUF_EXPORT bool safe_strtof(const char* str, float* value); +PROTOBUF_EXPORT bool safe_strtod(const char* str, double* value); +inline bool safe_strtof(const TProtoStringType& str, float* value) { + return safe_strtof(str.c_str(), value); +} +inline bool safe_strtod(const TProtoStringType& str, double* value) { + return safe_strtod(str.c_str(), value); +} +inline bool safe_strtof(StringPiece str, float* value) { + return safe_strtof(str.ToString(), value); +} +inline bool safe_strtod(StringPiece str, double* value) { + return safe_strtod(str.ToString(), value); +} + +// ---------------------------------------------------------------------- +// FastIntToBuffer() +// FastHexToBuffer() +// FastHex64ToBuffer() +// FastHex32ToBuffer() +// FastTimeToBuffer() +// These are intended for speed. FastIntToBuffer() assumes the +// integer is non-negative. FastHexToBuffer() puts output in +// hex rather than decimal. FastTimeToBuffer() puts the output +// into RFC822 format. +// +// FastHex64ToBuffer() puts a 64-bit unsigned value in hex-format, +// padded to exactly 16 bytes (plus one byte for '\0') +// +// FastHex32ToBuffer() puts a 32-bit unsigned value in hex-format, +// padded to exactly 8 bytes (plus one byte for '\0') +// +// All functions take the output buffer as an arg. +// They all return a pointer to the beginning of the output, +// which may not be the beginning of the input buffer. +// ---------------------------------------------------------------------- + +// Suggested buffer size for FastToBuffer functions. Also works with +// DoubleToBuffer() and FloatToBuffer(). +static const int kFastToBufferSize = 32; + +PROTOBUF_EXPORT char* FastInt32ToBuffer(int32 i, char* buffer); +PROTOBUF_EXPORT char* FastInt64ToBuffer(int64 i, char* buffer); +char* FastUInt32ToBuffer(uint32 i, char* buffer); // inline below +char* FastUInt64ToBuffer(uint64 i, char* buffer); // inline below +PROTOBUF_EXPORT char* FastHexToBuffer(int i, char* buffer); +PROTOBUF_EXPORT char* FastHex64ToBuffer(uint64 i, char* buffer); +PROTOBUF_EXPORT char* FastHex32ToBuffer(uint32 i, char* buffer); + +// at least 22 bytes long +inline char* FastIntToBuffer(int i, char* buffer) { + return (sizeof(i) == 4 ? + FastInt32ToBuffer(i, buffer) : FastInt64ToBuffer(i, buffer)); +} +inline char* FastUIntToBuffer(unsigned int i, char* buffer) { + return (sizeof(i) == 4 ? + FastUInt32ToBuffer(i, buffer) : FastUInt64ToBuffer(i, buffer)); +} +inline char* FastLongToBuffer(long i, char* buffer) { + return (sizeof(i) == 4 ? + FastInt32ToBuffer(i, buffer) : FastInt64ToBuffer(i, buffer)); +} +inline char* FastULongToBuffer(unsigned long i, char* buffer) { + return (sizeof(i) == 4 ? + FastUInt32ToBuffer(i, buffer) : FastUInt64ToBuffer(i, buffer)); +} + +// ---------------------------------------------------------------------- +// FastInt32ToBufferLeft() +// FastUInt32ToBufferLeft() +// FastInt64ToBufferLeft() +// FastUInt64ToBufferLeft() +// +// Like the Fast*ToBuffer() functions above, these are intended for speed. +// Unlike the Fast*ToBuffer() functions, however, these functions write +// their output to the beginning of the buffer (hence the name, as the +// output is left-aligned). The caller is responsible for ensuring that +// the buffer has enough space to hold the output. +// +// Returns a pointer to the end of the string (i.e. the null character +// terminating the string). +// ---------------------------------------------------------------------- + +PROTOBUF_EXPORT char* FastInt32ToBufferLeft(int32 i, char* buffer); +PROTOBUF_EXPORT char* FastUInt32ToBufferLeft(uint32 i, char* buffer); +PROTOBUF_EXPORT char* FastInt64ToBufferLeft(int64 i, char* buffer); +PROTOBUF_EXPORT char* FastUInt64ToBufferLeft(uint64 i, char* buffer); + +// Just define these in terms of the above. +inline char* FastUInt32ToBuffer(uint32 i, char* buffer) { + FastUInt32ToBufferLeft(i, buffer); + return buffer; +} +inline char* FastUInt64ToBuffer(uint64 i, char* buffer) { + FastUInt64ToBufferLeft(i, buffer); + return buffer; +} + +inline TProtoStringType SimpleBtoa(bool value) { return value ? "true" : "false"; } + +// ---------------------------------------------------------------------- +// SimpleItoa() +// Description: converts an integer to a string. +// +// Return value: string +// ---------------------------------------------------------------------- +PROTOBUF_EXPORT TProtoStringType SimpleItoa(int i); +PROTOBUF_EXPORT TProtoStringType SimpleItoa(unsigned int i); +PROTOBUF_EXPORT TProtoStringType SimpleItoa(long i); +PROTOBUF_EXPORT TProtoStringType SimpleItoa(unsigned long i); +PROTOBUF_EXPORT TProtoStringType SimpleItoa(long long i); +PROTOBUF_EXPORT TProtoStringType SimpleItoa(unsigned long long i); + +// ---------------------------------------------------------------------- +// SimpleDtoa() +// SimpleFtoa() +// DoubleToBuffer() +// FloatToBuffer() +// Description: converts a double or float to a string which, if +// passed to NoLocaleStrtod(), will produce the exact same original double +// (except in case of NaN; all NaNs are considered the same value). +// We try to keep the string short but it's not guaranteed to be as +// short as possible. +// +// DoubleToBuffer() and FloatToBuffer() write the text to the given +// buffer and return it. The buffer must be at least +// kDoubleToBufferSize bytes for doubles and kFloatToBufferSize +// bytes for floats. kFastToBufferSize is also guaranteed to be large +// enough to hold either. +// +// Return value: string +// ---------------------------------------------------------------------- +PROTOBUF_EXPORT TProtoStringType SimpleDtoa(double value); +PROTOBUF_EXPORT TProtoStringType SimpleFtoa(float value); + +PROTOBUF_EXPORT char* DoubleToBuffer(double i, char* buffer); +PROTOBUF_EXPORT char* FloatToBuffer(float i, char* buffer); + +// In practice, doubles should never need more than 24 bytes and floats +// should never need more than 14 (including null terminators), but we +// overestimate to be safe. +static const int kDoubleToBufferSize = 32; +static const int kFloatToBufferSize = 24; + +namespace strings { + +enum PadSpec { + NO_PAD = 1, + ZERO_PAD_2, + ZERO_PAD_3, + ZERO_PAD_4, + ZERO_PAD_5, + ZERO_PAD_6, + ZERO_PAD_7, + ZERO_PAD_8, + ZERO_PAD_9, + ZERO_PAD_10, + ZERO_PAD_11, + ZERO_PAD_12, + ZERO_PAD_13, + ZERO_PAD_14, + ZERO_PAD_15, + ZERO_PAD_16, +}; + +struct Hex { + uint64 value; + enum PadSpec spec; + template <class Int> + explicit Hex(Int v, PadSpec s = NO_PAD) + : spec(s) { + // Prevent sign-extension by casting integers to + // their unsigned counterparts. +#ifdef LANG_CXX11 + static_assert( + sizeof(v) == 1 || sizeof(v) == 2 || sizeof(v) == 4 || sizeof(v) == 8, + "Unknown integer type"); +#endif + value = sizeof(v) == 1 ? static_cast<uint8>(v) + : sizeof(v) == 2 ? static_cast<uint16>(v) + : sizeof(v) == 4 ? static_cast<uint32>(v) + : static_cast<uint64>(v); + } +}; + +struct PROTOBUF_EXPORT AlphaNum { + const char *piece_data_; // move these to string_ref eventually + size_t piece_size_; // move these to string_ref eventually + + char digits[kFastToBufferSize]; + + // No bool ctor -- bools convert to an integral type. + // A bool ctor would also convert incoming pointers (bletch). + + AlphaNum(int i32) + : piece_data_(digits), + piece_size_(FastInt32ToBufferLeft(i32, digits) - &digits[0]) {} + AlphaNum(unsigned int u32) + : piece_data_(digits), + piece_size_(FastUInt32ToBufferLeft(u32, digits) - &digits[0]) {} + AlphaNum(long long i64) + : piece_data_(digits), + piece_size_(FastInt64ToBufferLeft(i64, digits) - &digits[0]) {} + AlphaNum(unsigned long long u64) + : piece_data_(digits), + piece_size_(FastUInt64ToBufferLeft(u64, digits) - &digits[0]) {} + + // Note: on some architectures, "long" is only 32 bits, not 64, but the + // performance hit of using FastInt64ToBufferLeft to handle 32-bit values + // is quite minor. + AlphaNum(long i64) + : piece_data_(digits), + piece_size_(FastInt64ToBufferLeft(i64, digits) - &digits[0]) {} + AlphaNum(unsigned long u64) + : piece_data_(digits), + piece_size_(FastUInt64ToBufferLeft(u64, digits) - &digits[0]) {} + + AlphaNum(float f) + : piece_data_(digits), piece_size_(strlen(FloatToBuffer(f, digits))) {} + AlphaNum(double f) + : piece_data_(digits), piece_size_(strlen(DoubleToBuffer(f, digits))) {} + + AlphaNum(Hex hex); + + AlphaNum(const char* c_str) + : piece_data_(c_str), piece_size_(strlen(c_str)) {} + // TODO: Add a string_ref constructor, eventually + // AlphaNum(const StringPiece &pc) : piece(pc) {} + + AlphaNum(const TProtoStringType& str) + : piece_data_(str.data()), piece_size_(str.size()) {} + + AlphaNum(StringPiece str) + : piece_data_(str.data()), piece_size_(str.size()) {} + + size_t size() const { return piece_size_; } + const char *data() const { return piece_data_; } + + private: + // Use ":" not ':' + AlphaNum(char c); // NOLINT(runtime/explicit) + + // Disallow copy and assign. + AlphaNum(const AlphaNum&); + void operator=(const AlphaNum&); +}; + +} // namespace strings + +using strings::AlphaNum; + +// ---------------------------------------------------------------------- +// StrCat() +// This merges the given strings or numbers, with no delimiter. This +// is designed to be the fastest possible way to construct a string out +// of a mix of raw C strings, strings, bool values, +// and numeric values. +// +// Don't use this for user-visible strings. The localization process +// works poorly on strings built up out of fragments. +// +// For clarity and performance, don't use StrCat when appending to a +// string. In particular, avoid using any of these (anti-)patterns: +// str.append(StrCat(...) +// str += StrCat(...) +// str = StrCat(str, ...) +// where the last is the worse, with the potential to change a loop +// from a linear time operation with O(1) dynamic allocations into a +// quadratic time operation with O(n) dynamic allocations. StrAppend +// is a better choice than any of the above, subject to the restriction +// of StrAppend(&str, a, b, c, ...) that none of the a, b, c, ... may +// be a reference into str. +// ---------------------------------------------------------------------- + +PROTOBUF_EXPORT TProtoStringType StrCat(const AlphaNum& a, const AlphaNum& b); +PROTOBUF_EXPORT TProtoStringType StrCat(const AlphaNum& a, const AlphaNum& b, + const AlphaNum& c); +PROTOBUF_EXPORT TProtoStringType StrCat(const AlphaNum& a, const AlphaNum& b, + const AlphaNum& c, const AlphaNum& d); +PROTOBUF_EXPORT TProtoStringType StrCat(const AlphaNum& a, const AlphaNum& b, + const AlphaNum& c, const AlphaNum& d, + const AlphaNum& e); +PROTOBUF_EXPORT TProtoStringType StrCat(const AlphaNum& a, const AlphaNum& b, + const AlphaNum& c, const AlphaNum& d, + const AlphaNum& e, const AlphaNum& f); +PROTOBUF_EXPORT TProtoStringType StrCat(const AlphaNum& a, const AlphaNum& b, + const AlphaNum& c, const AlphaNum& d, + const AlphaNum& e, const AlphaNum& f, + const AlphaNum& g); +PROTOBUF_EXPORT TProtoStringType StrCat(const AlphaNum& a, const AlphaNum& b, + const AlphaNum& c, const AlphaNum& d, + const AlphaNum& e, const AlphaNum& f, + const AlphaNum& g, const AlphaNum& h); +PROTOBUF_EXPORT TProtoStringType StrCat(const AlphaNum& a, const AlphaNum& b, + const AlphaNum& c, const AlphaNum& d, + const AlphaNum& e, const AlphaNum& f, + const AlphaNum& g, const AlphaNum& h, + const AlphaNum& i); + +inline TProtoStringType StrCat(const AlphaNum& a) { + return TProtoStringType(a.data(), a.size()); +} + +// ---------------------------------------------------------------------- +// StrAppend() +// Same as above, but adds the output to the given string. +// WARNING: For speed, StrAppend does not try to check each of its input +// arguments to be sure that they are not a subset of the string being +// appended to. That is, while this will work: +// +// string s = "foo"; +// s += s; +// +// This will not (necessarily) work: +// +// string s = "foo"; +// StrAppend(&s, s); +// +// Note: while StrCat supports appending up to 9 arguments, StrAppend +// is currently limited to 4. That's rarely an issue except when +// automatically transforming StrCat to StrAppend, and can easily be +// worked around as consecutive calls to StrAppend are quite efficient. +// ---------------------------------------------------------------------- + +PROTOBUF_EXPORT void StrAppend(TProtoStringType* dest, const AlphaNum& a); +PROTOBUF_EXPORT void StrAppend(TProtoStringType* dest, const AlphaNum& a, + const AlphaNum& b); +PROTOBUF_EXPORT void StrAppend(TProtoStringType* dest, const AlphaNum& a, + const AlphaNum& b, const AlphaNum& c); +PROTOBUF_EXPORT void StrAppend(TProtoStringType* dest, const AlphaNum& a, + const AlphaNum& b, const AlphaNum& c, + const AlphaNum& d); + +// ---------------------------------------------------------------------- +// Join() +// These methods concatenate a range of components into a C++ string, using +// the C-string "delim" as a separator between components. +// ---------------------------------------------------------------------- +template <typename Iterator> +void Join(Iterator start, Iterator end, const char* delim, + TProtoStringType* result) { + for (Iterator it = start; it != end; ++it) { + if (it != start) { + result->append(delim); + } + StrAppend(result, *it); + } +} + +template <typename Range> +TProtoStringType Join(const Range& components, const char* delim) { + TProtoStringType result; + Join(components.begin(), components.end(), delim, &result); + return result; +} + +// ---------------------------------------------------------------------- +// ToHex() +// Return a lower-case hex string representation of the given integer. +// ---------------------------------------------------------------------- +PROTOBUF_EXPORT TProtoStringType ToHex(uint64 num); + +// ---------------------------------------------------------------------- +// GlobalReplaceSubstring() +// Replaces all instances of a substring in a string. Does nothing +// if 'substring' is empty. Returns the number of replacements. +// +// NOTE: The string pieces must not overlap s. +// ---------------------------------------------------------------------- +PROTOBUF_EXPORT int GlobalReplaceSubstring(const TProtoStringType& substring, + const TProtoStringType& replacement, + TProtoStringType* s); + +// ---------------------------------------------------------------------- +// Base64Unescape() +// Converts "src" which is encoded in Base64 to its binary equivalent and +// writes it to "dest". If src contains invalid characters, dest is cleared +// and the function returns false. Returns true on success. +// ---------------------------------------------------------------------- +PROTOBUF_EXPORT bool Base64Unescape(StringPiece src, TProtoStringType* dest); + +// ---------------------------------------------------------------------- +// WebSafeBase64Unescape() +// This is a variation of Base64Unescape which uses '-' instead of '+', and +// '_' instead of '/'. src is not null terminated, instead specify len. I +// recommend that slen<szdest, but we honor szdest anyway. +// RETURNS the length of dest, or -1 if src contains invalid chars. + +// The variation that stores into a string clears the string first, and +// returns false (with dest empty) if src contains invalid chars; for +// this version src and dest must be different strings. +// ---------------------------------------------------------------------- +PROTOBUF_EXPORT int WebSafeBase64Unescape(const char* src, int slen, char* dest, + int szdest); +PROTOBUF_EXPORT bool WebSafeBase64Unescape(StringPiece src, TProtoStringType* dest); + +// Return the length to use for the output buffer given to the base64 escape +// routines. Make sure to use the same value for do_padding in both. +// This function may return incorrect results if given input_len values that +// are extremely high, which should happen rarely. +PROTOBUF_EXPORT int CalculateBase64EscapedLen(int input_len, bool do_padding); +// Use this version when calling Base64Escape without a do_padding arg. +PROTOBUF_EXPORT int CalculateBase64EscapedLen(int input_len); + +// ---------------------------------------------------------------------- +// Base64Escape() +// WebSafeBase64Escape() +// Encode "src" to "dest" using base64 encoding. +// src is not null terminated, instead specify len. +// 'dest' should have at least CalculateBase64EscapedLen() length. +// RETURNS the length of dest. +// The WebSafe variation use '-' instead of '+' and '_' instead of '/' +// so that we can place the out in the URL or cookies without having +// to escape them. It also has an extra parameter "do_padding", +// which when set to false will prevent padding with "=". +// ---------------------------------------------------------------------- +PROTOBUF_EXPORT int Base64Escape(const unsigned char* src, int slen, char* dest, + int szdest); +PROTOBUF_EXPORT int WebSafeBase64Escape(const unsigned char* src, int slen, + char* dest, int szdest, + bool do_padding); +// Encode src into dest with padding. +PROTOBUF_EXPORT void Base64Escape(StringPiece src, TProtoStringType* dest); +// Encode src into dest web-safely without padding. +PROTOBUF_EXPORT void WebSafeBase64Escape(StringPiece src, TProtoStringType* dest); +// Encode src into dest web-safely with padding. +PROTOBUF_EXPORT void WebSafeBase64EscapeWithPadding(StringPiece src, + TProtoStringType* dest); + +PROTOBUF_EXPORT void Base64Escape(const unsigned char* src, int szsrc, + TProtoStringType* dest, bool do_padding); +PROTOBUF_EXPORT void WebSafeBase64Escape(const unsigned char* src, int szsrc, + TProtoStringType* dest, bool do_padding); + +inline bool IsValidCodePoint(uint32 code_point) { + return code_point < 0xD800 || + (code_point >= 0xE000 && code_point <= 0x10FFFF); +} + +static const int UTFmax = 4; +// ---------------------------------------------------------------------- +// EncodeAsUTF8Char() +// Helper to append a Unicode code point to a string as UTF8, without bringing +// in any external dependencies. The output buffer must be as least 4 bytes +// large. +// ---------------------------------------------------------------------- +PROTOBUF_EXPORT int EncodeAsUTF8Char(uint32 code_point, char* output); + +// ---------------------------------------------------------------------- +// UTF8FirstLetterNumBytes() +// Length of the first UTF-8 character. +// ---------------------------------------------------------------------- +PROTOBUF_EXPORT int UTF8FirstLetterNumBytes(const char* src, int len); + +// From google3/third_party/absl/strings/escaping.h + +// ---------------------------------------------------------------------- +// CleanStringLineEndings() +// Clean up a multi-line string to conform to Unix line endings. +// Reads from src and appends to dst, so usually dst should be empty. +// +// If there is no line ending at the end of a non-empty string, it can +// be added automatically. +// +// Four different types of input are correctly handled: +// +// - Unix/Linux files: line ending is LF: pass through unchanged +// +// - DOS/Windows files: line ending is CRLF: convert to LF +// +// - Legacy Mac files: line ending is CR: convert to LF +// +// - Garbled files: random line endings: convert gracefully +// lonely CR, lonely LF, CRLF: convert to LF +// +// @param src The multi-line string to convert +// @param dst The converted string is appended to this string +// @param auto_end_last_line Automatically terminate the last line +// +// Limitations: +// +// This does not do the right thing for CRCRLF files created by +// broken programs that do another Unix->DOS conversion on files +// that are already in CRLF format. For this, a two-pass approach +// brute-force would be needed that +// +// (1) determines the presence of LF (first one is ok) +// (2) if yes, removes any CR, else convert every CR to LF +PROTOBUF_EXPORT void CleanStringLineEndings(const TProtoStringType& src, + TProtoStringType* dst, + bool auto_end_last_line); + +// Same as above, but transforms the argument in place. +PROTOBUF_EXPORT void CleanStringLineEndings(TProtoStringType* str, + bool auto_end_last_line); + +namespace strings { +inline bool EndsWith(StringPiece text, StringPiece suffix) { + return suffix.empty() || + (text.size() >= suffix.size() && + memcmp(text.data() + (text.size() - suffix.size()), suffix.data(), + suffix.size()) == 0); +} +} // namespace strings + +namespace internal { + +// A locale-independent version of the standard strtod(), which always +// uses a dot as the decimal separator. +double NoLocaleStrtod(const char* str, char** endptr); + +} // namespace internal + +} // namespace protobuf +} // namespace google + +#include <google/protobuf/port_undef.inc> + +#endif // GOOGLE_PROTOBUF_STUBS_STRUTIL_H__ diff --git a/contrib/libs/protobuf_old/src/google/protobuf/stubs/substitute.cc b/contrib/libs/protobuf_old/src/google/protobuf/stubs/substitute.cc new file mode 100644 index 0000000000..bd2ccd2588 --- /dev/null +++ b/contrib/libs/protobuf_old/src/google/protobuf/stubs/substitute.cc @@ -0,0 +1,136 @@ +// 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: kenton@google.com (Kenton Varda) + +#include <google/protobuf/stubs/substitute.h> + +#include <google/protobuf/stubs/logging.h> +#include <google/protobuf/stubs/strutil.h> +#include <google/protobuf/stubs/stl_util.h> + +namespace google { +namespace protobuf { +namespace strings { + +using internal::SubstituteArg; + +// Returns the number of args in arg_array which were passed explicitly +// to Substitute(). +static int CountSubstituteArgs(const SubstituteArg* const* args_array) { + int count = 0; + while (args_array[count] != nullptr && args_array[count]->size() != -1) { + ++count; + } + return count; +} + +TProtoStringType Substitute(const TProtoStringType& format, const SubstituteArg& arg0, + const SubstituteArg& arg1, const SubstituteArg& arg2, + const SubstituteArg& arg3, const SubstituteArg& arg4, + const SubstituteArg& arg5, const SubstituteArg& arg6, + const SubstituteArg& arg7, const SubstituteArg& arg8, + const SubstituteArg& arg9) { + TProtoStringType result; + SubstituteAndAppend(&result, format.c_str(), arg0, arg1, arg2, arg3, arg4, + arg5, arg6, arg7, arg8, arg9); + return result; +} + +void SubstituteAndAppend(TProtoStringType* output, const char* format, + const SubstituteArg& arg0, const SubstituteArg& arg1, + const SubstituteArg& arg2, const SubstituteArg& arg3, + const SubstituteArg& arg4, const SubstituteArg& arg5, + const SubstituteArg& arg6, const SubstituteArg& arg7, + const SubstituteArg& arg8, const SubstituteArg& arg9) { + const SubstituteArg* const args_array[] = { + &arg0, &arg1, &arg2, &arg3, &arg4, &arg5, &arg6, &arg7, &arg8, &arg9, nullptr + }; + + // Determine total size needed. + int size = 0; + for (int i = 0; format[i] != '\0'; i++) { + if (format[i] == '$') { + if (ascii_isdigit(format[i+1])) { + int index = format[i+1] - '0'; + if (args_array[index]->size() == -1) { + GOOGLE_LOG(DFATAL) + << "strings::Substitute format string invalid: asked for \"$" + << index << "\", but only " << CountSubstituteArgs(args_array) + << " args were given. Full format string was: \"" + << CEscape(format) << "\"."; + return; + } + size += args_array[index]->size(); + ++i; // Skip next char. + } else if (format[i+1] == '$') { + ++size; + ++i; // Skip next char. + } else { + GOOGLE_LOG(DFATAL) + << "Invalid strings::Substitute() format string: \"" + << CEscape(format) << "\"."; + return; + } + } else { + ++size; + } + } + + if (size == 0) return; + + // Build the string. + int original_size = output->size(); + STLStringResizeUninitialized(output, original_size + size); + char* target = string_as_array(output) + original_size; + for (int i = 0; format[i] != '\0'; i++) { + if (format[i] == '$') { + if (ascii_isdigit(format[i+1])) { + unsigned int index = format[i+1] - '0'; + assert(index < 10); + const SubstituteArg* src = args_array[index]; + memcpy(target, src->data(), src->size()); + target += src->size(); + ++i; // Skip next char. + } else if (format[i+1] == '$') { + *target++ = '$'; + ++i; // Skip next char. + } + } else { + *target++ = format[i]; + } + } + + GOOGLE_DCHECK_EQ(target - output->data(), output->size()); +} + +} // namespace strings +} // namespace protobuf +} // namespace google diff --git a/contrib/libs/protobuf_old/src/google/protobuf/stubs/substitute.h b/contrib/libs/protobuf_old/src/google/protobuf/stubs/substitute.h new file mode 100644 index 0000000000..ccd8129726 --- /dev/null +++ b/contrib/libs/protobuf_old/src/google/protobuf/stubs/substitute.h @@ -0,0 +1,178 @@ +// 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: kenton@google.com (Kenton Varda) +// from google3/strings/substitute.h + +#include <google/protobuf/stubs/common.h> +#include <google/protobuf/stubs/stringpiece.h> +#include <google/protobuf/stubs/strutil.h> + +#include <string> + +#ifndef GOOGLE_PROTOBUF_STUBS_SUBSTITUTE_H_ +#define GOOGLE_PROTOBUF_STUBS_SUBSTITUTE_H_ + +#include <google/protobuf/port_def.inc> + +namespace google { +namespace protobuf { +namespace strings { + +// ---------------------------------------------------------------------- +// strings::Substitute() +// strings::SubstituteAndAppend() +// Kind of like StringPrintf, but different. +// +// Example: +// string GetMessage(string first_name, string last_name, int age) { +// return strings::Substitute("My name is $0 $1 and I am $2 years old.", +// first_name, last_name, age); +// } +// +// Differences from StringPrintf: +// * The format string does not identify the types of arguments. +// Instead, the magic of C++ deals with this for us. See below +// for a list of accepted types. +// * Substitutions in the format string are identified by a '$' +// followed by a digit. So, you can use arguments out-of-order and +// use the same argument multiple times. +// * It's much faster than StringPrintf. +// +// Supported types: +// * Strings (const char*, const string&) +// * Note that this means you do not have to add .c_str() to all of +// your strings. In fact, you shouldn't; it will be slower. +// * int32, int64, uint32, uint64: Formatted using SimpleItoa(). +// * float, double: Formatted using SimpleFtoa() and SimpleDtoa(). +// * bool: Printed as "true" or "false". +// +// SubstituteAndAppend() is like Substitute() but appends the result to +// *output. Example: +// +// string str; +// strings::SubstituteAndAppend(&str, +// "My name is $0 $1 and I am $2 years old.", +// first_name, last_name, age); +// +// Substitute() is significantly faster than StringPrintf(). For very +// large strings, it may be orders of magnitude faster. +// ---------------------------------------------------------------------- + +namespace internal { // Implementation details. + +class SubstituteArg { + public: + inline SubstituteArg(const char* value) + : text_(value), size_(strlen(text_)) {} + inline SubstituteArg(const TProtoStringType& value) + : text_(value.data()), size_(value.size()) {} + inline SubstituteArg(const StringPiece value) + : text_(value.data()), size_(value.size()) {} + + // Indicates that no argument was given. + inline explicit SubstituteArg() + : text_(nullptr), size_(-1) {} + + // Primitives + // We don't overload for signed and unsigned char because if people are + // explicitly declaring their chars as signed or unsigned then they are + // probably actually using them as 8-bit integers and would probably + // prefer an integer representation. But, we don't really know. So, we + // make the caller decide what to do. + inline SubstituteArg(char value) + : text_(scratch_), size_(1) { scratch_[0] = value; } + inline SubstituteArg(short value) + : text_(FastInt32ToBuffer(value, scratch_)), size_(strlen(text_)) {} + inline SubstituteArg(unsigned short value) + : text_(FastUInt32ToBuffer(value, scratch_)), size_(strlen(text_)) {} + inline SubstituteArg(int value) + : text_(FastInt32ToBuffer(value, scratch_)), size_(strlen(text_)) {} + inline SubstituteArg(unsigned int value) + : text_(FastUInt32ToBuffer(value, scratch_)), size_(strlen(text_)) {} + inline SubstituteArg(long value) + : text_(FastLongToBuffer(value, scratch_)), size_(strlen(text_)) {} + inline SubstituteArg(unsigned long value) + : text_(FastULongToBuffer(value, scratch_)), size_(strlen(text_)) {} + inline SubstituteArg(long long value) + : text_(FastInt64ToBuffer(value, scratch_)), size_(strlen(text_)) {} + inline SubstituteArg(unsigned long long value) + : text_(FastUInt64ToBuffer(value, scratch_)), size_(strlen(text_)) {} + inline SubstituteArg(float value) + : text_(FloatToBuffer(value, scratch_)), size_(strlen(text_)) {} + inline SubstituteArg(double value) + : text_(DoubleToBuffer(value, scratch_)), size_(strlen(text_)) {} + inline SubstituteArg(bool value) + : text_(value ? "true" : "false"), size_(strlen(text_)) {} + + inline const char* data() const { return text_; } + inline int size() const { return size_; } + + private: + const char* text_; + int size_; + char scratch_[kFastToBufferSize]; +}; + +} // namespace internal + +PROTOBUF_EXPORT TProtoStringType Substitute( + const TProtoStringType& format, + const internal::SubstituteArg& arg0 = internal::SubstituteArg(), + const internal::SubstituteArg& arg1 = internal::SubstituteArg(), + const internal::SubstituteArg& arg2 = internal::SubstituteArg(), + const internal::SubstituteArg& arg3 = internal::SubstituteArg(), + const internal::SubstituteArg& arg4 = internal::SubstituteArg(), + const internal::SubstituteArg& arg5 = internal::SubstituteArg(), + const internal::SubstituteArg& arg6 = internal::SubstituteArg(), + const internal::SubstituteArg& arg7 = internal::SubstituteArg(), + const internal::SubstituteArg& arg8 = internal::SubstituteArg(), + const internal::SubstituteArg& arg9 = internal::SubstituteArg()); + +PROTOBUF_EXPORT void SubstituteAndAppend( + TProtoStringType* output, const char* format, + const internal::SubstituteArg& arg0 = internal::SubstituteArg(), + const internal::SubstituteArg& arg1 = internal::SubstituteArg(), + const internal::SubstituteArg& arg2 = internal::SubstituteArg(), + const internal::SubstituteArg& arg3 = internal::SubstituteArg(), + const internal::SubstituteArg& arg4 = internal::SubstituteArg(), + const internal::SubstituteArg& arg5 = internal::SubstituteArg(), + const internal::SubstituteArg& arg6 = internal::SubstituteArg(), + const internal::SubstituteArg& arg7 = internal::SubstituteArg(), + const internal::SubstituteArg& arg8 = internal::SubstituteArg(), + const internal::SubstituteArg& arg9 = internal::SubstituteArg()); + +} // namespace strings +} // namespace protobuf +} // namespace google + +#include <google/protobuf/port_undef.inc> + +#endif // GOOGLE_PROTOBUF_STUBS_SUBSTITUTE_H_ diff --git a/contrib/libs/protobuf_old/src/google/protobuf/stubs/time.cc b/contrib/libs/protobuf_old/src/google/protobuf/stubs/time.cc new file mode 100644 index 0000000000..b450deb5bd --- /dev/null +++ b/contrib/libs/protobuf_old/src/google/protobuf/stubs/time.cc @@ -0,0 +1,365 @@ +#include <google/protobuf/stubs/time.h> + +#include <ctime> + +#include <google/protobuf/stubs/stringprintf.h> +#include <google/protobuf/stubs/strutil.h> + +namespace google { +namespace protobuf { +namespace internal { + +namespace { +static const int64 kSecondsPerMinute = 60; +static const int64 kSecondsPerHour = 3600; +static const int64 kSecondsPerDay = kSecondsPerHour * 24; +static const int64 kSecondsPer400Years = + kSecondsPerDay * (400 * 365 + 400 / 4 - 3); +// Seconds from 0001-01-01T00:00:00 to 1970-01-01T:00:00:00 +static const int64 kSecondsFromEraToEpoch = 62135596800LL; +// The range of timestamp values we support. +static const int64 kMinTime = -62135596800LL; // 0001-01-01T00:00:00 +static const int64 kMaxTime = 253402300799LL; // 9999-12-31T23:59:59 + +static const int kNanosPerMillisecond = 1000000; +static const int kNanosPerMicrosecond = 1000; + +// Count the seconds from the given year (start at Jan 1, 00:00) to 100 years +// after. +int64 SecondsPer100Years(int year) { + if (year % 400 == 0 || year % 400 > 300) { + return kSecondsPerDay * (100 * 365 + 100 / 4); + } else { + return kSecondsPerDay * (100 * 365 + 100 / 4 - 1); + } +} + +// Count the seconds from the given year (start at Jan 1, 00:00) to 4 years +// after. +int64 SecondsPer4Years(int year) { + if ((year % 100 == 0 || year % 100 > 96) && + !(year % 400 == 0 || year % 400 > 396)) { + // No leap years. + return kSecondsPerDay * (4 * 365); + } else { + // One leap years. + return kSecondsPerDay * (4 * 365 + 1); + } +} + +bool IsLeapYear(int year) { + return year % 400 == 0 || (year % 4 == 0 && year % 100 != 0); +} + +int64 SecondsPerYear(int year) { + return kSecondsPerDay * (IsLeapYear(year) ? 366 : 365); +} + +static const int kDaysInMonth[13] = { + 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 +}; + +int64 SecondsPerMonth(int month, bool leap) { + if (month == 2 && leap) { + return kSecondsPerDay * (kDaysInMonth[month] + 1); + } + return kSecondsPerDay * kDaysInMonth[month]; +} + +static const int kDaysSinceJan[13] = { + 0, 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, +}; + +bool ValidateDateTime(const DateTime& time) { + if (time.year < 1 || time.year > 9999 || + time.month < 1 || time.month > 12 || + time.day < 1 || time.day > 31 || + time.hour < 0 || time.hour > 23 || + time.minute < 0 || time.minute > 59 || + time.second < 0 || time.second > 59) { + return false; + } + if (time.month == 2 && IsLeapYear(time.year)) { + return time.day <= kDaysInMonth[time.month] + 1; + } else { + return time.day <= kDaysInMonth[time.month]; + } +} + +// Count the number of seconds elapsed from 0001-01-01T00:00:00 to the given +// time. +int64 SecondsSinceCommonEra(const DateTime& time) { + int64 result = 0; + // Years should be between 1 and 9999. + assert(time.year >= 1 && time.year <= 9999); + int year = 1; + if ((time.year - year) >= 400) { + int count_400years = (time.year - year) / 400; + result += kSecondsPer400Years * count_400years; + year += count_400years * 400; + } + while ((time.year - year) >= 100) { + result += SecondsPer100Years(year); + year += 100; + } + while ((time.year - year) >= 4) { + result += SecondsPer4Years(year); + year += 4; + } + while (time.year > year) { + result += SecondsPerYear(year); + ++year; + } + // Months should be between 1 and 12. + assert(time.month >= 1 && time.month <= 12); + int month = time.month; + result += kSecondsPerDay * kDaysSinceJan[month]; + if (month > 2 && IsLeapYear(year)) { + result += kSecondsPerDay; + } + assert(time.day >= 1 && + time.day <= (month == 2 && IsLeapYear(year) + ? kDaysInMonth[month] + 1 + : kDaysInMonth[month])); + result += kSecondsPerDay * (time.day - 1); + result += kSecondsPerHour * time.hour + + kSecondsPerMinute * time.minute + + time.second; + return result; +} + +// Format nanoseconds with either 3, 6, or 9 digits depending on the required +// precision to represent the exact value. +TProtoStringType FormatNanos(int32 nanos) { + if (nanos % kNanosPerMillisecond == 0) { + return StringPrintf("%03d", nanos / kNanosPerMillisecond); + } else if (nanos % kNanosPerMicrosecond == 0) { + return StringPrintf("%06d", nanos / kNanosPerMicrosecond); + } else { + return StringPrintf("%09d", nanos); + } +} + +// Parses an integer from a null-terminated char sequence. The method +// consumes at most "width" chars. Returns a pointer after the consumed +// integer, or nullptr if the data does not start with an integer or the +// integer value does not fall in the range of [min_value, max_value]. +const char* ParseInt(const char* data, int width, int min_value, + int max_value, int* result) { + if (!ascii_isdigit(*data)) { + return nullptr; + } + int value = 0; + for (int i = 0; i < width; ++i, ++data) { + if (ascii_isdigit(*data)) { + value = value * 10 + (*data - '0'); + } else { + break; + } + } + if (value >= min_value && value <= max_value) { + *result = value; + return data; + } else { + return nullptr; + } +} + +// Consumes the fractional parts of a second into nanos. For example, +// "010" will be parsed to 10000000 nanos. +const char* ParseNanos(const char* data, int32* nanos) { + if (!ascii_isdigit(*data)) { + return nullptr; + } + int value = 0; + int len = 0; + // Consume as many digits as there are but only take the first 9 into + // account. + while (ascii_isdigit(*data)) { + if (len < 9) { + value = value * 10 + *data - '0'; + } + ++len; + ++data; + } + while (len < 9) { + value = value * 10; + ++len; + } + *nanos = value; + return data; +} + +const char* ParseTimezoneOffset(const char* data, int64* offset) { + // Accept format "HH:MM". E.g., "08:00" + int hour; + if ((data = ParseInt(data, 2, 0, 23, &hour)) == nullptr) { + return nullptr; + } + if (*data++ != ':') { + return nullptr; + } + int minute; + if ((data = ParseInt(data, 2, 0, 59, &minute)) == nullptr) { + return nullptr; + } + *offset = (hour * 60 + minute) * 60; + return data; +} +} // namespace + +bool SecondsToDateTime(int64 seconds, DateTime* time) { + if (seconds < kMinTime || seconds > kMaxTime) { + return false; + } + // It's easier to calculate the DateTime starting from 0001-01-01T00:00:00 + seconds = seconds + kSecondsFromEraToEpoch; + int year = 1; + if (seconds >= kSecondsPer400Years) { + int count_400years = seconds / kSecondsPer400Years; + year += 400 * count_400years; + seconds %= kSecondsPer400Years; + } + while (seconds >= SecondsPer100Years(year)) { + seconds -= SecondsPer100Years(year); + year += 100; + } + while (seconds >= SecondsPer4Years(year)) { + seconds -= SecondsPer4Years(year); + year += 4; + } + while (seconds >= SecondsPerYear(year)) { + seconds -= SecondsPerYear(year); + year += 1; + } + bool leap = IsLeapYear(year); + int month = 1; + while (seconds >= SecondsPerMonth(month, leap)) { + seconds -= SecondsPerMonth(month, leap); + ++month; + } + int day = 1 + seconds / kSecondsPerDay; + seconds %= kSecondsPerDay; + int hour = seconds / kSecondsPerHour; + seconds %= kSecondsPerHour; + int minute = seconds / kSecondsPerMinute; + seconds %= kSecondsPerMinute; + time->year = year; + time->month = month; + time->day = day; + time->hour = hour; + time->minute = minute; + time->second = static_cast<int>(seconds); + return true; +} + +bool DateTimeToSeconds(const DateTime& time, int64* seconds) { + if (!ValidateDateTime(time)) { + return false; + } + *seconds = SecondsSinceCommonEra(time) - kSecondsFromEraToEpoch; + return true; +} + +void GetCurrentTime(int64* seconds, int32* nanos) { + // TODO(xiaofeng): Improve the accuracy of this implementation (or just + // remove this method from protobuf). + *seconds = time(nullptr); + *nanos = 0; +} + +TProtoStringType FormatTime(int64 seconds, int32 nanos) { + DateTime time; + if (nanos < 0 || nanos > 999999999 || !SecondsToDateTime(seconds, &time)) { + return "InvalidTime"; + } + TProtoStringType result = + StringPrintf("%04d-%02d-%02dT%02d:%02d:%02d", time.year, time.month, + time.day, time.hour, time.minute, time.second); + if (nanos != 0) { + result += "." + FormatNanos(nanos); + } + return result + "Z"; +} + +bool ParseTime(const TProtoStringType& value, int64* seconds, int32* nanos) { + DateTime time; + const char* data = value.c_str(); + // We only accept: + // Z-normalized: 2015-05-20T13:29:35.120Z + // With UTC offset: 2015-05-20T13:29:35.120-08:00 + + // Parse year + if ((data = ParseInt(data, 4, 1, 9999, &time.year)) == nullptr) { + return false; + } + // Expect '-' + if (*data++ != '-') return false; + // Parse month + if ((data = ParseInt(data, 2, 1, 12, &time.month)) == nullptr) { + return false; + } + // Expect '-' + if (*data++ != '-') return false; + // Parse day + if ((data = ParseInt(data, 2, 1, 31, &time.day)) == nullptr) { + return false; + } + // Expect 'T' + if (*data++ != 'T') return false; + // Parse hour + if ((data = ParseInt(data, 2, 0, 23, &time.hour)) == nullptr) { + return false; + } + // Expect ':' + if (*data++ != ':') return false; + // Parse minute + if ((data = ParseInt(data, 2, 0, 59, &time.minute)) == nullptr) { + return false; + } + // Expect ':' + if (*data++ != ':') return false; + // Parse second + if ((data = ParseInt(data, 2, 0, 59, &time.second)) == nullptr) { + return false; + } + if (!DateTimeToSeconds(time, seconds)) { + return false; + } + // Parse nanoseconds. + if (*data == '.') { + ++data; + // Parse nanoseconds. + if ((data = ParseNanos(data, nanos)) == nullptr) { + return false; + } + } else { + *nanos = 0; + } + // Parse UTC offsets. + if (*data == 'Z') { + ++data; + } else if (*data == '+') { + ++data; + int64 offset; + if ((data = ParseTimezoneOffset(data, &offset)) == nullptr) { + return false; + } + *seconds -= offset; + } else if (*data == '-') { + ++data; + int64 offset; + if ((data = ParseTimezoneOffset(data, &offset)) == nullptr) { + return false; + } + *seconds += offset; + } else { + return false; + } + // Done with parsing. + return *data == 0; +} + +} // namespace internal +} // namespace protobuf +} // namespace google diff --git a/contrib/libs/protobuf_old/src/google/protobuf/stubs/time.h b/contrib/libs/protobuf_old/src/google/protobuf/stubs/time.h new file mode 100644 index 0000000000..eb58dbf159 --- /dev/null +++ b/contrib/libs/protobuf_old/src/google/protobuf/stubs/time.h @@ -0,0 +1,80 @@ +// 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_STUBS_TIME_H_ +#define GOOGLE_PROTOBUF_STUBS_TIME_H_ + +#include <google/protobuf/stubs/common.h> + +#include <google/protobuf/port_def.inc> + +namespace google { +namespace protobuf { +namespace internal { + +struct DateTime { + int year; + int month; + int day; + int hour; + int minute; + int second; +}; + +// Converts a timestamp (seconds elapsed since 1970-01-01T00:00:00, could be +// negative to represent time before 1970-01-01) to DateTime. Returns false +// if the timestamp is not in the range between 0001-01-01T00:00:00 and +// 9999-12-31T23:59:59. +bool PROTOBUF_EXPORT SecondsToDateTime(int64 seconds, DateTime* time); +// Converts DateTime to a timestamp (seconds since 1970-01-01T00:00:00). +// Returns false if the DateTime is not valid or is not in the valid range. +bool PROTOBUF_EXPORT DateTimeToSeconds(const DateTime& time, int64* seconds); + +void PROTOBUF_EXPORT GetCurrentTime(int64* seconds, int32* nanos); + +// Formats a time string in RFC3339 format. +// +// For example, "2015-05-20T13:29:35.120Z". For nanos, 0, 3, 6 or 9 fractional +// digits will be used depending on how many are required to represent the exact +// value. +// +// Note that "nanos" must in the range of [0, 999999999]. +TProtoStringType PROTOBUF_EXPORT FormatTime(int64 seconds, int32 nanos); +// Parses a time string. This method accepts RFC3339 date/time string with UTC +// offset. For example, "2015-05-20T13:29:35.120-08:00". +bool PROTOBUF_EXPORT ParseTime(const TProtoStringType& value, int64* seconds, + int32* nanos); + +} // namespace internal +} // namespace protobuf +} // namespace google + +#include <google/protobuf/port_undef.inc> + +#endif // GOOGLE_PROTOBUF_STUBS_TIME_H_ diff --git a/contrib/libs/protobuf_old/src/google/protobuf/text_format.cc b/contrib/libs/protobuf_old/src/google/protobuf/text_format.cc new file mode 100644 index 0000000000..5b6eadfc19 --- /dev/null +++ b/contrib/libs/protobuf_old/src/google/protobuf/text_format.cc @@ -0,0 +1,2734 @@ +// 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: jschorr@google.com (Joseph Schorr) +// Based on original Protocol Buffers design by +// Sanjay Ghemawat, Jeff Dean, and others. + +#include <google/protobuf/text_format.h> + +#include <float.h> +#include <stdio.h> + +#include <algorithm> +#include <atomic> +#include <climits> +#include <cmath> +#include <limits> +#include <vector> + +#include <google/protobuf/stubs/stringprintf.h> +#include <google/protobuf/any.h> +#include <google/protobuf/descriptor.pb.h> +#include <google/protobuf/io/coded_stream.h> +#include <google/protobuf/io/tokenizer.h> +#include <google/protobuf/io/zero_copy_stream.h> +#include <google/protobuf/io/zero_copy_stream_impl.h> +#include <google/protobuf/descriptor.h> +#include <google/protobuf/dynamic_message.h> +#include <google/protobuf/map_field.h> +#include <google/protobuf/message.h> +#include <google/protobuf/repeated_field.h> +#include <google/protobuf/unknown_field_set.h> +#include <google/protobuf/wire_format_lite.h> +#include <google/protobuf/stubs/strutil.h> +#include <google/protobuf/io/strtod.h> +#include <google/protobuf/stubs/map_util.h> +#include <google/protobuf/stubs/stl_util.h> + +// Must be included last. +#include <google/protobuf/port_def.inc> + +#define DEBUG_STRING_SILENT_MARKER "\t " + +namespace google { +namespace protobuf { + +namespace { + +inline bool IsHexNumber(const TProtoStringType& str) { + return (str.length() >= 2 && str[0] == '0' && + (str[1] == 'x' || str[1] == 'X')); +} + +inline bool IsOctNumber(const TProtoStringType& str) { + return (str.length() >= 2 && str[0] == '0' && + (str[1] >= '0' && str[1] < '8')); +} + +} // namespace + +namespace internal { +// Controls insertion of DEBUG_STRING_SILENT_MARKER. +PROTOBUF_EXPORT std::atomic<bool> enable_debug_text_format_marker; +} // namespace internal + +TProtoStringType Message::DebugString() const { + TProtoStringType debug_string; + + TextFormat::Printer printer; + printer.SetExpandAny(true); + printer.SetInsertSilentMarker(internal::enable_debug_text_format_marker.load( + std::memory_order_relaxed)); + + printer.PrintToString(*this, &debug_string); + + return debug_string; +} + +TProtoStringType Message::ShortDebugString() const { + TProtoStringType debug_string; + + TextFormat::Printer printer; + printer.SetSingleLineMode(true); + printer.SetExpandAny(true); + printer.SetInsertSilentMarker(internal::enable_debug_text_format_marker.load( + std::memory_order_relaxed)); + + printer.PrintToString(*this, &debug_string); + // Single line mode currently might have an extra space at the end. + if (!debug_string.empty() && debug_string[debug_string.size() - 1] == ' ') { + debug_string.resize(debug_string.size() - 1); + } + + return debug_string; +} + +TProtoStringType Message::Utf8DebugString() const { + TProtoStringType debug_string; + + TextFormat::Printer printer; + printer.SetUseUtf8StringEscaping(true); + printer.SetExpandAny(true); + printer.SetInsertSilentMarker(internal::enable_debug_text_format_marker.load( + std::memory_order_relaxed)); + + printer.PrintToString(*this, &debug_string); + + return debug_string; +} + +void Message::PrintDebugString() const { printf("%s", DebugString().c_str()); } + + +// =========================================================================== +// Implementation of the parse information tree class. +void TextFormat::ParseInfoTree::RecordLocation( + const FieldDescriptor* field, TextFormat::ParseLocationRange range) { + locations_[field].push_back(range); +} + +TextFormat::ParseInfoTree* TextFormat::ParseInfoTree::CreateNested( + const FieldDescriptor* field) { + // Owned by us in the map. + auto& vec = nested_[field]; + vec.emplace_back(new TextFormat::ParseInfoTree()); + return vec.back().get(); +} + +void CheckFieldIndex(const FieldDescriptor* field, int index) { + if (field == nullptr) { + return; + } + + if (field->is_repeated() && index == -1) { + GOOGLE_LOG(DFATAL) << "Index must be in range of repeated field values. " + << "Field: " << field->name(); + } else if (!field->is_repeated() && index != -1) { + GOOGLE_LOG(DFATAL) << "Index must be -1 for singular fields." + << "Field: " << field->name(); + } +} + +TextFormat::ParseLocationRange TextFormat::ParseInfoTree::GetLocationRange( + const FieldDescriptor* field, int index) const { + CheckFieldIndex(field, index); + if (index == -1) { + index = 0; + } + + const std::vector<TextFormat::ParseLocationRange>* locations = + FindOrNull(locations_, field); + if (locations == nullptr || + index >= static_cast<arc_i64>(locations->size())) { + return TextFormat::ParseLocationRange(); + } + + return (*locations)[index]; +} + +TextFormat::ParseInfoTree* TextFormat::ParseInfoTree::GetTreeForNested( + const FieldDescriptor* field, int index) const { + CheckFieldIndex(field, index); + if (index == -1) { + index = 0; + } + + auto it = nested_.find(field); + if (it == nested_.end() || index >= static_cast<arc_i64>(it->second.size())) { + return nullptr; + } + + return it->second[index].get(); +} + +namespace { +// These functions implement the behavior of the "default" TextFormat::Finder, +// they are defined as standalone to be called when finder_ is nullptr. +const FieldDescriptor* DefaultFinderFindExtension(Message* message, + const TProtoStringType& name) { + const Descriptor* descriptor = message->GetDescriptor(); + return descriptor->file()->pool()->FindExtensionByPrintableName(descriptor, + name); +} + +const FieldDescriptor* DefaultFinderFindExtensionByNumber( + const Descriptor* descriptor, int number) { + return descriptor->file()->pool()->FindExtensionByNumber(descriptor, number); +} + +const Descriptor* DefaultFinderFindAnyType(const Message& message, + const TProtoStringType& prefix, + const TProtoStringType& name) { + if (prefix != internal::kTypeGoogleApisComPrefix && + prefix != internal::kTypeGoogleProdComPrefix) { + return nullptr; + } + return message.GetDescriptor()->file()->pool()->FindMessageTypeByName(name); +} +} // namespace + +// =========================================================================== +// Internal class for parsing an ASCII representation of a Protocol Message. +// This class makes use of the Protocol Message compiler's tokenizer found +// in //net/proto2/io/public/tokenizer.h. Note that class's Parse +// method is *not* thread-safe and should only be used in a single thread at +// a time. + +// Makes code slightly more readable. The meaning of "DO(foo)" is +// "Execute foo and fail if it fails.", where failure is indicated by +// returning false. Borrowed from parser.cc (Thanks Kenton!). +#define DO(STATEMENT) \ + if (STATEMENT) { \ + } else { \ + return false; \ + } + +class TextFormat::Parser::ParserImpl { + public: + // Determines if repeated values for non-repeated fields and + // oneofs are permitted, e.g., the string "foo: 1 foo: 2" for a + // required/optional field named "foo", or "baz: 1 qux: 2" + // where "baz" and "qux" are members of the same oneof. + enum SingularOverwritePolicy { + ALLOW_SINGULAR_OVERWRITES = 0, // the last value is retained + FORBID_SINGULAR_OVERWRITES = 1, // an error is issued + }; + + ParserImpl(const Descriptor* root_message_type, + io::ZeroCopyInputStream* input_stream, + io::ErrorCollector* error_collector, + const TextFormat::Finder* finder, ParseInfoTree* parse_info_tree, + SingularOverwritePolicy singular_overwrite_policy, + bool allow_case_insensitive_field, bool allow_unknown_field, + bool allow_unknown_extension, bool allow_unknown_enum, + bool allow_field_number, bool allow_relaxed_whitespace, + bool allow_partial, int recursion_limit) + : error_collector_(error_collector), + finder_(finder), + parse_info_tree_(parse_info_tree), + tokenizer_error_collector_(this), + tokenizer_(input_stream, &tokenizer_error_collector_), + root_message_type_(root_message_type), + singular_overwrite_policy_(singular_overwrite_policy), + allow_case_insensitive_field_(allow_case_insensitive_field), + allow_unknown_field_(allow_unknown_field), + allow_unknown_extension_(allow_unknown_extension), + allow_unknown_enum_(allow_unknown_enum), + allow_field_number_(allow_field_number), + allow_partial_(allow_partial), + initial_recursion_limit_(recursion_limit), + recursion_limit_(recursion_limit), + had_errors_(false) { + // For backwards-compatibility with proto1, we need to allow the 'f' suffix + // for floats. + tokenizer_.set_allow_f_after_float(true); + + // '#' starts a comment. + tokenizer_.set_comment_style(io::Tokenizer::SH_COMMENT_STYLE); + + if (allow_relaxed_whitespace) { + tokenizer_.set_require_space_after_number(false); + tokenizer_.set_allow_multiline_strings(true); + } + + // Consume the starting token. + tokenizer_.Next(); + } + ~ParserImpl() {} + + // Parses the ASCII representation specified in input and saves the + // information into the output pointer (a Message). Returns + // false if an error occurs (an error will also be logged to + // GOOGLE_LOG(ERROR)). + bool Parse(Message* output) { + // Consume fields until we cannot do so anymore. + while (true) { + if (LookingAtType(io::Tokenizer::TYPE_END)) { + // Ensures recursion limit properly unwinded, but only for success + // cases. This implicitly avoids the check when `Parse` returns false + // via `DO(...)`. + GOOGLE_DCHECK(had_errors_ || recursion_limit_ == initial_recursion_limit_) + << "Recursion limit at end of parse should be " + << initial_recursion_limit_ << ", but was " << recursion_limit_ + << ". Difference of " << initial_recursion_limit_ - recursion_limit_ + << " stack frames not accounted for stack unwind."; + + return !had_errors_; + } + + DO(ConsumeField(output)); + } + } + + bool ParseField(const FieldDescriptor* field, Message* output) { + bool suc; + if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) { + suc = ConsumeFieldMessage(output, output->GetReflection(), field); + } else { + suc = ConsumeFieldValue(output, output->GetReflection(), field); + } + return suc && LookingAtType(io::Tokenizer::TYPE_END); + } + + void ReportError(int line, int col, const TProtoStringType& message) { + had_errors_ = true; + if (error_collector_ == nullptr) { + if (line >= 0) { + GOOGLE_LOG(ERROR) << "Error parsing text-format " + << root_message_type_->full_name() << ": " << (line + 1) + << ":" << (col + 1) << ": " << message; + } else { + GOOGLE_LOG(ERROR) << "Error parsing text-format " + << root_message_type_->full_name() << ": " << message; + } + } else { + error_collector_->AddError(line, col, message); + } + } + + void ReportWarning(int line, int col, const TProtoStringType& message) { + if (error_collector_ == nullptr) { + if (line >= 0) { + GOOGLE_LOG(WARNING) << "Warning parsing text-format " + << root_message_type_->full_name() << ": " << (line + 1) + << ":" << (col + 1) << ": " << message; + } else { + GOOGLE_LOG(WARNING) << "Warning parsing text-format " + << root_message_type_->full_name() << ": " << message; + } + } else { + error_collector_->AddWarning(line, col, message); + } + } + + private: + static constexpr arc_i32 kint32max = std::numeric_limits<arc_i32>::max(); + static constexpr arc_ui32 kuint32max = std::numeric_limits<arc_ui32>::max(); + static constexpr arc_i64 kint64min = std::numeric_limits<arc_i64>::min(); + static constexpr arc_i64 kint64max = std::numeric_limits<arc_i64>::max(); + static constexpr arc_ui64 kuint64max = std::numeric_limits<arc_ui64>::max(); + + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ParserImpl); + + // Reports an error with the given message with information indicating + // the position (as derived from the current token). + void ReportError(const TProtoStringType& message) { + ReportError(tokenizer_.current().line, tokenizer_.current().column, + message); + } + + // Reports a warning with the given message with information indicating + // the position (as derived from the current token). + void ReportWarning(const TProtoStringType& message) { + ReportWarning(tokenizer_.current().line, tokenizer_.current().column, + message); + } + + // Consumes the specified message with the given starting delimiter. + // This method checks to see that the end delimiter at the conclusion of + // the consumption matches the starting delimiter passed in here. + bool ConsumeMessage(Message* message, const TProtoStringType delimiter) { + while (!LookingAt(">") && !LookingAt("}")) { + DO(ConsumeField(message)); + } + + // Confirm that we have a valid ending delimiter. + DO(Consume(delimiter)); + return true; + } + + // Consume either "<" or "{". + bool ConsumeMessageDelimiter(TProtoStringType* delimiter) { + if (TryConsume("<")) { + *delimiter = ">"; + } else { + DO(Consume("{")); + *delimiter = "}"; + } + return true; + } + + + // Consumes the current field (as returned by the tokenizer) on the + // passed in message. + bool ConsumeField(Message* message) { + const Reflection* reflection = message->GetReflection(); + const Descriptor* descriptor = message->GetDescriptor(); + + TProtoStringType field_name; + bool reserved_field = false; + const FieldDescriptor* field = nullptr; + int start_line = tokenizer_.current().line; + int start_column = tokenizer_.current().column; + + const FieldDescriptor* any_type_url_field; + const FieldDescriptor* any_value_field; + if (internal::GetAnyFieldDescriptors(*message, &any_type_url_field, + &any_value_field) && + TryConsume("[")) { + TProtoStringType full_type_name, prefix; + DO(ConsumeAnyTypeUrl(&full_type_name, &prefix)); + TProtoStringType prefix_and_full_type_name = + StrCat(prefix, full_type_name); + DO(ConsumeBeforeWhitespace("]")); + TryConsumeWhitespace(prefix_and_full_type_name, "Any"); + // ':' is optional between message labels and values. + TryConsumeBeforeWhitespace(":"); + TryConsumeWhitespace(prefix_and_full_type_name, "Any"); + TProtoStringType serialized_value; + const Descriptor* value_descriptor = + finder_ ? finder_->FindAnyType(*message, prefix, full_type_name) + : DefaultFinderFindAnyType(*message, prefix, full_type_name); + if (value_descriptor == nullptr) { + ReportError("Could not find type \"" + prefix_and_full_type_name + + "\" stored in google.protobuf.Any."); + return false; + } + DO(ConsumeAnyValue(value_descriptor, &serialized_value)); + if (singular_overwrite_policy_ == FORBID_SINGULAR_OVERWRITES) { + // Fail if any_type_url_field has already been specified. + if ((!any_type_url_field->is_repeated() && + reflection->HasField(*message, any_type_url_field)) || + (!any_value_field->is_repeated() && + reflection->HasField(*message, any_value_field))) { + ReportError("Non-repeated Any specified multiple times."); + return false; + } + } + reflection->SetString(message, any_type_url_field, + prefix_and_full_type_name); + reflection->SetString(message, any_value_field, serialized_value); + return true; + } + if (TryConsume("[")) { + // Extension. + DO(ConsumeFullTypeName(&field_name)); + DO(ConsumeBeforeWhitespace("]")); + TryConsumeWhitespace(message->GetTypeName(), "Extension"); + + field = finder_ ? finder_->FindExtension(message, field_name) + : DefaultFinderFindExtension(message, field_name); + + if (field == nullptr) { + if (!allow_unknown_field_ && !allow_unknown_extension_) { + ReportError("Extension \"" + field_name + + "\" is not defined or " + "is not an extension of \"" + + descriptor->full_name() + "\"."); + return false; + } else { + ReportWarning("Ignoring extension \"" + field_name + + "\" which is not defined or is not an extension of \"" + + descriptor->full_name() + "\"."); + } + } + } else { + DO(ConsumeIdentifierBeforeWhitespace(&field_name)); + TryConsumeWhitespace(message->GetTypeName(), "Normal"); + + arc_i32 field_number; + if (allow_field_number_ && safe_strto32(field_name, &field_number)) { + if (descriptor->IsExtensionNumber(field_number)) { + field = finder_ + ? finder_->FindExtensionByNumber(descriptor, field_number) + : DefaultFinderFindExtensionByNumber(descriptor, + field_number); + } else if (descriptor->IsReservedNumber(field_number)) { + reserved_field = true; + } else { + field = descriptor->FindFieldByNumber(field_number); + } + } else { + field = descriptor->FindFieldByName(field_name); + // Group names are expected to be capitalized as they appear in the + // .proto file, which actually matches their type names, not their + // field names. + if (field == nullptr) { + TProtoStringType lower_field_name = field_name; + LowerString(&lower_field_name); + field = descriptor->FindFieldByName(lower_field_name); + // If the case-insensitive match worked but the field is NOT a group, + if (field != nullptr && + field->type() != FieldDescriptor::TYPE_GROUP) { + field = nullptr; + } + } + // Again, special-case group names as described above. + if (field != nullptr && field->type() == FieldDescriptor::TYPE_GROUP && + field->message_type()->name() != field_name) { + field = nullptr; + } + + if (field == nullptr && allow_case_insensitive_field_) { + TProtoStringType lower_field_name = field_name; + LowerString(&lower_field_name); + field = descriptor->FindFieldByLowercaseName(lower_field_name); + } + + if (field == nullptr) { + reserved_field = descriptor->IsReservedName(field_name); + } + } + + if (field == nullptr && !reserved_field) { + if (!allow_unknown_field_) { + ReportError("Message type \"" + descriptor->full_name() + + "\" has no field named \"" + field_name + "\"."); + return false; + } else { + ReportWarning("Message type \"" + descriptor->full_name() + + "\" has no field named \"" + field_name + "\"."); + } + } + } + + // Skips unknown or reserved fields. + if (field == nullptr) { + GOOGLE_CHECK(allow_unknown_field_ || allow_unknown_extension_ || reserved_field); + + // Try to guess the type of this field. + // If this field is not a message, there should be a ":" between the + // field name and the field value and also the field value should not + // start with "{" or "<" which indicates the beginning of a message body. + // If there is no ":" or there is a "{" or "<" after ":", this field has + // to be a message or the input is ill-formed. + bool skip; + if (TryConsumeBeforeWhitespace(":")) { + TryConsumeWhitespace(message->GetTypeName(), "Unknown/Reserved"); + if (!LookingAt("{") && !LookingAt("<")) { + skip = SkipFieldValue(); + } else { + skip = SkipFieldMessage(); + } + } else { + skip = SkipFieldMessage(); + } + TryConsume(";") || TryConsume(","); + return skip; + } + + if (singular_overwrite_policy_ == FORBID_SINGULAR_OVERWRITES) { + // Fail if the field is not repeated and it has already been specified. + if (!field->is_repeated() && reflection->HasField(*message, field)) { + ReportError("Non-repeated field \"" + field_name + + "\" is specified multiple times."); + return false; + } + // Fail if the field is a member of a oneof and another member has already + // been specified. + const OneofDescriptor* oneof = field->containing_oneof(); + if (oneof != nullptr && reflection->HasOneof(*message, oneof)) { + const FieldDescriptor* other_field = + reflection->GetOneofFieldDescriptor(*message, oneof); + ReportError("Field \"" + field_name + + "\" is specified along with " + "field \"" + + other_field->name() + + "\", another member " + "of oneof \"" + + oneof->name() + "\"."); + return false; + } + } + + // Perform special handling for embedded message types. + if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) { + // ':' is optional here. + bool consumed_semicolon = TryConsumeBeforeWhitespace(":"); + TryConsumeWhitespace(message->GetTypeName(), "Normal"); + if (consumed_semicolon && field->options().weak() && + LookingAtType(io::Tokenizer::TYPE_STRING)) { + // we are getting a bytes string for a weak field. + TProtoStringType tmp; + DO(ConsumeString(&tmp)); + MessageFactory* factory = + finder_ ? finder_->FindExtensionFactory(field) : nullptr; + reflection->MutableMessage(message, field, factory) + ->ParseFromString(tmp); + goto label_skip_parsing; + } + } else { + // ':' is required here. + DO(ConsumeBeforeWhitespace(":")); + TryConsumeWhitespace(message->GetTypeName(), "Normal"); + } + + if (field->is_repeated() && TryConsume("[")) { + // Short repeated format, e.g. "foo: [1, 2, 3]". + if (!TryConsume("]")) { + // "foo: []" is treated as empty. + while (true) { + if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) { + // Perform special handling for embedded message types. + DO(ConsumeFieldMessage(message, reflection, field)); + } else { + DO(ConsumeFieldValue(message, reflection, field)); + } + if (TryConsume("]")) { + break; + } + DO(Consume(",")); + } + } + } else if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) { + DO(ConsumeFieldMessage(message, reflection, field)); + } else { + DO(ConsumeFieldValue(message, reflection, field)); + } + label_skip_parsing: + // For historical reasons, fields may optionally be separated by commas or + // semicolons. + TryConsume(";") || TryConsume(","); + + if (field->options().deprecated()) { + ReportWarning("text format contains deprecated field \"" + field_name + + "\""); + } + + // If a parse info tree exists, add the location for the parsed + // field. + if (parse_info_tree_ != nullptr) { + int end_line = tokenizer_.previous().line; + int end_column = tokenizer_.previous().end_column; + + RecordLocation(parse_info_tree_, field, + ParseLocationRange(ParseLocation(start_line, start_column), + ParseLocation(end_line, end_column))); + } + + return true; + } + + // Skips the next field including the field's name and value. + bool SkipField() { + if (TryConsume("[")) { + // Extension name or type URL. + DO(ConsumeTypeUrlOrFullTypeName()); + DO(ConsumeBeforeWhitespace("]")); + } else { + TProtoStringType field_name; + DO(ConsumeIdentifierBeforeWhitespace(&field_name)); + } + TryConsumeWhitespace("Unknown/Reserved", "n/a"); + + // Try to guess the type of this field. + // If this field is not a message, there should be a ":" between the + // field name and the field value and also the field value should not + // start with "{" or "<" which indicates the beginning of a message body. + // If there is no ":" or there is a "{" or "<" after ":", this field has + // to be a message or the input is ill-formed. + if (TryConsumeBeforeWhitespace(":")) { + TryConsumeWhitespace("Unknown/Reserved", "n/a"); + if (!LookingAt("{") && !LookingAt("<")) { + DO(SkipFieldValue()); + } else { + DO(SkipFieldMessage()); + } + } else { + DO(SkipFieldMessage()); + } + // For historical reasons, fields may optionally be separated by commas or + // semicolons. + TryConsume(";") || TryConsume(","); + return true; + } + + bool ConsumeFieldMessage(Message* message, const Reflection* reflection, + const FieldDescriptor* field) { + if (--recursion_limit_ < 0) { + ReportError( + StrCat("Message is too deep, the parser exceeded the " + "configured recursion limit of ", + initial_recursion_limit_, ".")); + return false; + } + // If the parse information tree is not nullptr, create a nested one + // for the nested message. + ParseInfoTree* parent = parse_info_tree_; + if (parent != nullptr) { + parse_info_tree_ = CreateNested(parent, field); + } + + TProtoStringType delimiter; + DO(ConsumeMessageDelimiter(&delimiter)); + MessageFactory* factory = + finder_ ? finder_->FindExtensionFactory(field) : nullptr; + if (field->is_repeated()) { + DO(ConsumeMessage(reflection->AddMessage(message, field, factory), + delimiter)); + } else { + DO(ConsumeMessage(reflection->MutableMessage(message, field, factory), + delimiter)); + } + + ++recursion_limit_; + + // Reset the parse information tree. + parse_info_tree_ = parent; + return true; + } + + // Skips the whole body of a message including the beginning delimiter and + // the ending delimiter. + bool SkipFieldMessage() { + if (--recursion_limit_ < 0) { + ReportError( + StrCat("Message is too deep, the parser exceeded the " + "configured recursion limit of ", + initial_recursion_limit_, ".")); + return false; + } + + TProtoStringType delimiter; + DO(ConsumeMessageDelimiter(&delimiter)); + while (!LookingAt(">") && !LookingAt("}")) { + DO(SkipField()); + } + DO(Consume(delimiter)); + + ++recursion_limit_; + return true; + } + + bool ConsumeFieldValue(Message* message, const Reflection* reflection, + const FieldDescriptor* field) { +// Define an easy to use macro for setting fields. This macro checks +// to see if the field is repeated (in which case we need to use the Add +// methods or not (in which case we need to use the Set methods). +#define SET_FIELD(CPPTYPE, VALUE) \ + if (field->is_repeated()) { \ + reflection->Add##CPPTYPE(message, field, VALUE); \ + } else { \ + reflection->Set##CPPTYPE(message, field, VALUE); \ + } + + switch (field->cpp_type()) { + case FieldDescriptor::CPPTYPE_INT32: { + arc_i64 value; + DO(ConsumeSignedInteger(&value, kint32max)); + SET_FIELD(Int32, static_cast<arc_i32>(value)); + break; + } + + case FieldDescriptor::CPPTYPE_UINT32: { + arc_ui64 value; + DO(ConsumeUnsignedInteger(&value, kuint32max)); + SET_FIELD(UInt32, static_cast<arc_ui32>(value)); + break; + } + + case FieldDescriptor::CPPTYPE_INT64: { + arc_i64 value; + DO(ConsumeSignedInteger(&value, kint64max)); + SET_FIELD(Int64, value); + break; + } + + case FieldDescriptor::CPPTYPE_UINT64: { + arc_ui64 value; + DO(ConsumeUnsignedInteger(&value, kuint64max)); + SET_FIELD(UInt64, value); + break; + } + + case FieldDescriptor::CPPTYPE_FLOAT: { + double value; + DO(ConsumeDouble(&value)); + SET_FIELD(Float, io::SafeDoubleToFloat(value)); + break; + } + + case FieldDescriptor::CPPTYPE_DOUBLE: { + double value; + DO(ConsumeDouble(&value)); + SET_FIELD(Double, value); + break; + } + + case FieldDescriptor::CPPTYPE_STRING: { + TProtoStringType value; + DO(ConsumeString(&value)); + SET_FIELD(String, value); + break; + } + + case FieldDescriptor::CPPTYPE_BOOL: { + if (LookingAtType(io::Tokenizer::TYPE_INTEGER)) { + arc_ui64 value; + DO(ConsumeUnsignedInteger(&value, 1)); + SET_FIELD(Bool, value); + } else { + TProtoStringType value; + DO(ConsumeIdentifier(&value)); + if (value == "true" || value == "True" || value == "t") { + SET_FIELD(Bool, true); + } else if (value == "false" || value == "False" || value == "f") { + SET_FIELD(Bool, false); + } else { + ReportError("Invalid value for boolean field \"" + field->name() + + "\". Value: \"" + value + "\"."); + return false; + } + } + break; + } + + case FieldDescriptor::CPPTYPE_ENUM: { + TProtoStringType value; + arc_i64 int_value = kint64max; + const EnumDescriptor* enum_type = field->enum_type(); + const EnumValueDescriptor* enum_value = nullptr; + + if (LookingAtType(io::Tokenizer::TYPE_IDENTIFIER)) { + DO(ConsumeIdentifier(&value)); + // Find the enumeration value. + enum_value = enum_type->FindValueByName(value); + + } else if (LookingAt("-") || + LookingAtType(io::Tokenizer::TYPE_INTEGER)) { + DO(ConsumeSignedInteger(&int_value, kint32max)); + value = StrCat(int_value); // for error reporting + enum_value = enum_type->FindValueByNumber(int_value); + } else { + ReportError("Expected integer or identifier, got: " + + tokenizer_.current().text); + return false; + } + + if (enum_value == nullptr) { + if (int_value != kint64max && + reflection->SupportsUnknownEnumValues()) { + SET_FIELD(EnumValue, int_value); + return true; + } else if (!allow_unknown_enum_) { + ReportError("Unknown enumeration value of \"" + value + + "\" for " + "field \"" + + field->name() + "\"."); + return false; + } else { + ReportWarning("Unknown enumeration value of \"" + value + + "\" for " + "field \"" + + field->name() + "\"."); + return true; + } + } + + SET_FIELD(Enum, enum_value); + break; + } + + case FieldDescriptor::CPPTYPE_MESSAGE: { + // We should never get here. Put here instead of a default + // so that if new types are added, we get a nice compiler warning. + GOOGLE_LOG(FATAL) << "Reached an unintended state: CPPTYPE_MESSAGE"; + break; + } + } +#undef SET_FIELD + return true; + } + + bool SkipFieldValue() { + if (--recursion_limit_ < 0) { + ReportError( + StrCat("Message is too deep, the parser exceeded the " + "configured recursion limit of ", + initial_recursion_limit_, ".")); + return false; + } + + if (LookingAtType(io::Tokenizer::TYPE_STRING)) { + while (LookingAtType(io::Tokenizer::TYPE_STRING)) { + tokenizer_.Next(); + } + ++recursion_limit_; + return true; + } + if (TryConsume("[")) { + while (true) { + if (!LookingAt("{") && !LookingAt("<")) { + DO(SkipFieldValue()); + } else { + DO(SkipFieldMessage()); + } + if (TryConsume("]")) { + break; + } + DO(Consume(",")); + } + ++recursion_limit_; + return true; + } + // Possible field values other than string: + // 12345 => TYPE_INTEGER + // -12345 => TYPE_SYMBOL + TYPE_INTEGER + // 1.2345 => TYPE_FLOAT + // -1.2345 => TYPE_SYMBOL + TYPE_FLOAT + // inf => TYPE_IDENTIFIER + // -inf => TYPE_SYMBOL + TYPE_IDENTIFIER + // TYPE_INTEGER => TYPE_IDENTIFIER + // Divides them into two group, one with TYPE_SYMBOL + // and the other without: + // Group one: + // 12345 => TYPE_INTEGER + // 1.2345 => TYPE_FLOAT + // inf => TYPE_IDENTIFIER + // TYPE_INTEGER => TYPE_IDENTIFIER + // Group two: + // -12345 => TYPE_SYMBOL + TYPE_INTEGER + // -1.2345 => TYPE_SYMBOL + TYPE_FLOAT + // -inf => TYPE_SYMBOL + TYPE_IDENTIFIER + // As we can see, the field value consists of an optional '-' and one of + // TYPE_INTEGER, TYPE_FLOAT and TYPE_IDENTIFIER. + bool has_minus = TryConsume("-"); + if (!LookingAtType(io::Tokenizer::TYPE_INTEGER) && + !LookingAtType(io::Tokenizer::TYPE_FLOAT) && + !LookingAtType(io::Tokenizer::TYPE_IDENTIFIER)) { + TProtoStringType text = tokenizer_.current().text; + ReportError("Cannot skip field value, unexpected token: " + text); + ++recursion_limit_; + return false; + } + // Combination of '-' and TYPE_IDENTIFIER may result in an invalid field + // value while other combinations all generate valid values. + // We check if the value of this combination is valid here. + // TYPE_IDENTIFIER after a '-' should be one of the float values listed + // below: + // inf, inff, infinity, nan + if (has_minus && LookingAtType(io::Tokenizer::TYPE_IDENTIFIER)) { + TProtoStringType text = tokenizer_.current().text; + LowerString(&text); + if (text != "inf" && + text != "infinity" && text != "nan") { + ReportError("Invalid float number: " + text); + ++recursion_limit_; + return false; + } + } + tokenizer_.Next(); + ++recursion_limit_; + return true; + } + + // Returns true if the current token's text is equal to that specified. + bool LookingAt(const TProtoStringType& text) { + return tokenizer_.current().text == text; + } + + // Returns true if the current token's type is equal to that specified. + bool LookingAtType(io::Tokenizer::TokenType token_type) { + return tokenizer_.current().type == token_type; + } + + // Consumes an identifier and saves its value in the identifier parameter. + // Returns false if the token is not of type IDENTFIER. + bool ConsumeIdentifier(TProtoStringType* identifier) { + if (LookingAtType(io::Tokenizer::TYPE_IDENTIFIER)) { + *identifier = tokenizer_.current().text; + tokenizer_.Next(); + return true; + } + + // If allow_field_numer_ or allow_unknown_field_ is true, we should able + // to parse integer identifiers. + if ((allow_field_number_ || allow_unknown_field_ || + allow_unknown_extension_) && + LookingAtType(io::Tokenizer::TYPE_INTEGER)) { + *identifier = tokenizer_.current().text; + tokenizer_.Next(); + return true; + } + + ReportError("Expected identifier, got: " + tokenizer_.current().text); + return false; + } + + // Similar to `ConsumeIdentifier`, but any following whitespace token may + // be reported. + bool ConsumeIdentifierBeforeWhitespace(TProtoStringType* identifier) { + tokenizer_.set_report_whitespace(true); + bool result = ConsumeIdentifier(identifier); + tokenizer_.set_report_whitespace(false); + return result; + } + + // Consume a string of form "<id1>.<id2>....<idN>". + bool ConsumeFullTypeName(TProtoStringType* name) { + DO(ConsumeIdentifier(name)); + while (TryConsume(".")) { + TProtoStringType part; + DO(ConsumeIdentifier(&part)); + *name += "."; + *name += part; + } + return true; + } + + bool ConsumeTypeUrlOrFullTypeName() { + TProtoStringType discarded; + DO(ConsumeIdentifier(&discarded)); + while (TryConsume(".") || TryConsume("/")) { + DO(ConsumeIdentifier(&discarded)); + } + return true; + } + + // Consumes a string and saves its value in the text parameter. + // Returns false if the token is not of type STRING. + bool ConsumeString(TProtoStringType* text) { + if (!LookingAtType(io::Tokenizer::TYPE_STRING)) { + ReportError("Expected string, got: " + tokenizer_.current().text); + return false; + } + + text->clear(); + while (LookingAtType(io::Tokenizer::TYPE_STRING)) { + io::Tokenizer::ParseStringAppend(tokenizer_.current().text, text); + + tokenizer_.Next(); + } + + return true; + } + + // Consumes a arc_ui64 and saves its value in the value parameter. + // Returns false if the token is not of type INTEGER. + bool ConsumeUnsignedInteger(arc_ui64* value, arc_ui64 max_value) { + if (!LookingAtType(io::Tokenizer::TYPE_INTEGER)) { + ReportError("Expected integer, got: " + tokenizer_.current().text); + return false; + } + + if (!io::Tokenizer::ParseInteger(tokenizer_.current().text, max_value, + value)) { + ReportError("Integer out of range (" + tokenizer_.current().text + ")"); + return false; + } + + tokenizer_.Next(); + return true; + } + + // Consumes an arc_i64 and saves its value in the value parameter. + // Note that since the tokenizer does not support negative numbers, + // we actually may consume an additional token (for the minus sign) in this + // method. Returns false if the token is not an integer + // (signed or otherwise). + bool ConsumeSignedInteger(arc_i64* value, arc_ui64 max_value) { + bool negative = false; + + if (TryConsume("-")) { + negative = true; + // Two's complement always allows one more negative integer than + // positive. + ++max_value; + } + + arc_ui64 unsigned_value; + + DO(ConsumeUnsignedInteger(&unsigned_value, max_value)); + + if (negative) { + if ((static_cast<arc_ui64>(kint64max) + 1) == unsigned_value) { + *value = kint64min; + } else { + *value = -static_cast<arc_i64>(unsigned_value); + } + } else { + *value = static_cast<arc_i64>(unsigned_value); + } + + return true; + } + + // Consumes a double and saves its value in the value parameter. + // Accepts decimal numbers only, rejects hex or oct numbers. + bool ConsumeUnsignedDecimalAsDouble(double* value, arc_ui64 max_value) { + if (!LookingAtType(io::Tokenizer::TYPE_INTEGER)) { + ReportError("Expected integer, got: " + tokenizer_.current().text); + return false; + } + + const TProtoStringType& text = tokenizer_.current().text; + if (IsHexNumber(text) || IsOctNumber(text)) { + ReportError("Expect a decimal number, got: " + text); + return false; + } + + arc_ui64 uint64_value; + if (io::Tokenizer::ParseInteger(text, max_value, &uint64_value)) { + *value = static_cast<double>(uint64_value); + } else { + // Uint64 overflow, attempt to parse as a double instead. + *value = io::Tokenizer::ParseFloat(text); + } + + tokenizer_.Next(); + return true; + } + + // Consumes a double and saves its value in the value parameter. + // Note that since the tokenizer does not support negative numbers, + // we actually may consume an additional token (for the minus sign) in this + // method. Returns false if the token is not a double + // (signed or otherwise). + bool ConsumeDouble(double* value) { + bool negative = false; + + if (TryConsume("-")) { + negative = true; + } + + // A double can actually be an integer, according to the tokenizer. + // Therefore, we must check both cases here. + if (LookingAtType(io::Tokenizer::TYPE_INTEGER)) { + // We have found an integer value for the double. + DO(ConsumeUnsignedDecimalAsDouble(value, kuint64max)); + } else if (LookingAtType(io::Tokenizer::TYPE_FLOAT)) { + // We have found a float value for the double. + *value = io::Tokenizer::ParseFloat(tokenizer_.current().text); + + // Mark the current token as consumed. + tokenizer_.Next(); + } else if (LookingAtType(io::Tokenizer::TYPE_IDENTIFIER)) { + TProtoStringType text = tokenizer_.current().text; + LowerString(&text); + if (text == "inf" || + text == "infinity") { + *value = std::numeric_limits<double>::infinity(); + tokenizer_.Next(); + } else if (text == "nan") { + *value = std::numeric_limits<double>::quiet_NaN(); + tokenizer_.Next(); + } else { + ReportError("Expected double, got: " + text); + return false; + } + } else { + ReportError("Expected double, got: " + tokenizer_.current().text); + return false; + } + + if (negative) { + *value = -*value; + } + + return true; + } + + // Consumes Any::type_url value, of form "type.googleapis.com/full.type.Name" + // or "type.googleprod.com/full.type.Name" + bool ConsumeAnyTypeUrl(TProtoStringType* full_type_name, TProtoStringType* prefix) { + // TODO(saito) Extend Consume() to consume multiple tokens at once, so that + // this code can be written as just DO(Consume(kGoogleApisTypePrefix)). + DO(ConsumeIdentifier(prefix)); + while (TryConsume(".")) { + TProtoStringType url; + DO(ConsumeIdentifier(&url)); + *prefix += "." + url; + } + DO(Consume("/")); + *prefix += "/"; + DO(ConsumeFullTypeName(full_type_name)); + + return true; + } + + // A helper function for reconstructing Any::value. Consumes a text of + // full_type_name, then serializes it into serialized_value. + bool ConsumeAnyValue(const Descriptor* value_descriptor, + TProtoStringType* serialized_value) { + DynamicMessageFactory factory; + const Message* value_prototype = factory.GetPrototype(value_descriptor); + if (value_prototype == nullptr) { + return false; + } + std::unique_ptr<Message> value(value_prototype->New()); + TProtoStringType sub_delimiter; + DO(ConsumeMessageDelimiter(&sub_delimiter)); + DO(ConsumeMessage(value.get(), sub_delimiter)); + + if (allow_partial_) { + value->AppendPartialToString(serialized_value); + } else { + if (!value->IsInitialized()) { + ReportError( + "Value of type \"" + value_descriptor->full_name() + + "\" stored in google.protobuf.Any has missing required fields"); + return false; + } + value->AppendToString(serialized_value); + } + return true; + } + + // Consumes a token and confirms that it matches that specified in the + // value parameter. Returns false if the token found does not match that + // which was specified. + bool Consume(const TProtoStringType& value) { + const TProtoStringType& current_value = tokenizer_.current().text; + + if (current_value != value) { + ReportError("Expected \"" + value + "\", found \"" + current_value + + "\"."); + return false; + } + + tokenizer_.Next(); + + return true; + } + + // Similar to `Consume`, but the following token may be tokenized as + // TYPE_WHITESPACE. + bool ConsumeBeforeWhitespace(const TProtoStringType& value) { + // Report whitespace after this token, but only once. + tokenizer_.set_report_whitespace(true); + bool result = Consume(value); + tokenizer_.set_report_whitespace(false); + return result; + } + + // Attempts to consume the supplied value. Returns false if a the + // token found does not match the value specified. + bool TryConsume(const TProtoStringType& value) { + if (tokenizer_.current().text == value) { + tokenizer_.Next(); + return true; + } else { + return false; + } + } + + // Similar to `TryConsume`, but the following token may be tokenized as + // TYPE_WHITESPACE. + bool TryConsumeBeforeWhitespace(const TProtoStringType& value) { + // Report whitespace after this token, but only once. + tokenizer_.set_report_whitespace(true); + bool result = TryConsume(value); + tokenizer_.set_report_whitespace(false); + return result; + } + + bool TryConsumeWhitespace(const TProtoStringType& message_type, + const char* field_type) { + if (LookingAtType(io::Tokenizer::TYPE_WHITESPACE)) { + tokenizer_.Next(); + return true; + } + + return false; + } + + // An internal instance of the Tokenizer's error collector, used to + // collect any base-level parse errors and feed them to the ParserImpl. + class ParserErrorCollector : public io::ErrorCollector { + public: + explicit ParserErrorCollector(TextFormat::Parser::ParserImpl* parser) + : parser_(parser) {} + + ~ParserErrorCollector() override {} + + void AddError(int line, int column, const TProtoStringType& message) override { + parser_->ReportError(line, column, message); + } + + void AddWarning(int line, int column, const TProtoStringType& message) override { + parser_->ReportWarning(line, column, message); + } + + private: + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ParserErrorCollector); + TextFormat::Parser::ParserImpl* parser_; + }; + + io::ErrorCollector* error_collector_; + const TextFormat::Finder* finder_; + ParseInfoTree* parse_info_tree_; + ParserErrorCollector tokenizer_error_collector_; + io::Tokenizer tokenizer_; + const Descriptor* root_message_type_; + SingularOverwritePolicy singular_overwrite_policy_; + const bool allow_case_insensitive_field_; + const bool allow_unknown_field_; + const bool allow_unknown_extension_; + const bool allow_unknown_enum_; + const bool allow_field_number_; + const bool allow_partial_; + const int initial_recursion_limit_; + int recursion_limit_; + bool had_errors_; +}; + +// =========================================================================== +// Internal class for writing text to the io::ZeroCopyOutputStream. Adapted +// from the Printer found in //net/proto2/io/public/printer.h +class TextFormat::Printer::TextGenerator + : public TextFormat::BaseTextGenerator { + public: + explicit TextGenerator(io::ZeroCopyOutputStream* output, + int initial_indent_level) + : output_(output), + buffer_(nullptr), + buffer_size_(0), + at_start_of_line_(true), + failed_(false), + insert_silent_marker_(false), + indent_level_(initial_indent_level), + initial_indent_level_(initial_indent_level) {} + + explicit TextGenerator(io::ZeroCopyOutputStream* output, + bool insert_silent_marker, int initial_indent_level) + : output_(output), + buffer_(nullptr), + buffer_size_(0), + at_start_of_line_(true), + failed_(false), + insert_silent_marker_(insert_silent_marker), + indent_level_(initial_indent_level), + initial_indent_level_(initial_indent_level) {} + + ~TextGenerator() { + // Only BackUp() if we're sure we've successfully called Next() at least + // once. + if (!failed_ && buffer_size_ > 0) { + output_->BackUp(buffer_size_); + } + } + + // Indent text by two spaces. After calling Indent(), two spaces will be + // inserted at the beginning of each line of text. Indent() may be called + // multiple times to produce deeper indents. + void Indent() override { ++indent_level_; } + + // Reduces the current indent level by two spaces, or crashes if the indent + // level is zero. + void Outdent() override { + if (indent_level_ == 0 || indent_level_ < initial_indent_level_) { + GOOGLE_LOG(DFATAL) << " Outdent() without matching Indent()."; + return; + } + + --indent_level_; + } + + size_t GetCurrentIndentationSize() const override { + return 2 * indent_level_; + } + + // Print text to the output stream. + void Print(const char* text, size_t size) override { + if (indent_level_ > 0) { + size_t pos = 0; // The number of bytes we've written so far. + for (size_t i = 0; i < size; i++) { + if (text[i] == '\n') { + // Saw newline. If there is more text, we may need to insert an + // indent here. So, write what we have so far, including the '\n'. + Write(text + pos, i - pos + 1); + pos = i + 1; + + // Setting this true will cause the next Write() to insert an indent + // first. + at_start_of_line_ = true; + } + } + // Write the rest. + Write(text + pos, size - pos); + } else { + Write(text, size); + if (size > 0 && text[size - 1] == '\n') { + at_start_of_line_ = true; + } + } + } + + // True if any write to the underlying stream failed. (We don't just + // crash in this case because this is an I/O failure, not a programming + // error.) + bool failed() const { return failed_; } + + void PrintMaybeWithMarker(StringPiece text) { + Print(text.data(), text.size()); + if (ConsumeInsertSilentMarker()) { + PrintLiteral(DEBUG_STRING_SILENT_MARKER); + } + } + + void PrintMaybeWithMarker(StringPiece text_head, + StringPiece text_tail) { + Print(text_head.data(), text_head.size()); + if (ConsumeInsertSilentMarker()) { + PrintLiteral(DEBUG_STRING_SILENT_MARKER); + } + Print(text_tail.data(), text_tail.size()); + } + + private: + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(TextGenerator); + + void Write(const char* data, size_t size) { + if (failed_) return; + if (size == 0) return; + + if (at_start_of_line_) { + // Insert an indent. + at_start_of_line_ = false; + WriteIndent(); + if (failed_) return; + } + + while (static_cast<arc_i64>(size) > buffer_size_) { + // Data exceeds space in the buffer. Copy what we can and request a + // new buffer. + if (buffer_size_ > 0) { + memcpy(buffer_, data, buffer_size_); + data += buffer_size_; + size -= buffer_size_; + } + void* void_buffer = nullptr; + failed_ = !output_->Next(&void_buffer, &buffer_size_); + if (failed_) return; + buffer_ = reinterpret_cast<char*>(void_buffer); + } + + // Buffer is big enough to receive the data; copy it. + memcpy(buffer_, data, size); + buffer_ += size; + buffer_size_ -= size; + } + + void WriteIndent() { + if (indent_level_ == 0) { + return; + } + GOOGLE_DCHECK(!failed_); + int size = GetCurrentIndentationSize(); + + while (size > buffer_size_) { + // Data exceeds space in the buffer. Write what we can and request a new + // buffer. + if (buffer_size_ > 0) { + memset(buffer_, ' ', buffer_size_); + } + size -= buffer_size_; + void* void_buffer; + failed_ = !output_->Next(&void_buffer, &buffer_size_); + if (failed_) return; + buffer_ = reinterpret_cast<char*>(void_buffer); + } + + // Buffer is big enough to receive the data; copy it. + memset(buffer_, ' ', size); + buffer_ += size; + buffer_size_ -= size; + } + + // Return the current value of insert_silent_marker_. If it is true, set it + // to false as we assume that a silent marker is inserted after a call to this + // function. + bool ConsumeInsertSilentMarker() { + if (insert_silent_marker_) { + insert_silent_marker_ = false; + return true; + } + return false; + } + + io::ZeroCopyOutputStream* const output_; + char* buffer_; + int buffer_size_; + bool at_start_of_line_; + bool failed_; + // This flag is false when inserting silent marker is disabled or a silent + // marker has been inserted. + bool insert_silent_marker_; + + int indent_level_; + int initial_indent_level_; +}; + +// =========================================================================== +// An internal field value printer that may insert a silent marker in +// DebugStrings. +class TextFormat::Printer::DebugStringFieldValuePrinter + : public TextFormat::FastFieldValuePrinter { + public: + void PrintMessageStart(const Message& /*message*/, int /*field_index*/, + int /*field_count*/, bool single_line_mode, + BaseTextGenerator* generator) const override { + // This is safe as only TextGenerator is used with + // DebugStringFieldValuePrinter. + TextGenerator* text_generator = static_cast<TextGenerator*>(generator); + if (single_line_mode) { + text_generator->PrintMaybeWithMarker(" ", "{ "); + } else { + text_generator->PrintMaybeWithMarker(" ", "{\n"); + } + } +}; + +// =========================================================================== +// An internal field value printer that escape UTF8 strings. +class TextFormat::Printer::FastFieldValuePrinterUtf8Escaping + : public TextFormat::Printer::DebugStringFieldValuePrinter { + public: + void PrintString(const TProtoStringType& val, + TextFormat::BaseTextGenerator* generator) const override { + generator->PrintLiteral("\""); + generator->PrintString(strings::Utf8SafeCEscape(val)); + generator->PrintLiteral("\""); + } + void PrintBytes(const TProtoStringType& val, + TextFormat::BaseTextGenerator* generator) const override { + return FastFieldValuePrinter::PrintString(val, generator); + } +}; + +// =========================================================================== +// Implementation of the default Finder for extensions. +TextFormat::Finder::~Finder() {} + +const FieldDescriptor* TextFormat::Finder::FindExtension( + Message* message, const TProtoStringType& name) const { + return DefaultFinderFindExtension(message, name); +} + +const FieldDescriptor* TextFormat::Finder::FindExtensionByNumber( + const Descriptor* descriptor, int number) const { + return DefaultFinderFindExtensionByNumber(descriptor, number); +} + +const Descriptor* TextFormat::Finder::FindAnyType( + const Message& message, const TProtoStringType& prefix, + const TProtoStringType& name) const { + return DefaultFinderFindAnyType(message, prefix, name); +} + +MessageFactory* TextFormat::Finder::FindExtensionFactory( + const FieldDescriptor* /*field*/) const { + return nullptr; +} + +// =========================================================================== + +TextFormat::Parser::Parser() + : error_collector_(nullptr), + finder_(nullptr), + parse_info_tree_(nullptr), + allow_partial_(false), + allow_case_insensitive_field_(false), + allow_unknown_field_(false), + allow_unknown_extension_(false), + allow_unknown_enum_(false), + allow_field_number_(false), + allow_relaxed_whitespace_(false), + allow_singular_overwrites_(false), + recursion_limit_(std::numeric_limits<int>::max()) {} + +TextFormat::Parser::~Parser() {} + +namespace { + +bool CheckParseInputSize(StringPiece input, + io::ErrorCollector* error_collector) { + if (input.size() > INT_MAX) { + error_collector->AddError( + -1, 0, + StrCat( + "Input size too large: ", static_cast<arc_i64>(input.size()), + " bytes", " > ", INT_MAX, " bytes.")); + return false; + } + return true; +} + +} // namespace + +bool TextFormat::Parser::Parse(io::ZeroCopyInputStream* input, + Message* output) { + output->Clear(); + + ParserImpl::SingularOverwritePolicy overwrites_policy = + allow_singular_overwrites_ ? ParserImpl::ALLOW_SINGULAR_OVERWRITES + : ParserImpl::FORBID_SINGULAR_OVERWRITES; + + ParserImpl parser(output->GetDescriptor(), input, error_collector_, finder_, + parse_info_tree_, overwrites_policy, + allow_case_insensitive_field_, allow_unknown_field_, + allow_unknown_extension_, allow_unknown_enum_, + allow_field_number_, allow_relaxed_whitespace_, + allow_partial_, recursion_limit_); + return MergeUsingImpl(input, output, &parser); +} + +bool TextFormat::Parser::ParseFromString(ConstStringParam input, + Message* output) { + DO(CheckParseInputSize(input, error_collector_)); + io::ArrayInputStream input_stream(input.data(), input.size()); + return Parse(&input_stream, output); +} + +bool TextFormat::Parser::Merge(io::ZeroCopyInputStream* input, + Message* output) { + ParserImpl parser(output->GetDescriptor(), input, error_collector_, finder_, + parse_info_tree_, ParserImpl::ALLOW_SINGULAR_OVERWRITES, + allow_case_insensitive_field_, allow_unknown_field_, + allow_unknown_extension_, allow_unknown_enum_, + allow_field_number_, allow_relaxed_whitespace_, + allow_partial_, recursion_limit_); + return MergeUsingImpl(input, output, &parser); +} + +bool TextFormat::Parser::MergeFromString(ConstStringParam input, + Message* output) { + DO(CheckParseInputSize(input, error_collector_)); + io::ArrayInputStream input_stream(input.data(), input.size()); + return Merge(&input_stream, output); +} + + +bool TextFormat::Parser::MergeUsingImpl(io::ZeroCopyInputStream* /* input */, + Message* output, + ParserImpl* parser_impl) { + if (!parser_impl->Parse(output)) return false; + if (!allow_partial_ && !output->IsInitialized()) { + std::vector<TProtoStringType> missing_fields; + output->FindInitializationErrors(&missing_fields); + parser_impl->ReportError(-1, 0, + "Message missing required fields: " + + Join(missing_fields, ", ")); + return false; + } + return true; +} + +bool TextFormat::Parser::ParseFieldValueFromString(const TProtoStringType& input, + const FieldDescriptor* field, + Message* output) { + io::ArrayInputStream input_stream(input.data(), input.size()); + ParserImpl parser( + output->GetDescriptor(), &input_stream, error_collector_, finder_, + parse_info_tree_, ParserImpl::ALLOW_SINGULAR_OVERWRITES, + allow_case_insensitive_field_, allow_unknown_field_, + allow_unknown_extension_, allow_unknown_enum_, allow_field_number_, + allow_relaxed_whitespace_, allow_partial_, recursion_limit_); + return parser.ParseField(field, output); +} + +/* static */ bool TextFormat::Parse(io::ZeroCopyInputStream* input, + Message* output) { + return Parser().Parse(input, output); +} + +/* static */ bool TextFormat::Merge(io::ZeroCopyInputStream* input, + Message* output) { + return Parser().Merge(input, output); +} + +/* static */ bool TextFormat::ParseFromString(ConstStringParam input, + Message* output) { + return Parser().ParseFromString(input, output); +} + +/* static */ bool TextFormat::MergeFromString(ConstStringParam input, + Message* output) { + return Parser().MergeFromString(input, output); +} + + +#undef DO + +// =========================================================================== + +TextFormat::BaseTextGenerator::~BaseTextGenerator() {} + +namespace { + +// A BaseTextGenerator that writes to a string. +class StringBaseTextGenerator : public TextFormat::BaseTextGenerator { + public: + void Print(const char* text, size_t size) override { + output_.append(text, size); + } + +// Some compilers do not support ref-qualifiers even in C++11 mode. +// Disable the optimization for now and revisit it later. +#if 0 // LANG_CXX11 + TProtoStringType Consume() && { return std::move(output_); } +#else // !LANG_CXX11 + const TProtoStringType& Get() { return output_; } +#endif // LANG_CXX11 + + private: + TProtoStringType output_; +}; + +} // namespace + +// The default implementation for FieldValuePrinter. We just delegate the +// implementation to the default FastFieldValuePrinter to avoid duplicating the +// logic. +TextFormat::FieldValuePrinter::FieldValuePrinter() {} +TextFormat::FieldValuePrinter::~FieldValuePrinter() {} + +#if 0 // LANG_CXX11 +#define FORWARD_IMPL(fn, ...) \ + StringBaseTextGenerator generator; \ + delegate_.fn(__VA_ARGS__, &generator); \ + return std::move(generator).Consume() +#else // !LANG_CXX11 +#define FORWARD_IMPL(fn, ...) \ + StringBaseTextGenerator generator; \ + delegate_.fn(__VA_ARGS__, &generator); \ + return generator.Get() +#endif // LANG_CXX11 + +TProtoStringType TextFormat::FieldValuePrinter::PrintBool(bool val) const { + FORWARD_IMPL(PrintBool, val); +} +TProtoStringType TextFormat::FieldValuePrinter::PrintInt32(arc_i32 val) const { + FORWARD_IMPL(PrintInt32, val); +} +TProtoStringType TextFormat::FieldValuePrinter::PrintUInt32(arc_ui32 val) const { + FORWARD_IMPL(PrintUInt32, val); +} +TProtoStringType TextFormat::FieldValuePrinter::PrintInt64(arc_i64 val) const { + FORWARD_IMPL(PrintInt64, val); +} +TProtoStringType TextFormat::FieldValuePrinter::PrintUInt64(arc_ui64 val) const { + FORWARD_IMPL(PrintUInt64, val); +} +TProtoStringType TextFormat::FieldValuePrinter::PrintFloat(float val) const { + FORWARD_IMPL(PrintFloat, val); +} +TProtoStringType TextFormat::FieldValuePrinter::PrintDouble(double val) const { + FORWARD_IMPL(PrintDouble, val); +} +TProtoStringType TextFormat::FieldValuePrinter::PrintString( + const TProtoStringType& val) const { + FORWARD_IMPL(PrintString, val); +} +TProtoStringType TextFormat::FieldValuePrinter::PrintBytes( + const TProtoStringType& val) const { + return PrintString(val); +} +TProtoStringType TextFormat::FieldValuePrinter::PrintEnum( + arc_i32 val, const TProtoStringType& name) const { + FORWARD_IMPL(PrintEnum, val, name); +} +TProtoStringType TextFormat::FieldValuePrinter::PrintFieldName( + const Message& message, const Reflection* reflection, + const FieldDescriptor* field) const { + FORWARD_IMPL(PrintFieldName, message, reflection, field); +} +TProtoStringType TextFormat::FieldValuePrinter::PrintMessageStart( + const Message& message, int field_index, int field_count, + bool single_line_mode) const { + FORWARD_IMPL(PrintMessageStart, message, field_index, field_count, + single_line_mode); +} +TProtoStringType TextFormat::FieldValuePrinter::PrintMessageEnd( + const Message& message, int field_index, int field_count, + bool single_line_mode) const { + FORWARD_IMPL(PrintMessageEnd, message, field_index, field_count, + single_line_mode); +} +#undef FORWARD_IMPL + +TextFormat::FastFieldValuePrinter::FastFieldValuePrinter() {} +TextFormat::FastFieldValuePrinter::~FastFieldValuePrinter() {} +void TextFormat::FastFieldValuePrinter::PrintBool( + bool val, BaseTextGenerator* generator) const { + if (val) { + generator->PrintLiteral("true"); + } else { + generator->PrintLiteral("false"); + } +} +void TextFormat::FastFieldValuePrinter::PrintInt32( + arc_i32 val, BaseTextGenerator* generator) const { + generator->PrintString(StrCat(val)); +} +void TextFormat::FastFieldValuePrinter::PrintUInt32( + arc_ui32 val, BaseTextGenerator* generator) const { + generator->PrintString(StrCat(val)); +} +void TextFormat::FastFieldValuePrinter::PrintInt64( + arc_i64 val, BaseTextGenerator* generator) const { + generator->PrintString(StrCat(val)); +} +void TextFormat::FastFieldValuePrinter::PrintUInt64( + arc_ui64 val, BaseTextGenerator* generator) const { + generator->PrintString(StrCat(val)); +} +void TextFormat::FastFieldValuePrinter::PrintFloat( + float val, BaseTextGenerator* generator) const { + generator->PrintString(!std::isnan(val) ? SimpleFtoa(val) : "nan"); +} +void TextFormat::FastFieldValuePrinter::PrintDouble( + double val, BaseTextGenerator* generator) const { + generator->PrintString(!std::isnan(val) ? SimpleDtoa(val) : "nan"); +} +void TextFormat::FastFieldValuePrinter::PrintEnum( + arc_i32 /*val*/, const TProtoStringType& name, + BaseTextGenerator* generator) const { + generator->PrintString(name); +} + +void TextFormat::FastFieldValuePrinter::PrintString( + const TProtoStringType& val, BaseTextGenerator* generator) const { + generator->PrintLiteral("\""); + generator->PrintString(CEscape(val)); + generator->PrintLiteral("\""); +} +void TextFormat::FastFieldValuePrinter::PrintBytes( + const TProtoStringType& val, BaseTextGenerator* generator) const { + PrintString(val, generator); +} +void TextFormat::FastFieldValuePrinter::PrintFieldName( + const Message& message, int /*field_index*/, int /*field_count*/, + const Reflection* reflection, const FieldDescriptor* field, + BaseTextGenerator* generator) const { + PrintFieldName(message, reflection, field, generator); +} +void TextFormat::FastFieldValuePrinter::PrintFieldName( + const Message& /*message*/, const Reflection* /*reflection*/, + const FieldDescriptor* field, BaseTextGenerator* generator) const { + if (field->is_extension()) { + generator->PrintLiteral("["); + generator->PrintString(field->PrintableNameForExtension()); + generator->PrintLiteral("]"); + } else if (field->type() == FieldDescriptor::TYPE_GROUP) { + // Groups must be serialized with their original capitalization. + generator->PrintString(field->message_type()->name()); + } else { + generator->PrintString(field->name()); + } +} +void TextFormat::FastFieldValuePrinter::PrintMessageStart( + const Message& /*message*/, int /*field_index*/, int /*field_count*/, + bool single_line_mode, BaseTextGenerator* generator) const { + if (single_line_mode) { + generator->PrintLiteral(" { "); + } else { + generator->PrintLiteral(" {\n"); + } +} +bool TextFormat::FastFieldValuePrinter::PrintMessageContent( + const Message& /*message*/, int /*field_index*/, int /*field_count*/, + bool /*single_line_mode*/, BaseTextGenerator* /*generator*/) const { + return false; // Use the default printing function. +} +void TextFormat::FastFieldValuePrinter::PrintMessageEnd( + const Message& /*message*/, int /*field_index*/, int /*field_count*/, + bool single_line_mode, BaseTextGenerator* generator) const { + if (single_line_mode) { + generator->PrintLiteral("} "); + } else { + generator->PrintLiteral("}\n"); + } +} + +namespace { + +// A legacy compatibility wrapper. Takes ownership of the delegate. +class FieldValuePrinterWrapper : public TextFormat::FastFieldValuePrinter { + public: + explicit FieldValuePrinterWrapper( + const TextFormat::FieldValuePrinter* delegate) + : delegate_(delegate) {} + + void SetDelegate(const TextFormat::FieldValuePrinter* delegate) { + delegate_.reset(delegate); + } + + void PrintBool(bool val, + TextFormat::BaseTextGenerator* generator) const override { + generator->PrintString(delegate_->PrintBool(val)); + } + void PrintInt32(arc_i32 val, + TextFormat::BaseTextGenerator* generator) const override { + generator->PrintString(delegate_->PrintInt32(val)); + } + void PrintUInt32(arc_ui32 val, + TextFormat::BaseTextGenerator* generator) const override { + generator->PrintString(delegate_->PrintUInt32(val)); + } + void PrintInt64(arc_i64 val, + TextFormat::BaseTextGenerator* generator) const override { + generator->PrintString(delegate_->PrintInt64(val)); + } + void PrintUInt64(arc_ui64 val, + TextFormat::BaseTextGenerator* generator) const override { + generator->PrintString(delegate_->PrintUInt64(val)); + } + void PrintFloat(float val, + TextFormat::BaseTextGenerator* generator) const override { + generator->PrintString(delegate_->PrintFloat(val)); + } + void PrintDouble(double val, + TextFormat::BaseTextGenerator* generator) const override { + generator->PrintString(delegate_->PrintDouble(val)); + } + void PrintString(const TProtoStringType& val, + TextFormat::BaseTextGenerator* generator) const override { + generator->PrintString(delegate_->PrintString(val)); + } + void PrintBytes(const TProtoStringType& val, + TextFormat::BaseTextGenerator* generator) const override { + generator->PrintString(delegate_->PrintBytes(val)); + } + void PrintEnum(arc_i32 val, const TProtoStringType& name, + TextFormat::BaseTextGenerator* generator) const override { + generator->PrintString(delegate_->PrintEnum(val, name)); + } + void PrintFieldName(const Message& message, int /*field_index*/, + int /*field_count*/, const Reflection* reflection, + const FieldDescriptor* field, + TextFormat::BaseTextGenerator* generator) const override { + generator->PrintString( + delegate_->PrintFieldName(message, reflection, field)); + } + void PrintFieldName(const Message& message, const Reflection* reflection, + const FieldDescriptor* field, + TextFormat::BaseTextGenerator* generator) const override { + generator->PrintString( + delegate_->PrintFieldName(message, reflection, field)); + } + void PrintMessageStart( + const Message& message, int field_index, int field_count, + bool single_line_mode, + TextFormat::BaseTextGenerator* generator) const override { + generator->PrintString(delegate_->PrintMessageStart( + message, field_index, field_count, single_line_mode)); + } + void PrintMessageEnd( + const Message& message, int field_index, int field_count, + bool single_line_mode, + TextFormat::BaseTextGenerator* generator) const override { + generator->PrintString(delegate_->PrintMessageEnd( + message, field_index, field_count, single_line_mode)); + } + + private: + std::unique_ptr<const TextFormat::FieldValuePrinter> delegate_; +}; + +} // namespace + +const char* const TextFormat::Printer::kDoNotParse = + "DO NOT PARSE: fields may be stripped and missing.\n"; + +TextFormat::Printer::Printer() + : initial_indent_level_(0), + single_line_mode_(false), + use_field_number_(false), + use_short_repeated_primitives_(false), + insert_silent_marker_(false), + hide_unknown_fields_(false), + print_message_fields_in_index_order_(false), + expand_any_(false), + truncate_string_field_longer_than_(0LL), + finder_(nullptr) { + SetUseUtf8StringEscaping(false); +} + +void TextFormat::Printer::SetUseUtf8StringEscaping(bool as_utf8) { + SetDefaultFieldValuePrinter(as_utf8 ? new FastFieldValuePrinterUtf8Escaping() + : new DebugStringFieldValuePrinter()); +} + +void TextFormat::Printer::SetDefaultFieldValuePrinter( + const FieldValuePrinter* printer) { + default_field_value_printer_.reset(new FieldValuePrinterWrapper(printer)); +} + +void TextFormat::Printer::SetDefaultFieldValuePrinter( + const FastFieldValuePrinter* printer) { + default_field_value_printer_.reset(printer); +} + +bool TextFormat::Printer::RegisterFieldValuePrinter( + const FieldDescriptor* field, const FieldValuePrinter* printer) { + if (field == nullptr || printer == nullptr) { + return false; + } + std::unique_ptr<FieldValuePrinterWrapper> wrapper( + new FieldValuePrinterWrapper(nullptr)); + auto pair = custom_printers_.insert(std::make_pair(field, nullptr)); + if (pair.second) { + wrapper->SetDelegate(printer); + pair.first->second = std::move(wrapper); + return true; + } else { + return false; + } +} + +bool TextFormat::Printer::RegisterFieldValuePrinter( + const FieldDescriptor* field, const FastFieldValuePrinter* printer) { + if (field == nullptr || printer == nullptr) { + return false; + } + auto pair = custom_printers_.insert(std::make_pair(field, nullptr)); + if (pair.second) { + pair.first->second.reset(printer); + return true; + } else { + return false; + } +} + +bool TextFormat::Printer::RegisterMessagePrinter( + const Descriptor* descriptor, const MessagePrinter* printer) { + if (descriptor == nullptr || printer == nullptr) { + return false; + } + auto pair = + custom_message_printers_.insert(std::make_pair(descriptor, nullptr)); + if (pair.second) { + pair.first->second.reset(printer); + return true; + } else { + return false; + } +} + +bool TextFormat::Printer::PrintToString(const Message& message, + TProtoStringType* output) const { + GOOGLE_DCHECK(output) << "output specified is nullptr"; + + output->clear(); + io::StringOutputStream output_stream(output); + + return Print(message, &output_stream); +} + +bool TextFormat::Printer::PrintUnknownFieldsToString( + const UnknownFieldSet& unknown_fields, TProtoStringType* output) const { + GOOGLE_DCHECK(output) << "output specified is nullptr"; + + output->clear(); + io::StringOutputStream output_stream(output); + return PrintUnknownFields(unknown_fields, &output_stream); +} + +bool TextFormat::Printer::Print(const Message& message, + io::ZeroCopyOutputStream* output) const { + TextGenerator generator(output, insert_silent_marker_, initial_indent_level_); + + Print(message, &generator); + + // Output false if the generator failed internally. + return !generator.failed(); +} + +// Maximum recursion depth for heuristically printing out length-delimited +// unknown fields as messages. +static constexpr int kUnknownFieldRecursionLimit = 10; + +bool TextFormat::Printer::PrintUnknownFields( + const UnknownFieldSet& unknown_fields, + io::ZeroCopyOutputStream* output) const { + TextGenerator generator(output, initial_indent_level_); + + PrintUnknownFields(unknown_fields, &generator, kUnknownFieldRecursionLimit); + + // Output false if the generator failed internally. + return !generator.failed(); +} + +namespace { +// Comparison functor for sorting FieldDescriptors by field index. +// Normal fields have higher precedence than extensions. +struct FieldIndexSorter { + bool operator()(const FieldDescriptor* left, + const FieldDescriptor* right) const { + if (left->is_extension() && right->is_extension()) { + return left->number() < right->number(); + } else if (left->is_extension()) { + return false; + } else if (right->is_extension()) { + return true; + } else { + return left->index() < right->index(); + } + } +}; + +} // namespace + +bool TextFormat::Printer::PrintAny(const Message& message, + TextGenerator* generator) const { + const FieldDescriptor* type_url_field; + const FieldDescriptor* value_field; + if (!internal::GetAnyFieldDescriptors(message, &type_url_field, + &value_field)) { + return false; + } + + const Reflection* reflection = message.GetReflection(); + + // Extract the full type name from the type_url field. + const TProtoStringType& type_url = reflection->GetString(message, type_url_field); + TProtoStringType url_prefix; + TProtoStringType full_type_name; + if (!internal::ParseAnyTypeUrl(type_url, &url_prefix, &full_type_name)) { + return false; + } + + // Print the "value" in text. + const Descriptor* value_descriptor = + finder_ ? finder_->FindAnyType(message, url_prefix, full_type_name) + : DefaultFinderFindAnyType(message, url_prefix, full_type_name); + if (value_descriptor == nullptr) { + GOOGLE_LOG(WARNING) << "Can't print proto content: proto type " << type_url + << " not found"; + return false; + } + DynamicMessageFactory factory; + std::unique_ptr<Message> value_message( + factory.GetPrototype(value_descriptor)->New()); + TProtoStringType serialized_value = reflection->GetString(message, value_field); + if (!value_message->ParseFromString(serialized_value)) { + GOOGLE_LOG(WARNING) << type_url << ": failed to parse contents"; + return false; + } + generator->PrintLiteral("["); + generator->PrintString(type_url); + generator->PrintLiteral("]"); + const FastFieldValuePrinter* printer = GetFieldPrinter(value_field); + printer->PrintMessageStart(message, -1, 0, single_line_mode_, generator); + generator->Indent(); + Print(*value_message, generator); + generator->Outdent(); + printer->PrintMessageEnd(message, -1, 0, single_line_mode_, generator); + return true; +} + +void TextFormat::Printer::Print(const Message& message, + TextGenerator* generator) const { + const Reflection* reflection = message.GetReflection(); + if (!reflection) { + // This message does not provide any way to describe its structure. + // Parse it again in an UnknownFieldSet, and display this instead. + UnknownFieldSet unknown_fields; + { + TProtoStringType serialized = message.SerializeAsString(); + io::ArrayInputStream input(serialized.data(), serialized.size()); + unknown_fields.ParseFromZeroCopyStream(&input); + } + PrintUnknownFields(unknown_fields, generator, kUnknownFieldRecursionLimit); + return; + } + const Descriptor* descriptor = message.GetDescriptor(); + auto itr = custom_message_printers_.find(descriptor); + if (itr != custom_message_printers_.end()) { + itr->second->Print(message, single_line_mode_, generator); + return; + } + if (descriptor->full_name() == internal::kAnyFullTypeName && expand_any_ && + PrintAny(message, generator)) { + return; + } + std::vector<const FieldDescriptor*> fields; + if (descriptor->options().map_entry()) { + fields.push_back(descriptor->field(0)); + fields.push_back(descriptor->field(1)); + } else { + reflection->ListFieldsOmitStripped(message, &fields); + if (reflection->IsMessageStripped(message.GetDescriptor())) { + generator->Print(kDoNotParse, std::strlen(kDoNotParse)); + } + } + + if (print_message_fields_in_index_order_) { + std::sort(fields.begin(), fields.end(), FieldIndexSorter()); + } + for (const FieldDescriptor* field : fields) { + PrintField(message, reflection, field, generator); + } + if (!hide_unknown_fields_) { + PrintUnknownFields(reflection->GetUnknownFields(message), generator, + kUnknownFieldRecursionLimit); + } +} + +void TextFormat::Printer::PrintFieldValueToString(const Message& message, + const FieldDescriptor* field, + int index, + TProtoStringType* output) const { + GOOGLE_DCHECK(output) << "output specified is nullptr"; + + output->clear(); + io::StringOutputStream output_stream(output); + TextGenerator generator(&output_stream, initial_indent_level_); + + PrintFieldValue(message, message.GetReflection(), field, index, &generator); +} + +class MapEntryMessageComparator { + public: + explicit MapEntryMessageComparator(const Descriptor* descriptor) + : field_(descriptor->field(0)) {} + + bool operator()(const Message* a, const Message* b) { + const Reflection* reflection = a->GetReflection(); + switch (field_->cpp_type()) { + case FieldDescriptor::CPPTYPE_BOOL: { + bool first = reflection->GetBool(*a, field_); + bool second = reflection->GetBool(*b, field_); + return first < second; + } + case FieldDescriptor::CPPTYPE_INT32: { + arc_i32 first = reflection->GetInt32(*a, field_); + arc_i32 second = reflection->GetInt32(*b, field_); + return first < second; + } + case FieldDescriptor::CPPTYPE_INT64: { + arc_i64 first = reflection->GetInt64(*a, field_); + arc_i64 second = reflection->GetInt64(*b, field_); + return first < second; + } + case FieldDescriptor::CPPTYPE_UINT32: { + arc_ui32 first = reflection->GetUInt32(*a, field_); + arc_ui32 second = reflection->GetUInt32(*b, field_); + return first < second; + } + case FieldDescriptor::CPPTYPE_UINT64: { + arc_ui64 first = reflection->GetUInt64(*a, field_); + arc_ui64 second = reflection->GetUInt64(*b, field_); + return first < second; + } + case FieldDescriptor::CPPTYPE_STRING: { + TProtoStringType first = reflection->GetString(*a, field_); + TProtoStringType second = reflection->GetString(*b, field_); + return first < second; + } + default: + GOOGLE_LOG(DFATAL) << "Invalid key for map field."; + return true; + } + } + + private: + const FieldDescriptor* field_; +}; + +namespace internal { +class MapFieldPrinterHelper { + public: + // DynamicMapSorter::Sort cannot be used because it enfores syncing with + // repeated field. + static bool SortMap(const Message& message, const Reflection* reflection, + const FieldDescriptor* field, + std::vector<const Message*>* sorted_map_field); + static void CopyKey(const MapKey& key, Message* message, + const FieldDescriptor* field_desc); + static void CopyValue(const MapValueRef& value, Message* message, + const FieldDescriptor* field_desc); +}; + +// Returns true if elements contained in sorted_map_field need to be released. +bool MapFieldPrinterHelper::SortMap( + const Message& message, const Reflection* reflection, + const FieldDescriptor* field, + std::vector<const Message*>* sorted_map_field) { + bool need_release = false; + const MapFieldBase& base = *reflection->GetMapData(message, field); + + if (base.IsRepeatedFieldValid()) { + const RepeatedPtrField<Message>& map_field = + reflection->GetRepeatedPtrFieldInternal<Message>(message, field); + for (int i = 0; i < map_field.size(); ++i) { + sorted_map_field->push_back( + const_cast<RepeatedPtrField<Message>*>(&map_field)->Mutable(i)); + } + } else { + // TODO(teboring): For performance, instead of creating map entry message + // for each element, just store map keys and sort them. + const Descriptor* map_entry_desc = field->message_type(); + const Message* prototype = + reflection->GetMessageFactory()->GetPrototype(map_entry_desc); + for (MapIterator iter = + reflection->MapBegin(const_cast<Message*>(&message), field); + iter != reflection->MapEnd(const_cast<Message*>(&message), field); + ++iter) { + Message* map_entry_message = prototype->New(); + CopyKey(iter.GetKey(), map_entry_message, map_entry_desc->field(0)); + CopyValue(iter.GetValueRef(), map_entry_message, + map_entry_desc->field(1)); + sorted_map_field->push_back(map_entry_message); + } + need_release = true; + } + + MapEntryMessageComparator comparator(field->message_type()); + std::stable_sort(sorted_map_field->begin(), sorted_map_field->end(), + comparator); + return need_release; +} + +void MapFieldPrinterHelper::CopyKey(const MapKey& key, Message* message, + const FieldDescriptor* field_desc) { + const Reflection* reflection = message->GetReflection(); + switch (field_desc->cpp_type()) { + case FieldDescriptor::CPPTYPE_DOUBLE: + case FieldDescriptor::CPPTYPE_FLOAT: + case FieldDescriptor::CPPTYPE_ENUM: + case FieldDescriptor::CPPTYPE_MESSAGE: + GOOGLE_LOG(ERROR) << "Not supported."; + break; + case FieldDescriptor::CPPTYPE_STRING: + reflection->SetString(message, field_desc, key.GetStringValue()); + return; + case FieldDescriptor::CPPTYPE_INT64: + reflection->SetInt64(message, field_desc, key.GetInt64Value()); + return; + case FieldDescriptor::CPPTYPE_INT32: + reflection->SetInt32(message, field_desc, key.GetInt32Value()); + return; + case FieldDescriptor::CPPTYPE_UINT64: + reflection->SetUInt64(message, field_desc, key.GetUInt64Value()); + return; + case FieldDescriptor::CPPTYPE_UINT32: + reflection->SetUInt32(message, field_desc, key.GetUInt32Value()); + return; + case FieldDescriptor::CPPTYPE_BOOL: + reflection->SetBool(message, field_desc, key.GetBoolValue()); + return; + } +} + +void MapFieldPrinterHelper::CopyValue(const MapValueRef& value, + Message* message, + const FieldDescriptor* field_desc) { + const Reflection* reflection = message->GetReflection(); + switch (field_desc->cpp_type()) { + case FieldDescriptor::CPPTYPE_DOUBLE: + reflection->SetDouble(message, field_desc, value.GetDoubleValue()); + return; + case FieldDescriptor::CPPTYPE_FLOAT: + reflection->SetFloat(message, field_desc, value.GetFloatValue()); + return; + case FieldDescriptor::CPPTYPE_ENUM: + reflection->SetEnumValue(message, field_desc, value.GetEnumValue()); + return; + case FieldDescriptor::CPPTYPE_MESSAGE: { + Message* sub_message = value.GetMessageValue().New(); + sub_message->CopyFrom(value.GetMessageValue()); + reflection->SetAllocatedMessage(message, sub_message, field_desc); + return; + } + case FieldDescriptor::CPPTYPE_STRING: + reflection->SetString(message, field_desc, value.GetStringValue()); + return; + case FieldDescriptor::CPPTYPE_INT64: + reflection->SetInt64(message, field_desc, value.GetInt64Value()); + return; + case FieldDescriptor::CPPTYPE_INT32: + reflection->SetInt32(message, field_desc, value.GetInt32Value()); + return; + case FieldDescriptor::CPPTYPE_UINT64: + reflection->SetUInt64(message, field_desc, value.GetUInt64Value()); + return; + case FieldDescriptor::CPPTYPE_UINT32: + reflection->SetUInt32(message, field_desc, value.GetUInt32Value()); + return; + case FieldDescriptor::CPPTYPE_BOOL: + reflection->SetBool(message, field_desc, value.GetBoolValue()); + return; + } +} +} // namespace internal + +void TextFormat::Printer::PrintField(const Message& message, + const Reflection* reflection, + const FieldDescriptor* field, + TextGenerator* generator) const { + if (use_short_repeated_primitives_ && field->is_repeated() && + field->cpp_type() != FieldDescriptor::CPPTYPE_STRING && + field->cpp_type() != FieldDescriptor::CPPTYPE_MESSAGE) { + PrintShortRepeatedField(message, reflection, field, generator); + return; + } + + int count = 0; + + if (field->is_repeated()) { + count = reflection->FieldSize(message, field); + } else if (reflection->HasField(message, field) || + field->containing_type()->options().map_entry()) { + count = 1; + } + + std::vector<const Message*> sorted_map_field; + bool need_release = false; + bool is_map = field->is_map(); + if (is_map) { + need_release = internal::MapFieldPrinterHelper::SortMap( + message, reflection, field, &sorted_map_field); + } + + for (int j = 0; j < count; ++j) { + const int field_index = field->is_repeated() ? j : -1; + + PrintFieldName(message, field_index, count, reflection, field, generator); + + if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) { + const FastFieldValuePrinter* printer = GetFieldPrinter(field); + const Message& sub_message = + field->is_repeated() + ? (is_map ? *sorted_map_field[j] + : reflection->GetRepeatedMessage(message, field, j)) + : reflection->GetMessage(message, field); + printer->PrintMessageStart(sub_message, field_index, count, + single_line_mode_, generator); + generator->Indent(); + if (!printer->PrintMessageContent(sub_message, field_index, count, + single_line_mode_, generator)) { + Print(sub_message, generator); + } + generator->Outdent(); + printer->PrintMessageEnd(sub_message, field_index, count, + single_line_mode_, generator); + } else { + generator->PrintMaybeWithMarker(": "); + // Write the field value. + PrintFieldValue(message, reflection, field, field_index, generator); + if (single_line_mode_) { + generator->PrintLiteral(" "); + } else { + generator->PrintLiteral("\n"); + } + } + } + + if (need_release) { + for (const Message* message_to_delete : sorted_map_field) { + delete message_to_delete; + } + } +} + +void TextFormat::Printer::PrintShortRepeatedField( + const Message& message, const Reflection* reflection, + const FieldDescriptor* field, TextGenerator* generator) const { + // Print primitive repeated field in short form. + int size = reflection->FieldSize(message, field); + PrintFieldName(message, /*field_index=*/-1, /*field_count=*/size, reflection, + field, generator); + generator->PrintMaybeWithMarker(": ", "["); + for (int i = 0; i < size; i++) { + if (i > 0) generator->PrintLiteral(", "); + PrintFieldValue(message, reflection, field, i, generator); + } + if (single_line_mode_) { + generator->PrintLiteral("] "); + } else { + generator->PrintLiteral("]\n"); + } +} + +void TextFormat::Printer::PrintFieldName(const Message& message, + int field_index, int field_count, + const Reflection* reflection, + const FieldDescriptor* field, + TextGenerator* generator) const { + // if use_field_number_ is true, prints field number instead + // of field name. + if (use_field_number_) { + generator->PrintString(StrCat(field->number())); + return; + } + + const FastFieldValuePrinter* printer = GetFieldPrinter(field); + printer->PrintFieldName(message, field_index, field_count, reflection, field, + generator); +} + +void TextFormat::Printer::PrintFieldValue(const Message& message, + const Reflection* reflection, + const FieldDescriptor* field, + int index, + TextGenerator* generator) const { + GOOGLE_DCHECK(field->is_repeated() || (index == -1)) + << "Index must be -1 for non-repeated fields"; + + const FastFieldValuePrinter* printer = GetFieldPrinter(field); + + switch (field->cpp_type()) { +#define OUTPUT_FIELD(CPPTYPE, METHOD) \ + case FieldDescriptor::CPPTYPE_##CPPTYPE: \ + printer->Print##METHOD( \ + field->is_repeated() \ + ? reflection->GetRepeated##METHOD(message, field, index) \ + : reflection->Get##METHOD(message, field), \ + generator); \ + break + + OUTPUT_FIELD(INT32, Int32); + OUTPUT_FIELD(INT64, Int64); + OUTPUT_FIELD(UINT32, UInt32); + OUTPUT_FIELD(UINT64, UInt64); + OUTPUT_FIELD(FLOAT, Float); + OUTPUT_FIELD(DOUBLE, Double); + OUTPUT_FIELD(BOOL, Bool); +#undef OUTPUT_FIELD + + case FieldDescriptor::CPPTYPE_STRING: { + TProtoStringType scratch; + const TProtoStringType& value = + field->is_repeated() + ? reflection->GetRepeatedStringReference(message, field, index, + &scratch) + : reflection->GetStringReference(message, field, &scratch); + const TProtoStringType* value_to_print = &value; + TProtoStringType truncated_value; + if (truncate_string_field_longer_than_ > 0 && + static_cast<size_t>(truncate_string_field_longer_than_) < + value.size()) { + truncated_value = value.substr(0, truncate_string_field_longer_than_) + + "...<truncated>..."; + value_to_print = &truncated_value; + } + if (field->type() == FieldDescriptor::TYPE_STRING) { + printer->PrintString(*value_to_print, generator); + } else { + GOOGLE_DCHECK_EQ(field->type(), FieldDescriptor::TYPE_BYTES); + printer->PrintBytes(*value_to_print, generator); + } + break; + } + + case FieldDescriptor::CPPTYPE_ENUM: { + int enum_value = + field->is_repeated() + ? reflection->GetRepeatedEnumValue(message, field, index) + : reflection->GetEnumValue(message, field); + const EnumValueDescriptor* enum_desc = + field->enum_type()->FindValueByNumber(enum_value); + if (enum_desc != nullptr) { + printer->PrintEnum(enum_value, enum_desc->name(), generator); + } else { + // Ordinarily, enum_desc should not be null, because proto2 has the + // invariant that set enum field values must be in-range, but with the + // new integer-based API for enums (or the RepeatedField<int> loophole), + // it is possible for the user to force an unknown integer value. So we + // simply use the integer value itself as the enum value name in this + // case. + printer->PrintEnum(enum_value, StrCat(enum_value), generator); + } + break; + } + + case FieldDescriptor::CPPTYPE_MESSAGE: + Print(field->is_repeated() + ? reflection->GetRepeatedMessage(message, field, index) + : reflection->GetMessage(message, field), + generator); + break; + } +} + +/* static */ bool TextFormat::Print(const Message& message, + io::ZeroCopyOutputStream* output) { + return Printer().Print(message, output); +} + +/* static */ bool TextFormat::PrintUnknownFields( + const UnknownFieldSet& unknown_fields, io::ZeroCopyOutputStream* output) { + return Printer().PrintUnknownFields(unknown_fields, output); +} + +/* static */ bool TextFormat::PrintToString(const Message& message, + TProtoStringType* output) { + return Printer().PrintToString(message, output); +} + +/* static */ bool TextFormat::PrintUnknownFieldsToString( + const UnknownFieldSet& unknown_fields, TProtoStringType* output) { + return Printer().PrintUnknownFieldsToString(unknown_fields, output); +} + +/* static */ void TextFormat::PrintFieldValueToString( + const Message& message, const FieldDescriptor* field, int index, + TProtoStringType* output) { + return Printer().PrintFieldValueToString(message, field, index, output); +} + +/* static */ bool TextFormat::ParseFieldValueFromString( + const TProtoStringType& input, const FieldDescriptor* field, Message* message) { + return Parser().ParseFieldValueFromString(input, field, message); +} + +void TextFormat::Printer::PrintUnknownFields( + const UnknownFieldSet& unknown_fields, TextGenerator* generator, + int recursion_budget) const { + for (int i = 0; i < unknown_fields.field_count(); i++) { + const UnknownField& field = unknown_fields.field(i); + TProtoStringType field_number = StrCat(field.number()); + + switch (field.type()) { + case UnknownField::TYPE_VARINT: + generator->PrintString(field_number); + generator->PrintMaybeWithMarker(": "); + generator->PrintString(StrCat(field.varint())); + if (single_line_mode_) { + generator->PrintLiteral(" "); + } else { + generator->PrintLiteral("\n"); + } + break; + case UnknownField::TYPE_FIXED32: { + generator->PrintString(field_number); + generator->PrintMaybeWithMarker(": ", "0x"); + generator->PrintString( + StrCat(strings::Hex(field.fixed32(), strings::ZERO_PAD_8))); + if (single_line_mode_) { + generator->PrintLiteral(" "); + } else { + generator->PrintLiteral("\n"); + } + break; + } + case UnknownField::TYPE_FIXED64: { + generator->PrintString(field_number); + generator->PrintMaybeWithMarker(": ", "0x"); + generator->PrintString( + StrCat(strings::Hex(field.fixed64(), strings::ZERO_PAD_16))); + if (single_line_mode_) { + generator->PrintLiteral(" "); + } else { + generator->PrintLiteral("\n"); + } + break; + } + case UnknownField::TYPE_LENGTH_DELIMITED: { + generator->PrintString(field_number); + const TProtoStringType& value = field.length_delimited(); + // We create a CodedInputStream so that we can adhere to our recursion + // budget when we attempt to parse the data. UnknownFieldSet parsing is + // recursive because of groups. + io::CodedInputStream input_stream( + reinterpret_cast<const uint8_t*>(value.data()), value.size()); + input_stream.SetRecursionLimit(recursion_budget); + UnknownFieldSet embedded_unknown_fields; + if (!value.empty() && recursion_budget > 0 && + embedded_unknown_fields.ParseFromCodedStream(&input_stream)) { + // This field is parseable as a Message. + // So it is probably an embedded message. + if (single_line_mode_) { + generator->PrintMaybeWithMarker(" ", "{ "); + } else { + generator->PrintMaybeWithMarker(" ", "{\n"); + generator->Indent(); + } + PrintUnknownFields(embedded_unknown_fields, generator, + recursion_budget - 1); + if (single_line_mode_) { + generator->PrintLiteral("} "); + } else { + generator->Outdent(); + generator->PrintLiteral("}\n"); + } + } else { + // This field is not parseable as a Message (or we ran out of + // recursion budget). So it is probably just a plain string. + generator->PrintMaybeWithMarker(": ", "\""); + generator->PrintString(CEscape(value)); + if (single_line_mode_) { + generator->PrintLiteral("\" "); + } else { + generator->PrintLiteral("\"\n"); + } + } + break; + } + case UnknownField::TYPE_GROUP: + generator->PrintString(field_number); + if (single_line_mode_) { + generator->PrintMaybeWithMarker(" ", "{ "); + } else { + generator->PrintMaybeWithMarker(" ", "{\n"); + generator->Indent(); + } + // For groups, we recurse without checking the budget. This is OK, + // because if the groups were too deeply nested then we would have + // already rejected the message when we originally parsed it. + PrintUnknownFields(field.group(), generator, recursion_budget - 1); + if (single_line_mode_) { + generator->PrintLiteral("} "); + } else { + generator->Outdent(); + generator->PrintLiteral("}\n"); + } + break; + } + } +} + +} // namespace protobuf +} // namespace google + +#include <google/protobuf/port_undef.inc> diff --git a/contrib/libs/protobuf_old/src/google/protobuf/text_format.h b/contrib/libs/protobuf_old/src/google/protobuf/text_format.h new file mode 100644 index 0000000000..70c49f4ed1 --- /dev/null +++ b/contrib/libs/protobuf_old/src/google/protobuf/text_format.h @@ -0,0 +1,687 @@ +// 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: jschorr@google.com (Joseph Schorr) +// Based on original Protocol Buffers design by +// Sanjay Ghemawat, Jeff Dean, and others. +// +// Utilities for printing and parsing protocol messages in a human-readable, +// text-based format. + +#ifndef GOOGLE_PROTOBUF_TEXT_FORMAT_H__ +#define GOOGLE_PROTOBUF_TEXT_FORMAT_H__ + +#include <map> +#include <memory> +#include <string> +#include <vector> + +#include <google/protobuf/stubs/common.h> +#include <google/protobuf/descriptor.h> +#include <google/protobuf/message.h> +#include <google/protobuf/message_lite.h> +#include <google/protobuf/port.h> + +#include <google/protobuf/port_def.inc> + +#ifdef SWIG +#error "You cannot SWIG proto headers" +#endif + +namespace google { +namespace protobuf { + +namespace io { +class ErrorCollector; // tokenizer.h +} + +// This class implements protocol buffer text format, colloquially known as text +// proto. Printing and parsing protocol messages in text format is useful for +// debugging and human editing of messages. +// +// This class is really a namespace that contains only static methods. +class PROTOBUF_EXPORT TextFormat { + public: + // Outputs a textual representation of the given message to the given + // output stream. Returns false if printing fails. + static bool Print(const Message& message, io::ZeroCopyOutputStream* output); + + // Print the fields in an UnknownFieldSet. They are printed by tag number + // only. Embedded messages are heuristically identified by attempting to + // parse them. Returns false if printing fails. + static bool PrintUnknownFields(const UnknownFieldSet& unknown_fields, + io::ZeroCopyOutputStream* output); + + // Like Print(), but outputs directly to a string. + // Note: output will be cleared prior to printing, and will be left empty + // even if printing fails. Returns false if printing fails. + static bool PrintToString(const Message& message, TProtoStringType* output); + + // Like PrintUnknownFields(), but outputs directly to a string. Returns + // false if printing fails. + static bool PrintUnknownFieldsToString(const UnknownFieldSet& unknown_fields, + TProtoStringType* output); + + // Outputs a textual representation of the value of the field supplied on + // the message supplied. For non-repeated fields, an index of -1 must + // be supplied. Note that this method will print the default value for a + // field if it is not set. + static void PrintFieldValueToString(const Message& message, + const FieldDescriptor* field, int index, + TProtoStringType* output); + + class PROTOBUF_EXPORT BaseTextGenerator { + public: + virtual ~BaseTextGenerator(); + + virtual void Indent() {} + virtual void Outdent() {} + // Returns the current indentation size in characters. + virtual size_t GetCurrentIndentationSize() const { return 0; } + + // Print text to the output stream. + virtual void Print(const char* text, size_t size) = 0; + + void PrintString(const TProtoStringType& str) { Print(str.data(), str.size()); } + + template <size_t n> + void PrintLiteral(const char (&text)[n]) { + Print(text, n - 1); // n includes the terminating zero character. + } + }; + + // The default printer that converts scalar values from fields into their + // string representation. + // You can derive from this FastFieldValuePrinter if you want to have fields + // to be printed in a different way and register it at the Printer. + class PROTOBUF_EXPORT FastFieldValuePrinter { + public: + FastFieldValuePrinter(); + virtual ~FastFieldValuePrinter(); + virtual void PrintBool(bool val, BaseTextGenerator* generator) const; + virtual void PrintInt32(arc_i32 val, BaseTextGenerator* generator) const; + virtual void PrintUInt32(arc_ui32 val, BaseTextGenerator* generator) const; + virtual void PrintInt64(arc_i64 val, BaseTextGenerator* generator) const; + virtual void PrintUInt64(arc_ui64 val, BaseTextGenerator* generator) const; + virtual void PrintFloat(float val, BaseTextGenerator* generator) const; + virtual void PrintDouble(double val, BaseTextGenerator* generator) const; + virtual void PrintString(const TProtoStringType& val, + BaseTextGenerator* generator) const; + virtual void PrintBytes(const TProtoStringType& val, + BaseTextGenerator* generator) const; + virtual void PrintEnum(arc_i32 val, const TProtoStringType& name, + BaseTextGenerator* generator) const; + virtual void PrintFieldName(const Message& message, int field_index, + int field_count, const Reflection* reflection, + const FieldDescriptor* field, + BaseTextGenerator* generator) const; + virtual void PrintFieldName(const Message& message, + const Reflection* reflection, + const FieldDescriptor* field, + BaseTextGenerator* generator) const; + virtual void PrintMessageStart(const Message& message, int field_index, + int field_count, bool single_line_mode, + BaseTextGenerator* generator) const; + // Allows to override the logic on how to print the content of a message. + // Return false to use the default printing logic. Note that it is legal for + // this function to print something and then return false to use the default + // content printing (although at that point it would behave similarly to + // PrintMessageStart). + virtual bool PrintMessageContent(const Message& message, int field_index, + int field_count, bool single_line_mode, + BaseTextGenerator* generator) const; + virtual void PrintMessageEnd(const Message& message, int field_index, + int field_count, bool single_line_mode, + BaseTextGenerator* generator) const; + + private: + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(FastFieldValuePrinter); + }; + + // Deprecated: please use FastFieldValuePrinter instead. + class PROTOBUF_EXPORT FieldValuePrinter { + public: + FieldValuePrinter(); + virtual ~FieldValuePrinter(); + virtual TProtoStringType PrintBool(bool val) const; + virtual TProtoStringType PrintInt32(arc_i32 val) const; + virtual TProtoStringType PrintUInt32(arc_ui32 val) const; + virtual TProtoStringType PrintInt64(arc_i64 val) const; + virtual TProtoStringType PrintUInt64(arc_ui64 val) const; + virtual TProtoStringType PrintFloat(float val) const; + virtual TProtoStringType PrintDouble(double val) const; + virtual TProtoStringType PrintString(const TProtoStringType& val) const; + virtual TProtoStringType PrintBytes(const TProtoStringType& val) const; + virtual TProtoStringType PrintEnum(arc_i32 val, const TProtoStringType& name) const; + virtual TProtoStringType PrintFieldName(const Message& message, + const Reflection* reflection, + const FieldDescriptor* field) const; + virtual TProtoStringType PrintMessageStart(const Message& message, + int field_index, int field_count, + bool single_line_mode) const; + virtual TProtoStringType PrintMessageEnd(const Message& message, int field_index, + int field_count, + bool single_line_mode) const; + + private: + FastFieldValuePrinter delegate_; + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(FieldValuePrinter); + }; + + class PROTOBUF_EXPORT MessagePrinter { + public: + MessagePrinter() {} + virtual ~MessagePrinter() {} + virtual void Print(const Message& message, bool single_line_mode, + BaseTextGenerator* generator) const = 0; + + private: + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(MessagePrinter); + }; + + // Interface that Printers or Parsers can use to find extensions, or types + // referenced in Any messages. + class PROTOBUF_EXPORT Finder { + public: + virtual ~Finder(); + + // Try to find an extension of *message by fully-qualified field + // name. Returns nullptr if no extension is known for this name or number. + // The base implementation uses the extensions already known by the message. + virtual const FieldDescriptor* FindExtension(Message* message, + const TProtoStringType& name) const; + + // Similar to FindExtension, but uses a Descriptor and the extension number + // instead of using a Message and the name when doing the look up. + virtual const FieldDescriptor* FindExtensionByNumber( + const Descriptor* descriptor, int number) const; + + // Find the message type for an Any proto. + // Returns nullptr if no message is known for this name. + // The base implementation only accepts prefixes of type.googleprod.com/ or + // type.googleapis.com/, and searches the DescriptorPool of the parent + // message. + virtual const Descriptor* FindAnyType(const Message& message, + const TProtoStringType& prefix, + const TProtoStringType& name) const; + + // Find the message factory for the given extension field. This can be used + // to generalize the Parser to add extension fields to a message in the same + // way as the "input" message for the Parser. + virtual MessageFactory* FindExtensionFactory( + const FieldDescriptor* field) const; + }; + + // Class for those users which require more fine-grained control over how + // a protobuffer message is printed out. + class PROTOBUF_EXPORT Printer { + public: + Printer(); + + // Like TextFormat::Print + bool Print(const Message& message, io::ZeroCopyOutputStream* output) const; + // Like TextFormat::PrintUnknownFields + bool PrintUnknownFields(const UnknownFieldSet& unknown_fields, + io::ZeroCopyOutputStream* output) const; + // Like TextFormat::PrintToString + bool PrintToString(const Message& message, TProtoStringType* output) const; + // Like TextFormat::PrintUnknownFieldsToString + bool PrintUnknownFieldsToString(const UnknownFieldSet& unknown_fields, + TProtoStringType* output) const; + // Like TextFormat::PrintFieldValueToString + void PrintFieldValueToString(const Message& message, + const FieldDescriptor* field, int index, + TProtoStringType* output) const; + + // Adjust the initial indent level of all output. Each indent level is + // equal to two spaces. + void SetInitialIndentLevel(int indent_level) { + initial_indent_level_ = indent_level; + } + + // If printing in single line mode, then the entire message will be output + // on a single line with no line breaks. + void SetSingleLineMode(bool single_line_mode) { + single_line_mode_ = single_line_mode; + } + + bool IsInSingleLineMode() const { return single_line_mode_; } + + // If use_field_number is true, uses field number instead of field name. + void SetUseFieldNumber(bool use_field_number) { + use_field_number_ = use_field_number; + } + + // Set true to print repeated primitives in a format like: + // field_name: [1, 2, 3, 4] + // instead of printing each value on its own line. Short format applies + // only to primitive values -- i.e. everything except strings and + // sub-messages/groups. + void SetUseShortRepeatedPrimitives(bool use_short_repeated_primitives) { + use_short_repeated_primitives_ = use_short_repeated_primitives; + } + + // Set true to output UTF-8 instead of ASCII. The only difference + // is that bytes >= 0x80 in string fields will not be escaped, + // because they are assumed to be part of UTF-8 multi-byte + // sequences. This will change the default FastFieldValuePrinter. + void SetUseUtf8StringEscaping(bool as_utf8); + + // Set the default FastFieldValuePrinter that is used for all fields that + // don't have a field-specific printer registered. + // Takes ownership of the printer. + void SetDefaultFieldValuePrinter(const FastFieldValuePrinter* printer); + + PROTOBUF_DEPRECATED_MSG("Please use FastFieldValuePrinter") + void SetDefaultFieldValuePrinter(const FieldValuePrinter* printer); + + // Sets whether we want to hide unknown fields or not. + // Usually unknown fields are printed in a generic way that includes the + // tag number of the field instead of field name. However, sometimes it + // is useful to be able to print the message without unknown fields (e.g. + // for the python protobuf version to maintain consistency between its pure + // python and c++ implementations). + void SetHideUnknownFields(bool hide) { hide_unknown_fields_ = hide; } + + // If print_message_fields_in_index_order is true, fields of a proto message + // will be printed using the order defined in source code instead of the + // field number, extensions will be printed at the end of the message + // and their relative order is determined by the extension number. + // By default, use the field number order. + void SetPrintMessageFieldsInIndexOrder( + bool print_message_fields_in_index_order) { + print_message_fields_in_index_order_ = + print_message_fields_in_index_order; + } + + // If expand==true, expand google.protobuf.Any payloads. The output + // will be of form + // [type_url] { <value_printed_in_text> } + // + // If expand==false, print Any using the default printer. The output will + // look like + // type_url: "<type_url>" value: "serialized_content" + void SetExpandAny(bool expand) { expand_any_ = expand; } + + // Set how parser finds message for Any payloads. + void SetFinder(const Finder* finder) { finder_ = finder; } + + // If non-zero, we truncate all string fields that are longer than + // this threshold. This is useful when the proto message has very long + // strings, e.g., dump of encoded image file. + // + // NOTE(hfgong): Setting a non-zero value breaks round-trip safe + // property of TextFormat::Printer. That is, from the printed message, we + // cannot fully recover the original string field any more. + void SetTruncateStringFieldLongerThan( + const arc_i64 truncate_string_field_longer_than) { + truncate_string_field_longer_than_ = truncate_string_field_longer_than; + } + + // Register a custom field-specific FastFieldValuePrinter for fields + // with a particular FieldDescriptor. + // Returns "true" if the registration succeeded, or "false", if there is + // already a printer for that FieldDescriptor. + // Takes ownership of the printer on successful registration. + bool RegisterFieldValuePrinter(const FieldDescriptor* field, + const FastFieldValuePrinter* printer); + + PROTOBUF_DEPRECATED_MSG("Please use FastFieldValuePrinter") + bool RegisterFieldValuePrinter(const FieldDescriptor* field, + const FieldValuePrinter* printer); + + // Register a custom message-specific MessagePrinter for messages with a + // particular Descriptor. + // Returns "true" if the registration succeeded, or "false" if there is + // already a printer for that Descriptor. + bool RegisterMessagePrinter(const Descriptor* descriptor, + const MessagePrinter* printer); + + private: + friend TProtoStringType Message::DebugString() const; + friend TProtoStringType Message::ShortDebugString() const; + friend TProtoStringType Message::Utf8DebugString() const; + + // Sets whether *DebugString should insert a silent marker. + void SetInsertSilentMarker(bool v) { insert_silent_marker_ = v; } + + // Forward declaration of an internal class used to print the text + // output to the OutputStream (see text_format.cc for implementation). + class TextGenerator; + + // Forward declaration of an internal class used to print field values for + // DebugString APIs (see text_format.cc for implementation). + class DebugStringFieldValuePrinter; + + // Forward declaration of an internal class used to print UTF-8 escaped + // strings (see text_format.cc for implementation). + class FastFieldValuePrinterUtf8Escaping; + + static const char* const kDoNotParse; + + // Internal Print method, used for writing to the OutputStream via + // the TextGenerator class. + void Print(const Message& message, TextGenerator* generator) const; + + // Print a single field. + void PrintField(const Message& message, const Reflection* reflection, + const FieldDescriptor* field, + TextGenerator* generator) const; + + // Print a repeated primitive field in short form. + void PrintShortRepeatedField(const Message& message, + const Reflection* reflection, + const FieldDescriptor* field, + TextGenerator* generator) const; + + // Print the name of a field -- i.e. everything that comes before the + // ':' for a single name/value pair. + void PrintFieldName(const Message& message, int field_index, + int field_count, const Reflection* reflection, + const FieldDescriptor* field, + TextGenerator* generator) const; + + // Outputs a textual representation of the value of the field supplied on + // the message supplied or the default value if not set. + void PrintFieldValue(const Message& message, const Reflection* reflection, + const FieldDescriptor* field, int index, + TextGenerator* generator) const; + + // Print the fields in an UnknownFieldSet. They are printed by tag number + // only. Embedded messages are heuristically identified by attempting to + // parse them (subject to the recursion budget). + void PrintUnknownFields(const UnknownFieldSet& unknown_fields, + TextGenerator* generator, + int recursion_budget) const; + + bool PrintAny(const Message& message, TextGenerator* generator) const; + + const FastFieldValuePrinter* GetFieldPrinter( + const FieldDescriptor* field) const { + auto it = custom_printers_.find(field); + return it == custom_printers_.end() ? default_field_value_printer_.get() + : it->second.get(); + } + + int initial_indent_level_; + bool single_line_mode_; + bool use_field_number_; + bool use_short_repeated_primitives_; + bool insert_silent_marker_; + bool hide_unknown_fields_; + bool print_message_fields_in_index_order_; + bool expand_any_; + arc_i64 truncate_string_field_longer_than_; + + std::unique_ptr<const FastFieldValuePrinter> default_field_value_printer_; + typedef std::map<const FieldDescriptor*, + std::unique_ptr<const FastFieldValuePrinter>> + CustomPrinterMap; + CustomPrinterMap custom_printers_; + + typedef std::map<const Descriptor*, std::unique_ptr<const MessagePrinter>> + CustomMessagePrinterMap; + CustomMessagePrinterMap custom_message_printers_; + + const Finder* finder_; + }; + + // Parses a text-format protocol message from the given input stream to + // the given message object. This function parses the human-readable format + // written by Print(). Returns true on success. The message is cleared first, + // even if the function fails -- See Merge() to avoid this behavior. + // + // Example input: "user {\n id: 123 extra { gender: MALE language: 'en' }\n}" + // + // One use for this function is parsing handwritten strings in test code. + // Another use is to parse the output from google::protobuf::Message::DebugString() + // (or ShortDebugString()), because these functions output using + // google::protobuf::TextFormat::Print(). + // + // If you would like to read a protocol buffer serialized in the + // (non-human-readable) binary wire format, see + // google::protobuf::MessageLite::ParseFromString(). + static bool Parse(io::ZeroCopyInputStream* input, Message* output); + // Like Parse(), but reads directly from a string. + static bool ParseFromString(ConstStringParam input, Message* output); + + // Like Parse(), but the data is merged into the given message, as if + // using Message::MergeFrom(). + static bool Merge(io::ZeroCopyInputStream* input, Message* output); + // Like Merge(), but reads directly from a string. + static bool MergeFromString(ConstStringParam input, Message* output); + + // Parse the given text as a single field value and store it into the + // given field of the given message. If the field is a repeated field, + // the new value will be added to the end + static bool ParseFieldValueFromString(const TProtoStringType& input, + const FieldDescriptor* field, + Message* message); + + // A location in the parsed text. + struct ParseLocation { + int line; + int column; + + ParseLocation() : line(-1), column(-1) {} + ParseLocation(int line_param, int column_param) + : line(line_param), column(column_param) {} + }; + + // A range of locations in the parsed text, including `start` and excluding + // `end`. + struct ParseLocationRange { + ParseLocation start; + ParseLocation end; + ParseLocationRange() : start(), end() {} + ParseLocationRange(ParseLocation start_param, ParseLocation end_param) + : start(start_param), end(end_param) {} + }; + + // Data structure which is populated with the locations of each field + // value parsed from the text. + class PROTOBUF_EXPORT ParseInfoTree { + public: + ParseInfoTree() = default; + ParseInfoTree(const ParseInfoTree&) = delete; + ParseInfoTree& operator=(const ParseInfoTree&) = delete; + + // Returns the parse location range for index-th value of the field in + // the parsed text. If none exists, returns a location with start and end + // line -1. Index should be -1 for not-repeated fields. + ParseLocationRange GetLocationRange(const FieldDescriptor* field, + int index) const; + + // Returns the starting parse location for index-th value of the field in + // the parsed text. If none exists, returns a location with line = -1. Index + // should be -1 for not-repeated fields. + ParseLocation GetLocation(const FieldDescriptor* field, int index) const { + return GetLocationRange(field, index).start; + } + + // Returns the parse info tree for the given field, which must be a message + // type. The nested information tree is owned by the root tree and will be + // deleted when it is deleted. + ParseInfoTree* GetTreeForNested(const FieldDescriptor* field, + int index) const; + + private: + // Allow the text format parser to record information into the tree. + friend class TextFormat; + + // Records the starting and ending locations of a single value for a field. + void RecordLocation(const FieldDescriptor* field, ParseLocationRange range); + + // Create and records a nested tree for a nested message field. + ParseInfoTree* CreateNested(const FieldDescriptor* field); + + // Defines the map from the index-th field descriptor to its parse location. + typedef std::map<const FieldDescriptor*, std::vector<ParseLocationRange>> + LocationMap; + + // Defines the map from the index-th field descriptor to the nested parse + // info tree. + typedef std::map<const FieldDescriptor*, + std::vector<std::unique_ptr<ParseInfoTree>>> + NestedMap; + + LocationMap locations_; + NestedMap nested_; + }; + + // For more control over parsing, use this class. + class PROTOBUF_EXPORT Parser { + public: + Parser(); + ~Parser(); + + // Like TextFormat::Parse(). + bool Parse(io::ZeroCopyInputStream* input, Message* output); + // Like TextFormat::ParseFromString(). + bool ParseFromString(ConstStringParam input, Message* output); + // Like TextFormat::Merge(). + bool Merge(io::ZeroCopyInputStream* input, Message* output); + // Like TextFormat::MergeFromString(). + bool MergeFromString(ConstStringParam input, Message* output); + + // Set where to report parse errors. If nullptr (the default), errors will + // be printed to stderr. + void RecordErrorsTo(io::ErrorCollector* error_collector) { + error_collector_ = error_collector; + } + + // Set how parser finds extensions. If nullptr (the default), the + // parser will use the standard Reflection object associated with + // the message being parsed. + void SetFinder(const Finder* finder) { finder_ = finder; } + + // Sets where location information about the parse will be written. If + // nullptr + // (the default), then no location will be written. + void WriteLocationsTo(ParseInfoTree* tree) { parse_info_tree_ = tree; } + + // Normally parsing fails if, after parsing, output->IsInitialized() + // returns false. Call AllowPartialMessage(true) to skip this check. + void AllowPartialMessage(bool allow) { allow_partial_ = allow; } + + // Allow field names to be matched case-insensitively. + // This is not advisable if there are fields that only differ in case, or + // if you want to enforce writing in the canonical form. + // This is 'false' by default. + void AllowCaseInsensitiveField(bool allow) { + allow_case_insensitive_field_ = allow; + } + + // Like TextFormat::ParseFieldValueFromString + bool ParseFieldValueFromString(const TProtoStringType& input, + const FieldDescriptor* field, + Message* output); + + // When an unknown extension is met, parsing will fail if this option is + // set to false (the default). If true, unknown extensions will be ignored + // and a warning message will be generated. + // Beware! Setting this option true may hide some errors (e.g. spelling + // error on extension name). This allows data loss; unlike binary format, + // text format cannot preserve unknown extensions. Avoid using this option + // if possible. + void AllowUnknownExtension(bool allow) { allow_unknown_extension_ = allow; } + + // When an unknown field is met, parsing will fail if this option is set + // to false (the default). If true, unknown fields will be ignored and + // a warning message will be generated. + // Beware! Setting this option true may hide some errors (e.g. spelling + // error on field name). This allows data loss; unlike binary format, text + // format cannot preserve unknown fields. Avoid using this option + // if possible. + void AllowUnknownField(bool allow) { allow_unknown_field_ = allow; } + + + void AllowFieldNumber(bool allow) { allow_field_number_ = allow; } + + // Sets maximum recursion depth which parser can use. This is effectively + // the maximum allowed nesting of proto messages. + void SetRecursionLimit(int limit) { recursion_limit_ = limit; } + + private: + // Forward declaration of an internal class used to parse text + // representations (see text_format.cc for implementation). + class ParserImpl; + + // Like TextFormat::Merge(). The provided implementation is used + // to do the parsing. + bool MergeUsingImpl(io::ZeroCopyInputStream* input, Message* output, + ParserImpl* parser_impl); + + io::ErrorCollector* error_collector_; + const Finder* finder_; + ParseInfoTree* parse_info_tree_; + bool allow_partial_; + bool allow_case_insensitive_field_; + bool allow_unknown_field_; + bool allow_unknown_extension_; + bool allow_unknown_enum_; + bool allow_field_number_; + bool allow_relaxed_whitespace_; + bool allow_singular_overwrites_; + int recursion_limit_; + }; + + + private: + // Hack: ParseInfoTree declares TextFormat as a friend which should extend + // the friendship to TextFormat::Parser::ParserImpl, but unfortunately some + // old compilers (e.g. GCC 3.4.6) don't implement this correctly. We provide + // helpers for ParserImpl to call methods of ParseInfoTree. + static inline void RecordLocation(ParseInfoTree* info_tree, + const FieldDescriptor* field, + ParseLocationRange location); + static inline ParseInfoTree* CreateNested(ParseInfoTree* info_tree, + const FieldDescriptor* field); + + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(TextFormat); +}; + +inline void TextFormat::RecordLocation(ParseInfoTree* info_tree, + const FieldDescriptor* field, + ParseLocationRange location) { + info_tree->RecordLocation(field, location); +} + +inline TextFormat::ParseInfoTree* TextFormat::CreateNested( + ParseInfoTree* info_tree, const FieldDescriptor* field) { + return info_tree->CreateNested(field); +} + +} // namespace protobuf +} // namespace google + +#include <google/protobuf/port_undef.inc> + +#endif // GOOGLE_PROTOBUF_TEXT_FORMAT_H__ diff --git a/contrib/libs/protobuf_old/src/google/protobuf/timestamp.pb.cc b/contrib/libs/protobuf_old/src/google/protobuf/timestamp.pb.cc new file mode 100644 index 0000000000..6f39fd988f --- /dev/null +++ b/contrib/libs/protobuf_old/src/google/protobuf/timestamp.pb.cc @@ -0,0 +1,300 @@ +// Generated by the protocol buffer compiler. DO NOT EDIT! +// source: google/protobuf/timestamp.proto + +#include <google/protobuf/timestamp.pb.h> + +#include <algorithm> + +#include <google/protobuf/io/coded_stream.h> +#include <google/protobuf/extension_set.h> +#include <google/protobuf/wire_format_lite.h> +#include <google/protobuf/descriptor.h> +#include <google/protobuf/generated_message_reflection.h> +#include <google/protobuf/reflection_ops.h> +#include <google/protobuf/wire_format.h> +// @@protoc_insertion_point(includes) +#include <google/protobuf/port_def.inc> + +PROTOBUF_PRAGMA_INIT_SEG +PROTOBUF_NAMESPACE_OPEN +constexpr Timestamp::Timestamp( + ::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized) + : seconds_(arc_i64{0}) + , nanos_(0){} +struct TimestampDefaultTypeInternal { + constexpr TimestampDefaultTypeInternal() + : _instance(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized{}) {} + ~TimestampDefaultTypeInternal() {} + union { + Timestamp _instance; + }; +}; +PROTOBUF_ATTRIBUTE_NO_DESTROY PROTOBUF_CONSTINIT TimestampDefaultTypeInternal _Timestamp_default_instance_; +PROTOBUF_NAMESPACE_CLOSE +static ::PROTOBUF_NAMESPACE_ID::Metadata file_level_metadata_google_2fprotobuf_2ftimestamp_2eproto[1]; +static constexpr ::PROTOBUF_NAMESPACE_ID::EnumDescriptor const** file_level_enum_descriptors_google_2fprotobuf_2ftimestamp_2eproto = nullptr; +static constexpr ::PROTOBUF_NAMESPACE_ID::ServiceDescriptor const** file_level_service_descriptors_google_2fprotobuf_2ftimestamp_2eproto = nullptr; + +const arc_ui32 TableStruct_google_2fprotobuf_2ftimestamp_2eproto::offsets[] PROTOBUF_SECTION_VARIABLE(protodesc_cold) = { + ~0u, // no _has_bits_ + PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::Timestamp, _internal_metadata_), + ~0u, // no _extensions_ + ~0u, // no _oneof_case_ + ~0u, // no _weak_field_map_ + ~0u, // no _inlined_string_donated_ + PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::Timestamp, seconds_), + PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::Timestamp, nanos_), +}; +static const ::PROTOBUF_NAMESPACE_ID::internal::MigrationSchema schemas[] PROTOBUF_SECTION_VARIABLE(protodesc_cold) = { + { 0, -1, -1, sizeof(::PROTOBUF_NAMESPACE_ID::Timestamp)}, +}; + +static ::PROTOBUF_NAMESPACE_ID::Message const * const file_default_instances[] = { + reinterpret_cast<const ::PROTOBUF_NAMESPACE_ID::Message*>(&::PROTOBUF_NAMESPACE_ID::_Timestamp_default_instance_), +}; + +const char descriptor_table_protodef_google_2fprotobuf_2ftimestamp_2eproto[] PROTOBUF_SECTION_VARIABLE(protodesc_cold) = + "\n\037google/protobuf/timestamp.proto\022\017googl" + "e.protobuf\"+\n\tTimestamp\022\017\n\007seconds\030\001 \001(\003" + "\022\r\n\005nanos\030\002 \001(\005B\205\001\n\023com.google.protobufB" + "\016TimestampProtoP\001Z2google.golang.org/pro" + "tobuf/types/known/timestamppb\370\001\001\242\002\003GPB\252\002" + "\036Google.Protobuf.WellKnownTypesb\006proto3" + ; +static ::PROTOBUF_NAMESPACE_ID::internal::once_flag descriptor_table_google_2fprotobuf_2ftimestamp_2eproto_once; +const ::PROTOBUF_NAMESPACE_ID::internal::DescriptorTable descriptor_table_google_2fprotobuf_2ftimestamp_2eproto = { + false, false, 239, descriptor_table_protodef_google_2fprotobuf_2ftimestamp_2eproto, "google/protobuf/timestamp.proto", + &descriptor_table_google_2fprotobuf_2ftimestamp_2eproto_once, nullptr, 0, 1, + schemas, file_default_instances, TableStruct_google_2fprotobuf_2ftimestamp_2eproto::offsets, + file_level_metadata_google_2fprotobuf_2ftimestamp_2eproto, file_level_enum_descriptors_google_2fprotobuf_2ftimestamp_2eproto, file_level_service_descriptors_google_2fprotobuf_2ftimestamp_2eproto, +}; +PROTOBUF_ATTRIBUTE_WEAK const ::PROTOBUF_NAMESPACE_ID::internal::DescriptorTable* descriptor_table_google_2fprotobuf_2ftimestamp_2eproto_getter() { + return &descriptor_table_google_2fprotobuf_2ftimestamp_2eproto; +} + +// Force running AddDescriptors() at dynamic initialization time. +PROTOBUF_ATTRIBUTE_INIT_PRIORITY static ::PROTOBUF_NAMESPACE_ID::internal::AddDescriptorsRunner dynamic_init_dummy_google_2fprotobuf_2ftimestamp_2eproto(&descriptor_table_google_2fprotobuf_2ftimestamp_2eproto); +PROTOBUF_NAMESPACE_OPEN + +// =================================================================== + +class Timestamp::_Internal { + public: +}; + +Timestamp::Timestamp(::PROTOBUF_NAMESPACE_ID::Arena* arena, + bool is_message_owned) + : ::PROTOBUF_NAMESPACE_ID::Message(arena, is_message_owned) { + SharedCtor(); + if (!is_message_owned) { + RegisterArenaDtor(arena); + } + // @@protoc_insertion_point(arena_constructor:google.protobuf.Timestamp) +} +Timestamp::Timestamp(const Timestamp& from) + : ::PROTOBUF_NAMESPACE_ID::Message() { + _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_); + ::memcpy(&seconds_, &from.seconds_, + static_cast<size_t>(reinterpret_cast<char*>(&nanos_) - + reinterpret_cast<char*>(&seconds_)) + sizeof(nanos_)); + // @@protoc_insertion_point(copy_constructor:google.protobuf.Timestamp) +} + +inline void Timestamp::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_) - + reinterpret_cast<char*>(&seconds_)) + sizeof(nanos_)); +} + +Timestamp::~Timestamp() { + // @@protoc_insertion_point(destructor:google.protobuf.Timestamp) + if (GetArenaForAllocation() != nullptr) return; + SharedDtor(); + _internal_metadata_.Delete<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(); +} + +inline void Timestamp::SharedDtor() { + GOOGLE_DCHECK(GetArenaForAllocation() == nullptr); +} + +void Timestamp::ArenaDtor(void* object) { + Timestamp* _this = reinterpret_cast< Timestamp* >(object); + (void)_this; +} +void Timestamp::RegisterArenaDtor(::PROTOBUF_NAMESPACE_ID::Arena*) { +} +void Timestamp::SetCachedSize(int size) const { + _cached_size_.Set(size); +} + +void Timestamp::Clear() { +// @@protoc_insertion_point(message_clear_start:google.protobuf.Timestamp) + arc_ui32 cached_has_bits = 0; + // Prevent compiler warnings about cached_has_bits being unused + (void) cached_has_bits; + + ::memset(&seconds_, 0, static_cast<size_t>( + reinterpret_cast<char*>(&nanos_) - + reinterpret_cast<char*>(&seconds_)) + sizeof(nanos_)); + _internal_metadata_.Clear<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(); +} + +const char* Timestamp::_InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) { +#define CHK_(x) if (PROTOBUF_PREDICT_FALSE(!(x))) goto failure + while (!ctx->Done(&ptr)) { + arc_ui32 tag; + ptr = ::PROTOBUF_NAMESPACE_ID::internal::ReadTag(ptr, &tag); + switch (tag >> 3) { + // int64 seconds = 1; + case 1: + if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 8)) { + seconds_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint64(&ptr); + CHK_(ptr); + } else + goto handle_unusual; + continue; + // int32 nanos = 2; + case 2: + if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 16)) { + nanos_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint32(&ptr); + CHK_(ptr); + } else + goto handle_unusual; + continue; + default: + goto handle_unusual; + } // switch + handle_unusual: + if ((tag == 0) || ((tag & 7) == 4)) { + CHK_(ptr); + ctx->SetLastTag(tag); + goto message_done; + } + ptr = UnknownFieldParse( + tag, + _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(), + ptr, ctx); + CHK_(ptr != nullptr); + } // while +message_done: + return ptr; +failure: + ptr = nullptr; + goto message_done; +#undef CHK_ +} + +uint8_t* Timestamp::_InternalSerialize( + uint8_t* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const { + // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.Timestamp) + arc_ui32 cached_has_bits = 0; + (void) cached_has_bits; + + // int64 seconds = 1; + if (this->_internal_seconds() != 0) { + target = stream->EnsureSpace(target); + target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteInt64ToArray(1, this->_internal_seconds(), target); + } + + // int32 nanos = 2; + if (this->_internal_nanos() != 0) { + target = stream->EnsureSpace(target); + target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteInt32ToArray(2, this->_internal_nanos(), target); + } + + if (PROTOBUF_PREDICT_FALSE(_internal_metadata_.have_unknown_fields())) { + target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::InternalSerializeUnknownFieldsToArray( + _internal_metadata_.unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(::PROTOBUF_NAMESPACE_ID::UnknownFieldSet::default_instance), target, stream); + } + // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.Timestamp) + return target; +} + +size_t Timestamp::ByteSizeLong() const { +// @@protoc_insertion_point(message_byte_size_start:google.protobuf.Timestamp) + size_t total_size = 0; + + arc_ui32 cached_has_bits = 0; + // Prevent compiler warnings about cached_has_bits being unused + (void) cached_has_bits; + + // int64 seconds = 1; + if (this->_internal_seconds() != 0) { + total_size += ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::Int64SizePlusOne(this->_internal_seconds()); + } + + // int32 nanos = 2; + if (this->_internal_nanos() != 0) { + total_size += ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::Int32SizePlusOne(this->_internal_nanos()); + } + + return MaybeComputeUnknownFieldsSize(total_size, &_cached_size_); +} + +const ::PROTOBUF_NAMESPACE_ID::Message::ClassData Timestamp::_class_data_ = { + ::PROTOBUF_NAMESPACE_ID::Message::CopyWithSizeCheck, + Timestamp::MergeImpl +}; +const ::PROTOBUF_NAMESPACE_ID::Message::ClassData*Timestamp::GetClassData() const { return &_class_data_; } + +void Timestamp::MergeImpl(::PROTOBUF_NAMESPACE_ID::Message* to, + const ::PROTOBUF_NAMESPACE_ID::Message& from) { + static_cast<Timestamp *>(to)->MergeFrom( + static_cast<const Timestamp &>(from)); +} + + +void Timestamp::MergeFrom(const Timestamp& from) { +// @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.Timestamp) + GOOGLE_DCHECK_NE(&from, this); + arc_ui32 cached_has_bits = 0; + (void) cached_has_bits; + + if (from._internal_seconds() != 0) { + _internal_set_seconds(from._internal_seconds()); + } + if (from._internal_nanos() != 0) { + _internal_set_nanos(from._internal_nanos()); + } + _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_); +} + +void Timestamp::CopyFrom(const Timestamp& from) { +// @@protoc_insertion_point(class_specific_copy_from_start:google.protobuf.Timestamp) + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool Timestamp::IsInitialized() const { + return true; +} + +void Timestamp::InternalSwap(Timestamp* other) { + using std::swap; + _internal_metadata_.InternalSwap(&other->_internal_metadata_); + ::PROTOBUF_NAMESPACE_ID::internal::memswap< + PROTOBUF_FIELD_OFFSET(Timestamp, nanos_) + + sizeof(Timestamp::nanos_) + - PROTOBUF_FIELD_OFFSET(Timestamp, seconds_)>( + reinterpret_cast<char*>(&seconds_), + reinterpret_cast<char*>(&other->seconds_)); +} + +::PROTOBUF_NAMESPACE_ID::Metadata Timestamp::GetMetadata() const { + return ::PROTOBUF_NAMESPACE_ID::internal::AssignDescriptors( + &descriptor_table_google_2fprotobuf_2ftimestamp_2eproto_getter, &descriptor_table_google_2fprotobuf_2ftimestamp_2eproto_once, + file_level_metadata_google_2fprotobuf_2ftimestamp_2eproto[0]); +} + +// @@protoc_insertion_point(namespace_scope) +PROTOBUF_NAMESPACE_CLOSE +PROTOBUF_NAMESPACE_OPEN +template<> PROTOBUF_NOINLINE ::PROTOBUF_NAMESPACE_ID::Timestamp* Arena::CreateMaybeMessage< ::PROTOBUF_NAMESPACE_ID::Timestamp >(Arena* arena) { + return Arena::CreateMessageInternal< ::PROTOBUF_NAMESPACE_ID::Timestamp >(arena); +} +PROTOBUF_NAMESPACE_CLOSE + +// @@protoc_insertion_point(global_scope) +#include <google/protobuf/port_undef.inc> diff --git a/contrib/libs/protobuf_old/src/google/protobuf/timestamp.pb.h b/contrib/libs/protobuf_old/src/google/protobuf/timestamp.pb.h new file mode 100644 index 0000000000..744cd9a2af --- /dev/null +++ b/contrib/libs/protobuf_old/src/google/protobuf/timestamp.pb.h @@ -0,0 +1,285 @@ +// Generated by the protocol buffer compiler. DO NOT EDIT! +// source: google/protobuf/timestamp.proto + +#ifndef GOOGLE_PROTOBUF_INCLUDED_google_2fprotobuf_2ftimestamp_2eproto +#define GOOGLE_PROTOBUF_INCLUDED_google_2fprotobuf_2ftimestamp_2eproto + +#include <limits> +#include <string> + +#include <google/protobuf/port_def.inc> +#if PROTOBUF_VERSION < 3019000 +#error This file was generated by a newer version of protoc which is +#error incompatible with your Protocol Buffer headers. Please update +#error your headers. +#endif +#if 3019000 < PROTOBUF_MIN_PROTOC_VERSION +#error This file was generated by an older version of protoc which is +#error incompatible with your Protocol Buffer headers. Please +#error regenerate this file with a newer version of protoc. +#endif + +#include <google/protobuf/port_undef.inc> +#include <google/protobuf/io/coded_stream.h> +#include <google/protobuf/arena.h> +#include <google/protobuf/arenastring.h> +#include <google/protobuf/generated_message_table_driven.h> +#include <google/protobuf/generated_message_util.h> +#include <google/protobuf/metadata_lite.h> +#include <google/protobuf/generated_message_reflection.h> +#include <google/protobuf/message.h> +#include <google/protobuf/repeated_field.h> // IWYU pragma: export +#include <google/protobuf/extension_set.h> // IWYU pragma: export +#include <google/protobuf/unknown_field_set.h> +// @@protoc_insertion_point(includes) +#include <google/protobuf/port_def.inc> +#define PROTOBUF_INTERNAL_EXPORT_google_2fprotobuf_2ftimestamp_2eproto PROTOBUF_EXPORT +PROTOBUF_NAMESPACE_OPEN +namespace internal { +class AnyMetadata; +} // namespace internal +PROTOBUF_NAMESPACE_CLOSE + +// Internal implementation detail -- do not use these members. +struct PROTOBUF_EXPORT TableStruct_google_2fprotobuf_2ftimestamp_2eproto { + static const ::PROTOBUF_NAMESPACE_ID::internal::ParseTableField entries[] + PROTOBUF_SECTION_VARIABLE(protodesc_cold); + static const ::PROTOBUF_NAMESPACE_ID::internal::AuxiliaryParseTableField aux[] + PROTOBUF_SECTION_VARIABLE(protodesc_cold); + static const ::PROTOBUF_NAMESPACE_ID::internal::ParseTable schema[1] + PROTOBUF_SECTION_VARIABLE(protodesc_cold); + static const ::PROTOBUF_NAMESPACE_ID::internal::FieldMetadata field_metadata[]; + static const ::PROTOBUF_NAMESPACE_ID::internal::SerializationTable serialization_table[]; + static const arc_ui32 offsets[]; +}; +PROTOBUF_EXPORT extern const ::PROTOBUF_NAMESPACE_ID::internal::DescriptorTable descriptor_table_google_2fprotobuf_2ftimestamp_2eproto; +PROTOBUF_NAMESPACE_OPEN +class Timestamp; +struct TimestampDefaultTypeInternal; +PROTOBUF_EXPORT extern TimestampDefaultTypeInternal _Timestamp_default_instance_; +PROTOBUF_NAMESPACE_CLOSE +PROTOBUF_NAMESPACE_OPEN +template<> PROTOBUF_EXPORT ::PROTOBUF_NAMESPACE_ID::Timestamp* Arena::CreateMaybeMessage<::PROTOBUF_NAMESPACE_ID::Timestamp>(Arena*); +PROTOBUF_NAMESPACE_CLOSE +PROTOBUF_NAMESPACE_OPEN + +// =================================================================== + +class PROTOBUF_EXPORT Timestamp final : + public ::PROTOBUF_NAMESPACE_ID::Message /* @@protoc_insertion_point(class_definition:google.protobuf.Timestamp) */ { + public: + inline Timestamp() : Timestamp(nullptr) {} + ~Timestamp() override; + explicit constexpr Timestamp(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized); + + Timestamp(const Timestamp& from); + Timestamp(Timestamp&& from) noexcept + : Timestamp() { + *this = ::std::move(from); + } + + inline Timestamp& operator=(const Timestamp& from) { + CopyFrom(from); + return *this; + } + inline Timestamp& operator=(Timestamp&& from) noexcept { + if (this == &from) return *this; + if (GetOwningArena() == from.GetOwningArena() + #ifdef PROTOBUF_FORCE_COPY_IN_MOVE + && GetOwningArena() != nullptr + #endif // !PROTOBUF_FORCE_COPY_IN_MOVE + ) { + InternalSwap(&from); + } else { + CopyFrom(from); + } + return *this; + } + + static const ::PROTOBUF_NAMESPACE_ID::Descriptor* descriptor() { + return GetDescriptor(); + } + static const ::PROTOBUF_NAMESPACE_ID::Descriptor* GetDescriptor() { + return default_instance().GetMetadata().descriptor; + } + static const ::PROTOBUF_NAMESPACE_ID::Reflection* GetReflection() { + return default_instance().GetMetadata().reflection; + } + static const Timestamp& default_instance() { + return *internal_default_instance(); + } + static inline const Timestamp* internal_default_instance() { + return reinterpret_cast<const Timestamp*>( + &_Timestamp_default_instance_); + } + static constexpr int kIndexInFileMessages = + 0; + + friend void swap(Timestamp& a, Timestamp& b) { + a.Swap(&b); + } + inline void Swap(Timestamp* other) { + if (other == this) return; + #ifdef PROTOBUF_FORCE_COPY_IN_SWAP + if (GetOwningArena() != nullptr && + GetOwningArena() == other->GetOwningArena()) { + #else // PROTOBUF_FORCE_COPY_IN_SWAP + if (GetOwningArena() == other->GetOwningArena()) { + #endif // !PROTOBUF_FORCE_COPY_IN_SWAP + InternalSwap(other); + } else { + ::PROTOBUF_NAMESPACE_ID::internal::GenericSwap(this, other); + } + } + void UnsafeArenaSwap(Timestamp* other) { + if (other == this) return; + GOOGLE_DCHECK(GetOwningArena() == other->GetOwningArena()); + InternalSwap(other); + } + + // implements Message ---------------------------------------------- + + Timestamp* New(::PROTOBUF_NAMESPACE_ID::Arena* arena = nullptr) const final { + return CreateMaybeMessage<Timestamp>(arena); + } + using ::PROTOBUF_NAMESPACE_ID::Message::CopyFrom; + void CopyFrom(const Timestamp& from); + using ::PROTOBUF_NAMESPACE_ID::Message::MergeFrom; + void MergeFrom(const Timestamp& 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; + + size_t ByteSizeLong() const final; + const char* _InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) final; + uint8_t* _InternalSerialize( + uint8_t* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const final; + int GetCachedSize() const final { return _cached_size_.Get(); } + + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const final; + void InternalSwap(Timestamp* other); + + private: + friend class ::PROTOBUF_NAMESPACE_ID::internal::AnyMetadata; + static ::PROTOBUF_NAMESPACE_ID::StringPiece FullMessageName() { + return "google.protobuf.Timestamp"; + } + protected: + explicit Timestamp(::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 ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + enum : int { + kSecondsFieldNumber = 1, + kNanosFieldNumber = 2, + }; + // int64 seconds = 1; + void clear_seconds(); + arc_i64 seconds() const; + void set_seconds(arc_i64 value); + private: + arc_i64 _internal_seconds() const; + void _internal_set_seconds(arc_i64 value); + public: + + // int32 nanos = 2; + void clear_nanos(); + arc_i32 nanos() const; + void set_nanos(arc_i32 value); + private: + arc_i32 _internal_nanos() const; + void _internal_set_nanos(arc_i32 value); + public: + + // @@protoc_insertion_point(class_scope:google.protobuf.Timestamp) + private: + class _Internal; + + template <typename T> friend class ::PROTOBUF_NAMESPACE_ID::Arena::InternalHelper; + typedef void InternalArenaConstructable_; + typedef void DestructorSkippable_; + arc_i64 seconds_; + arc_i32 nanos_; + mutable ::PROTOBUF_NAMESPACE_ID::internal::CachedSize _cached_size_; + friend struct ::TableStruct_google_2fprotobuf_2ftimestamp_2eproto; +}; +// =================================================================== + + +// =================================================================== + +#ifdef __GNUC__ + #pragma GCC diagnostic push + #pragma GCC diagnostic ignored "-Wstrict-aliasing" +#endif // __GNUC__ +// Timestamp + +// int64 seconds = 1; +inline void Timestamp::clear_seconds() { + seconds_ = arc_i64{0}; +} +inline arc_i64 Timestamp::_internal_seconds() const { + return seconds_; +} +inline arc_i64 Timestamp::seconds() const { + // @@protoc_insertion_point(field_get:google.protobuf.Timestamp.seconds) + return _internal_seconds(); +} +inline void Timestamp::_internal_set_seconds(arc_i64 value) { + + seconds_ = value; +} +inline void Timestamp::set_seconds(arc_i64 value) { + _internal_set_seconds(value); + // @@protoc_insertion_point(field_set:google.protobuf.Timestamp.seconds) +} + +// int32 nanos = 2; +inline void Timestamp::clear_nanos() { + nanos_ = 0; +} +inline arc_i32 Timestamp::_internal_nanos() const { + return nanos_; +} +inline arc_i32 Timestamp::nanos() const { + // @@protoc_insertion_point(field_get:google.protobuf.Timestamp.nanos) + return _internal_nanos(); +} +inline void Timestamp::_internal_set_nanos(arc_i32 value) { + + nanos_ = value; +} +inline void Timestamp::set_nanos(arc_i32 value) { + _internal_set_nanos(value); + // @@protoc_insertion_point(field_set:google.protobuf.Timestamp.nanos) +} + +#ifdef __GNUC__ + #pragma GCC diagnostic pop +#endif // __GNUC__ + +// @@protoc_insertion_point(namespace_scope) + +PROTOBUF_NAMESPACE_CLOSE + +// @@protoc_insertion_point(global_scope) + +#include <google/protobuf/port_undef.inc> +#endif // GOOGLE_PROTOBUF_INCLUDED_GOOGLE_PROTOBUF_INCLUDED_google_2fprotobuf_2ftimestamp_2eproto diff --git a/contrib/libs/protobuf_old/src/google/protobuf/timestamp.proto b/contrib/libs/protobuf_old/src/google/protobuf/timestamp.proto new file mode 100644 index 0000000000..3b2df6d911 --- /dev/null +++ b/contrib/libs/protobuf_old/src/google/protobuf/timestamp.proto @@ -0,0 +1,147 @@ +// 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 google.protobuf; + +option csharp_namespace = "Google.Protobuf.WellKnownTypes"; +option cc_enable_arenas = true; +option go_package = "google.golang.org/protobuf/types/known/timestamppb"; +option java_package = "com.google.protobuf"; +option java_outer_classname = "TimestampProto"; +option java_multiple_files = true; +option objc_class_prefix = "GPB"; + +// A Timestamp represents a point in time independent of any time zone or local +// calendar, encoded as a count of seconds and fractions of seconds at +// nanosecond resolution. The count is relative to an epoch at UTC midnight on +// January 1, 1970, in the proleptic Gregorian calendar which extends the +// Gregorian calendar backwards to year one. +// +// All minutes are 60 seconds long. Leap seconds are "smeared" so that no leap +// second table is needed for interpretation, using a [24-hour linear +// smear](https://developers.google.com/time/smear). +// +// The range is from 0001-01-01T00:00:00Z to 9999-12-31T23:59:59.999999999Z. By +// restricting to that range, we ensure that we can convert to and from [RFC +// 3339](https://www.ietf.org/rfc/rfc3339.txt) date strings. +// +// # Examples +// +// Example 1: Compute Timestamp from POSIX `time()`. +// +// Timestamp timestamp; +// timestamp.set_seconds(time(NULL)); +// timestamp.set_nanos(0); +// +// Example 2: Compute Timestamp from POSIX `gettimeofday()`. +// +// struct timeval tv; +// gettimeofday(&tv, NULL); +// +// Timestamp timestamp; +// timestamp.set_seconds(tv.tv_sec); +// timestamp.set_nanos(tv.tv_usec * 1000); +// +// Example 3: Compute Timestamp from Win32 `GetSystemTimeAsFileTime()`. +// +// FILETIME ft; +// GetSystemTimeAsFileTime(&ft); +// UINT64 ticks = (((UINT64)ft.dwHighDateTime) << 32) | ft.dwLowDateTime; +// +// // A Windows tick is 100 nanoseconds. Windows epoch 1601-01-01T00:00:00Z +// // is 11644473600 seconds before Unix epoch 1970-01-01T00:00:00Z. +// Timestamp timestamp; +// timestamp.set_seconds((INT64) ((ticks / 10000000) - 11644473600LL)); +// timestamp.set_nanos((INT32) ((ticks % 10000000) * 100)); +// +// Example 4: Compute Timestamp from Java `System.currentTimeMillis()`. +// +// long millis = System.currentTimeMillis(); +// +// Timestamp timestamp = Timestamp.newBuilder().setSeconds(millis / 1000) +// .setNanos((int) ((millis % 1000) * 1000000)).build(); +// +// +// Example 5: Compute Timestamp from Java `Instant.now()`. +// +// Instant now = Instant.now(); +// +// Timestamp timestamp = +// Timestamp.newBuilder().setSeconds(now.getEpochSecond()) +// .setNanos(now.getNano()).build(); +// +// +// Example 6: Compute Timestamp from current time in Python. +// +// timestamp = Timestamp() +// timestamp.GetCurrentTime() +// +// # JSON Mapping +// +// In JSON format, the Timestamp type is encoded as a string in the +// [RFC 3339](https://www.ietf.org/rfc/rfc3339.txt) format. That is, the +// format is "{year}-{month}-{day}T{hour}:{min}:{sec}[.{frac_sec}]Z" +// where {year} is always expressed using four digits while {month}, {day}, +// {hour}, {min}, and {sec} are zero-padded to two digits each. The fractional +// seconds, which can go up to 9 digits (i.e. up to 1 nanosecond resolution), +// are optional. The "Z" suffix indicates the timezone ("UTC"); the timezone +// is required. A proto3 JSON serializer should always use UTC (as indicated by +// "Z") when printing the Timestamp type and a proto3 JSON parser should be +// able to accept both UTC and other timezones (as indicated by an offset). +// +// For example, "2017-01-15T01:30:15.01Z" encodes 15.01 seconds past +// 01:30 UTC on January 15, 2017. +// +// In JavaScript, one can convert a Date object to this format using the +// standard +// [toISOString()](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/toISOString) +// method. In Python, a standard `datetime.datetime` object can be converted +// to this format using +// [`strftime`](https://docs.python.org/2/library/time.html#time.strftime) with +// the time format spec '%Y-%m-%dT%H:%M:%S.%fZ'. Likewise, in Java, one can use +// the Joda Time's [`ISODateTimeFormat.dateTime()`]( +// http://www.joda.org/joda-time/apidocs/org/joda/time/format/ISODateTimeFormat.html#dateTime%2D%2D +// ) to obtain a formatter capable of generating timestamps in this format. +// +// +message Timestamp { + // Represents seconds of UTC time since Unix epoch + // 1970-01-01T00:00:00Z. Must be from 0001-01-01T00:00:00Z to + // 9999-12-31T23:59:59Z inclusive. + int64 seconds = 1; + + // Non-negative fractions of a second at nanosecond resolution. Negative + // second values with fractions must still have non-negative nanos values + // that count forward in time. Must be from 0 to 999,999,999 + // inclusive. + int32 nanos = 2; +} diff --git a/contrib/libs/protobuf_old/src/google/protobuf/type.pb.cc b/contrib/libs/protobuf_old/src/google/protobuf/type.pb.cc new file mode 100644 index 0000000000..a12ad27b82 --- /dev/null +++ b/contrib/libs/protobuf_old/src/google/protobuf/type.pb.cc @@ -0,0 +1,2133 @@ +// Generated by the protocol buffer compiler. DO NOT EDIT! +// source: google/protobuf/type.proto + +#include <google/protobuf/type.pb.h> + +#include <algorithm> + +#include <google/protobuf/io/coded_stream.h> +#include <google/protobuf/extension_set.h> +#include <google/protobuf/wire_format_lite.h> +#include <google/protobuf/descriptor.h> +#include <google/protobuf/generated_message_reflection.h> +#include <google/protobuf/reflection_ops.h> +#include <google/protobuf/wire_format.h> +// @@protoc_insertion_point(includes) +#include <google/protobuf/port_def.inc> + +PROTOBUF_PRAGMA_INIT_SEG +PROTOBUF_NAMESPACE_OPEN +constexpr Type::Type( + ::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized) + : fields_() + , oneofs_() + , options_() + , name_(&::PROTOBUF_NAMESPACE_ID::internal::fixed_address_empty_string) + , source_context_(nullptr) + , syntax_(0) +{} +struct TypeDefaultTypeInternal { + constexpr TypeDefaultTypeInternal() + : _instance(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized{}) {} + ~TypeDefaultTypeInternal() {} + union { + Type _instance; + }; +}; +PROTOBUF_ATTRIBUTE_NO_DESTROY PROTOBUF_CONSTINIT TypeDefaultTypeInternal _Type_default_instance_; +constexpr Field::Field( + ::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized) + : options_() + , name_(&::PROTOBUF_NAMESPACE_ID::internal::fixed_address_empty_string) + , type_url_(&::PROTOBUF_NAMESPACE_ID::internal::fixed_address_empty_string) + , json_name_(&::PROTOBUF_NAMESPACE_ID::internal::fixed_address_empty_string) + , default_value_(&::PROTOBUF_NAMESPACE_ID::internal::fixed_address_empty_string) + , kind_(0) + + , cardinality_(0) + + , number_(0) + , oneof_index_(0) + , packed_(false){} +struct FieldDefaultTypeInternal { + constexpr FieldDefaultTypeInternal() + : _instance(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized{}) {} + ~FieldDefaultTypeInternal() {} + union { + Field _instance; + }; +}; +PROTOBUF_ATTRIBUTE_NO_DESTROY PROTOBUF_CONSTINIT FieldDefaultTypeInternal _Field_default_instance_; +constexpr Enum::Enum( + ::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized) + : enumvalue_() + , options_() + , name_(&::PROTOBUF_NAMESPACE_ID::internal::fixed_address_empty_string) + , source_context_(nullptr) + , syntax_(0) +{} +struct EnumDefaultTypeInternal { + constexpr EnumDefaultTypeInternal() + : _instance(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized{}) {} + ~EnumDefaultTypeInternal() {} + union { + Enum _instance; + }; +}; +PROTOBUF_ATTRIBUTE_NO_DESTROY PROTOBUF_CONSTINIT EnumDefaultTypeInternal _Enum_default_instance_; +constexpr EnumValue::EnumValue( + ::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized) + : options_() + , name_(&::PROTOBUF_NAMESPACE_ID::internal::fixed_address_empty_string) + , number_(0){} +struct EnumValueDefaultTypeInternal { + constexpr EnumValueDefaultTypeInternal() + : _instance(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized{}) {} + ~EnumValueDefaultTypeInternal() {} + union { + EnumValue _instance; + }; +}; +PROTOBUF_ATTRIBUTE_NO_DESTROY PROTOBUF_CONSTINIT EnumValueDefaultTypeInternal _EnumValue_default_instance_; +constexpr Option::Option( + ::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized) + : name_(&::PROTOBUF_NAMESPACE_ID::internal::fixed_address_empty_string) + , value_(nullptr){} +struct OptionDefaultTypeInternal { + constexpr OptionDefaultTypeInternal() + : _instance(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized{}) {} + ~OptionDefaultTypeInternal() {} + union { + Option _instance; + }; +}; +PROTOBUF_ATTRIBUTE_NO_DESTROY PROTOBUF_CONSTINIT OptionDefaultTypeInternal _Option_default_instance_; +PROTOBUF_NAMESPACE_CLOSE +static ::PROTOBUF_NAMESPACE_ID::Metadata file_level_metadata_google_2fprotobuf_2ftype_2eproto[5]; +static const ::PROTOBUF_NAMESPACE_ID::EnumDescriptor* file_level_enum_descriptors_google_2fprotobuf_2ftype_2eproto[3]; +static constexpr ::PROTOBUF_NAMESPACE_ID::ServiceDescriptor const** file_level_service_descriptors_google_2fprotobuf_2ftype_2eproto = nullptr; + +const arc_ui32 TableStruct_google_2fprotobuf_2ftype_2eproto::offsets[] PROTOBUF_SECTION_VARIABLE(protodesc_cold) = { + ~0u, // no _has_bits_ + PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::Type, _internal_metadata_), + ~0u, // no _extensions_ + ~0u, // no _oneof_case_ + ~0u, // no _weak_field_map_ + ~0u, // no _inlined_string_donated_ + PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::Type, name_), + PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::Type, fields_), + PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::Type, oneofs_), + PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::Type, options_), + PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::Type, source_context_), + PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::Type, syntax_), + ~0u, // no _has_bits_ + PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::Field, _internal_metadata_), + ~0u, // no _extensions_ + ~0u, // no _oneof_case_ + ~0u, // no _weak_field_map_ + ~0u, // no _inlined_string_donated_ + PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::Field, kind_), + PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::Field, cardinality_), + PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::Field, number_), + PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::Field, name_), + PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::Field, type_url_), + PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::Field, oneof_index_), + PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::Field, packed_), + PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::Field, options_), + PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::Field, json_name_), + PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::Field, default_value_), + ~0u, // no _has_bits_ + PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::Enum, _internal_metadata_), + ~0u, // no _extensions_ + ~0u, // no _oneof_case_ + ~0u, // no _weak_field_map_ + ~0u, // no _inlined_string_donated_ + PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::Enum, name_), + PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::Enum, enumvalue_), + PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::Enum, options_), + PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::Enum, source_context_), + PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::Enum, syntax_), + ~0u, // no _has_bits_ + PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::EnumValue, _internal_metadata_), + ~0u, // no _extensions_ + ~0u, // no _oneof_case_ + ~0u, // no _weak_field_map_ + ~0u, // no _inlined_string_donated_ + PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::EnumValue, name_), + PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::EnumValue, number_), + PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::EnumValue, options_), + ~0u, // no _has_bits_ + PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::Option, _internal_metadata_), + ~0u, // no _extensions_ + ~0u, // no _oneof_case_ + ~0u, // no _weak_field_map_ + ~0u, // no _inlined_string_donated_ + PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::Option, name_), + PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::Option, value_), +}; +static const ::PROTOBUF_NAMESPACE_ID::internal::MigrationSchema schemas[] PROTOBUF_SECTION_VARIABLE(protodesc_cold) = { + { 0, -1, -1, sizeof(::PROTOBUF_NAMESPACE_ID::Type)}, + { 12, -1, -1, sizeof(::PROTOBUF_NAMESPACE_ID::Field)}, + { 28, -1, -1, sizeof(::PROTOBUF_NAMESPACE_ID::Enum)}, + { 39, -1, -1, sizeof(::PROTOBUF_NAMESPACE_ID::EnumValue)}, + { 48, -1, -1, sizeof(::PROTOBUF_NAMESPACE_ID::Option)}, +}; + +static ::PROTOBUF_NAMESPACE_ID::Message const * const file_default_instances[] = { + reinterpret_cast<const ::PROTOBUF_NAMESPACE_ID::Message*>(&::PROTOBUF_NAMESPACE_ID::_Type_default_instance_), + reinterpret_cast<const ::PROTOBUF_NAMESPACE_ID::Message*>(&::PROTOBUF_NAMESPACE_ID::_Field_default_instance_), + reinterpret_cast<const ::PROTOBUF_NAMESPACE_ID::Message*>(&::PROTOBUF_NAMESPACE_ID::_Enum_default_instance_), + reinterpret_cast<const ::PROTOBUF_NAMESPACE_ID::Message*>(&::PROTOBUF_NAMESPACE_ID::_EnumValue_default_instance_), + reinterpret_cast<const ::PROTOBUF_NAMESPACE_ID::Message*>(&::PROTOBUF_NAMESPACE_ID::_Option_default_instance_), +}; + +const char descriptor_table_protodef_google_2fprotobuf_2ftype_2eproto[] PROTOBUF_SECTION_VARIABLE(protodesc_cold) = + "\n\032google/protobuf/type.proto\022\017google.pro" + "tobuf\032\031google/protobuf/any.proto\032$google" + "/protobuf/source_context.proto\"\327\001\n\004Type\022" + "\014\n\004name\030\001 \001(\t\022&\n\006fields\030\002 \003(\0132\026.google.p" + "rotobuf.Field\022\016\n\006oneofs\030\003 \003(\t\022(\n\007options" + "\030\004 \003(\0132\027.google.protobuf.Option\0226\n\016sourc" + "e_context\030\005 \001(\0132\036.google.protobuf.Source" + "Context\022\'\n\006syntax\030\006 \001(\0162\027.google.protobu" + "f.Syntax\"\325\005\n\005Field\022)\n\004kind\030\001 \001(\0162\033.googl" + "e.protobuf.Field.Kind\0227\n\013cardinality\030\002 \001" + "(\0162\".google.protobuf.Field.Cardinality\022\016" + "\n\006number\030\003 \001(\005\022\014\n\004name\030\004 \001(\t\022\020\n\010type_url" + "\030\006 \001(\t\022\023\n\013oneof_index\030\007 \001(\005\022\016\n\006packed\030\010 " + "\001(\010\022(\n\007options\030\t \003(\0132\027.google.protobuf.O" + "ption\022\021\n\tjson_name\030\n \001(\t\022\025\n\rdefault_valu" + "e\030\013 \001(\t\"\310\002\n\004Kind\022\020\n\014TYPE_UNKNOWN\020\000\022\017\n\013TY" + "PE_DOUBLE\020\001\022\016\n\nTYPE_FLOAT\020\002\022\016\n\nTYPE_INT6" + "4\020\003\022\017\n\013TYPE_UINT64\020\004\022\016\n\nTYPE_INT32\020\005\022\020\n\014" + "TYPE_FIXED64\020\006\022\020\n\014TYPE_FIXED32\020\007\022\r\n\tTYPE" + "_BOOL\020\010\022\017\n\013TYPE_STRING\020\t\022\016\n\nTYPE_GROUP\020\n" + "\022\020\n\014TYPE_MESSAGE\020\013\022\016\n\nTYPE_BYTES\020\014\022\017\n\013TY" + "PE_UINT32\020\r\022\r\n\tTYPE_ENUM\020\016\022\021\n\rTYPE_SFIXE" + "D32\020\017\022\021\n\rTYPE_SFIXED64\020\020\022\017\n\013TYPE_SINT32\020" + "\021\022\017\n\013TYPE_SINT64\020\022\"t\n\013Cardinality\022\027\n\023CAR" + "DINALITY_UNKNOWN\020\000\022\030\n\024CARDINALITY_OPTION" + "AL\020\001\022\030\n\024CARDINALITY_REQUIRED\020\002\022\030\n\024CARDIN" + "ALITY_REPEATED\020\003\"\316\001\n\004Enum\022\014\n\004name\030\001 \001(\t\022" + "-\n\tenumvalue\030\002 \003(\0132\032.google.protobuf.Enu" + "mValue\022(\n\007options\030\003 \003(\0132\027.google.protobu" + "f.Option\0226\n\016source_context\030\004 \001(\0132\036.googl" + "e.protobuf.SourceContext\022\'\n\006syntax\030\005 \001(\016" + "2\027.google.protobuf.Syntax\"S\n\tEnumValue\022\014" + "\n\004name\030\001 \001(\t\022\016\n\006number\030\002 \001(\005\022(\n\007options\030" + "\003 \003(\0132\027.google.protobuf.Option\";\n\006Option" + "\022\014\n\004name\030\001 \001(\t\022#\n\005value\030\002 \001(\0132\024.google.p" + "rotobuf.Any*.\n\006Syntax\022\021\n\rSYNTAX_PROTO2\020\000" + "\022\021\n\rSYNTAX_PROTO3\020\001B{\n\023com.google.protob" + "ufB\tTypeProtoP\001Z-google.golang.org/proto" + "buf/types/known/typepb\370\001\001\242\002\003GPB\252\002\036Google" + ".Protobuf.WellKnownTypesb\006proto3" + ; +static const ::PROTOBUF_NAMESPACE_ID::internal::DescriptorTable*const descriptor_table_google_2fprotobuf_2ftype_2eproto_deps[2] = { + &::descriptor_table_google_2fprotobuf_2fany_2eproto, + &::descriptor_table_google_2fprotobuf_2fsource_5fcontext_2eproto, +}; +static ::PROTOBUF_NAMESPACE_ID::internal::once_flag descriptor_table_google_2fprotobuf_2ftype_2eproto_once; +const ::PROTOBUF_NAMESPACE_ID::internal::DescriptorTable descriptor_table_google_2fprotobuf_2ftype_2eproto = { + false, false, 1592, descriptor_table_protodef_google_2fprotobuf_2ftype_2eproto, "google/protobuf/type.proto", + &descriptor_table_google_2fprotobuf_2ftype_2eproto_once, descriptor_table_google_2fprotobuf_2ftype_2eproto_deps, 2, 5, + schemas, file_default_instances, TableStruct_google_2fprotobuf_2ftype_2eproto::offsets, + file_level_metadata_google_2fprotobuf_2ftype_2eproto, file_level_enum_descriptors_google_2fprotobuf_2ftype_2eproto, file_level_service_descriptors_google_2fprotobuf_2ftype_2eproto, +}; +PROTOBUF_ATTRIBUTE_WEAK const ::PROTOBUF_NAMESPACE_ID::internal::DescriptorTable* descriptor_table_google_2fprotobuf_2ftype_2eproto_getter() { + return &descriptor_table_google_2fprotobuf_2ftype_2eproto; +} + +// Force running AddDescriptors() at dynamic initialization time. +PROTOBUF_ATTRIBUTE_INIT_PRIORITY static ::PROTOBUF_NAMESPACE_ID::internal::AddDescriptorsRunner dynamic_init_dummy_google_2fprotobuf_2ftype_2eproto(&descriptor_table_google_2fprotobuf_2ftype_2eproto); +PROTOBUF_NAMESPACE_OPEN +const ::PROTOBUF_NAMESPACE_ID::EnumDescriptor* Field_Kind_descriptor() { + ::PROTOBUF_NAMESPACE_ID::internal::AssignDescriptors(&descriptor_table_google_2fprotobuf_2ftype_2eproto); + return file_level_enum_descriptors_google_2fprotobuf_2ftype_2eproto[0]; +} +bool Field_Kind_IsValid(int value) { + switch (value) { + case 0: + case 1: + case 2: + case 3: + case 4: + case 5: + case 6: + case 7: + case 8: + case 9: + case 10: + case 11: + case 12: + case 13: + case 14: + case 15: + case 16: + case 17: + case 18: + return true; + default: + return false; + } +} + +#if (__cplusplus < 201703) && (!defined(_MSC_VER) || (_MSC_VER >= 1900 && _MSC_VER < 1912)) +constexpr Field_Kind Field::TYPE_UNKNOWN; +constexpr Field_Kind Field::TYPE_DOUBLE; +constexpr Field_Kind Field::TYPE_FLOAT; +constexpr Field_Kind Field::TYPE_INT64; +constexpr Field_Kind Field::TYPE_UINT64; +constexpr Field_Kind Field::TYPE_INT32; +constexpr Field_Kind Field::TYPE_FIXED64; +constexpr Field_Kind Field::TYPE_FIXED32; +constexpr Field_Kind Field::TYPE_BOOL; +constexpr Field_Kind Field::TYPE_STRING; +constexpr Field_Kind Field::TYPE_GROUP; +constexpr Field_Kind Field::TYPE_MESSAGE; +constexpr Field_Kind Field::TYPE_BYTES; +constexpr Field_Kind Field::TYPE_UINT32; +constexpr Field_Kind Field::TYPE_ENUM; +constexpr Field_Kind Field::TYPE_SFIXED32; +constexpr Field_Kind Field::TYPE_SFIXED64; +constexpr Field_Kind Field::TYPE_SINT32; +constexpr Field_Kind Field::TYPE_SINT64; +constexpr Field_Kind Field::Kind_MIN; +constexpr Field_Kind Field::Kind_MAX; +constexpr int Field::Kind_ARRAYSIZE; +#endif // (__cplusplus < 201703) && (!defined(_MSC_VER) || (_MSC_VER >= 1900 && _MSC_VER < 1912)) +const ::PROTOBUF_NAMESPACE_ID::EnumDescriptor* Field_Cardinality_descriptor() { + ::PROTOBUF_NAMESPACE_ID::internal::AssignDescriptors(&descriptor_table_google_2fprotobuf_2ftype_2eproto); + return file_level_enum_descriptors_google_2fprotobuf_2ftype_2eproto[1]; +} +bool Field_Cardinality_IsValid(int value) { + switch (value) { + case 0: + case 1: + case 2: + case 3: + return true; + default: + return false; + } +} + +#if (__cplusplus < 201703) && (!defined(_MSC_VER) || (_MSC_VER >= 1900 && _MSC_VER < 1912)) +constexpr Field_Cardinality Field::CARDINALITY_UNKNOWN; +constexpr Field_Cardinality Field::CARDINALITY_OPTIONAL; +constexpr Field_Cardinality Field::CARDINALITY_REQUIRED; +constexpr Field_Cardinality Field::CARDINALITY_REPEATED; +constexpr Field_Cardinality Field::Cardinality_MIN; +constexpr Field_Cardinality Field::Cardinality_MAX; +constexpr int Field::Cardinality_ARRAYSIZE; +#endif // (__cplusplus < 201703) && (!defined(_MSC_VER) || (_MSC_VER >= 1900 && _MSC_VER < 1912)) +const ::PROTOBUF_NAMESPACE_ID::EnumDescriptor* Syntax_descriptor() { + ::PROTOBUF_NAMESPACE_ID::internal::AssignDescriptors(&descriptor_table_google_2fprotobuf_2ftype_2eproto); + return file_level_enum_descriptors_google_2fprotobuf_2ftype_2eproto[2]; +} +bool Syntax_IsValid(int value) { + switch (value) { + case 0: + case 1: + return true; + default: + return false; + } +} + + +// =================================================================== + +class Type::_Internal { + public: + static const ::PROTOBUF_NAMESPACE_ID::SourceContext& source_context(const Type* msg); +}; + +const ::PROTOBUF_NAMESPACE_ID::SourceContext& +Type::_Internal::source_context(const Type* msg) { + return *msg->source_context_; +} +void Type::clear_source_context() { + if (GetArenaForAllocation() == nullptr && source_context_ != nullptr) { + delete source_context_; + } + source_context_ = nullptr; +} +Type::Type(::PROTOBUF_NAMESPACE_ID::Arena* arena, + bool is_message_owned) + : ::PROTOBUF_NAMESPACE_ID::Message(arena, is_message_owned), + fields_(arena), + oneofs_(arena), + options_(arena) { + SharedCtor(); + if (!is_message_owned) { + RegisterArenaDtor(arena); + } + // @@protoc_insertion_point(arena_constructor:google.protobuf.Type) +} +Type::Type(const Type& from) + : ::PROTOBUF_NAMESPACE_ID::Message(), + fields_(from.fields_), + oneofs_(from.oneofs_), + options_(from.options_) { + _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_); + name_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); + #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING + name_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation()); + #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING + if (!from._internal_name().empty()) { + name_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, from._internal_name(), + GetArenaForAllocation()); + } + if (from._internal_has_source_context()) { + source_context_ = new ::PROTOBUF_NAMESPACE_ID::SourceContext(*from.source_context_); + } else { + source_context_ = nullptr; + } + syntax_ = from.syntax_; + // @@protoc_insertion_point(copy_constructor:google.protobuf.Type) +} + +inline void Type::SharedCtor() { +name_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); +#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING + name_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation()); +#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING +::memset(reinterpret_cast<char*>(this) + static_cast<size_t>( + reinterpret_cast<char*>(&source_context_) - reinterpret_cast<char*>(this)), + 0, static_cast<size_t>(reinterpret_cast<char*>(&syntax_) - + reinterpret_cast<char*>(&source_context_)) + sizeof(syntax_)); +} + +Type::~Type() { + // @@protoc_insertion_point(destructor:google.protobuf.Type) + if (GetArenaForAllocation() != nullptr) return; + SharedDtor(); + _internal_metadata_.Delete<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(); +} + +inline void Type::SharedDtor() { + GOOGLE_DCHECK(GetArenaForAllocation() == nullptr); + name_.DestroyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); + if (this != internal_default_instance()) delete source_context_; +} + +void Type::ArenaDtor(void* object) { + Type* _this = reinterpret_cast< Type* >(object); + (void)_this; +} +void Type::RegisterArenaDtor(::PROTOBUF_NAMESPACE_ID::Arena*) { +} +void Type::SetCachedSize(int size) const { + _cached_size_.Set(size); +} + +void Type::Clear() { +// @@protoc_insertion_point(message_clear_start:google.protobuf.Type) + arc_ui32 cached_has_bits = 0; + // Prevent compiler warnings about cached_has_bits being unused + (void) cached_has_bits; + + fields_.Clear(); + oneofs_.Clear(); + options_.Clear(); + name_.ClearToEmpty(); + if (GetArenaForAllocation() == nullptr && source_context_ != nullptr) { + delete source_context_; + } + source_context_ = nullptr; + syntax_ = 0; + _internal_metadata_.Clear<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(); +} + +const char* Type::_InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) { +#define CHK_(x) if (PROTOBUF_PREDICT_FALSE(!(x))) goto failure + while (!ctx->Done(&ptr)) { + arc_ui32 tag; + ptr = ::PROTOBUF_NAMESPACE_ID::internal::ReadTag(ptr, &tag); + switch (tag >> 3) { + // string name = 1; + case 1: + if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 10)) { + auto str = _internal_mutable_name(); + ptr = ::PROTOBUF_NAMESPACE_ID::internal::InlineGreedyStringParser(str, ptr, ctx); + CHK_(::PROTOBUF_NAMESPACE_ID::internal::VerifyUTF8(str, "google.protobuf.Type.name")); + CHK_(ptr); + } else + goto handle_unusual; + continue; + // repeated .google.protobuf.Field fields = 2; + case 2: + if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 18)) { + ptr -= 1; + do { + ptr += 1; + ptr = ctx->ParseMessage(_internal_add_fields(), ptr); + CHK_(ptr); + if (!ctx->DataAvailable(ptr)) break; + } while (::PROTOBUF_NAMESPACE_ID::internal::ExpectTag<18>(ptr)); + } else + goto handle_unusual; + continue; + // repeated string oneofs = 3; + case 3: + if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 26)) { + ptr -= 1; + do { + ptr += 1; + auto str = _internal_add_oneofs(); + ptr = ::PROTOBUF_NAMESPACE_ID::internal::InlineGreedyStringParser(str, ptr, ctx); + CHK_(::PROTOBUF_NAMESPACE_ID::internal::VerifyUTF8(str, "google.protobuf.Type.oneofs")); + CHK_(ptr); + if (!ctx->DataAvailable(ptr)) break; + } while (::PROTOBUF_NAMESPACE_ID::internal::ExpectTag<26>(ptr)); + } else + goto handle_unusual; + continue; + // repeated .google.protobuf.Option options = 4; + case 4: + if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 34)) { + ptr -= 1; + do { + ptr += 1; + ptr = ctx->ParseMessage(_internal_add_options(), ptr); + CHK_(ptr); + if (!ctx->DataAvailable(ptr)) break; + } while (::PROTOBUF_NAMESPACE_ID::internal::ExpectTag<34>(ptr)); + } else + goto handle_unusual; + continue; + // .google.protobuf.SourceContext source_context = 5; + case 5: + if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 42)) { + ptr = ctx->ParseMessage(_internal_mutable_source_context(), ptr); + CHK_(ptr); + } else + goto handle_unusual; + continue; + // .google.protobuf.Syntax syntax = 6; + case 6: + if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 48)) { + arc_ui64 val = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint64(&ptr); + CHK_(ptr); + _internal_set_syntax(static_cast<::PROTOBUF_NAMESPACE_ID::Syntax>(val)); + } else + goto handle_unusual; + continue; + default: + goto handle_unusual; + } // switch + handle_unusual: + if ((tag == 0) || ((tag & 7) == 4)) { + CHK_(ptr); + ctx->SetLastTag(tag); + goto message_done; + } + ptr = UnknownFieldParse( + tag, + _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(), + ptr, ctx); + CHK_(ptr != nullptr); + } // while +message_done: + return ptr; +failure: + ptr = nullptr; + goto message_done; +#undef CHK_ +} + +uint8_t* Type::_InternalSerialize( + uint8_t* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const { + // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.Type) + arc_ui32 cached_has_bits = 0; + (void) cached_has_bits; + + // string name = 1; + if (!this->_internal_name().empty()) { + ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::VerifyUtf8String( + this->_internal_name().data(), static_cast<int>(this->_internal_name().length()), + ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::SERIALIZE, + "google.protobuf.Type.name"); + target = stream->WriteStringMaybeAliased( + 1, this->_internal_name(), target); + } + + // repeated .google.protobuf.Field fields = 2; + for (unsigned int i = 0, + n = static_cast<unsigned int>(this->_internal_fields_size()); i < n; i++) { + target = stream->EnsureSpace(target); + target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite:: + InternalWriteMessage(2, this->_internal_fields(i), target, stream); + } + + // repeated string oneofs = 3; + for (int i = 0, n = this->_internal_oneofs_size(); i < n; i++) { + const auto& s = this->_internal_oneofs(i); + ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::VerifyUtf8String( + s.data(), static_cast<int>(s.length()), + ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::SERIALIZE, + "google.protobuf.Type.oneofs"); + target = stream->WriteString(3, s, target); + } + + // repeated .google.protobuf.Option options = 4; + for (unsigned int i = 0, + n = static_cast<unsigned int>(this->_internal_options_size()); i < n; i++) { + target = stream->EnsureSpace(target); + target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite:: + InternalWriteMessage(4, this->_internal_options(i), target, stream); + } + + // .google.protobuf.SourceContext source_context = 5; + if (this->_internal_has_source_context()) { + target = stream->EnsureSpace(target); + target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite:: + InternalWriteMessage( + 5, _Internal::source_context(this), target, stream); + } + + // .google.protobuf.Syntax syntax = 6; + if (this->_internal_syntax() != 0) { + target = stream->EnsureSpace(target); + target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteEnumToArray( + 6, this->_internal_syntax(), target); + } + + if (PROTOBUF_PREDICT_FALSE(_internal_metadata_.have_unknown_fields())) { + target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::InternalSerializeUnknownFieldsToArray( + _internal_metadata_.unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(::PROTOBUF_NAMESPACE_ID::UnknownFieldSet::default_instance), target, stream); + } + // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.Type) + return target; +} + +size_t Type::ByteSizeLong() const { +// @@protoc_insertion_point(message_byte_size_start:google.protobuf.Type) + size_t total_size = 0; + + arc_ui32 cached_has_bits = 0; + // Prevent compiler warnings about cached_has_bits being unused + (void) cached_has_bits; + + // repeated .google.protobuf.Field fields = 2; + total_size += 1UL * this->_internal_fields_size(); + for (const auto& msg : this->fields_) { + total_size += + ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::MessageSize(msg); + } + + // repeated string oneofs = 3; + total_size += 1 * + ::PROTOBUF_NAMESPACE_ID::internal::FromIntSize(oneofs_.size()); + for (int i = 0, n = oneofs_.size(); i < n; i++) { + total_size += ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::StringSize( + oneofs_.Get(i)); + } + + // repeated .google.protobuf.Option options = 4; + total_size += 1UL * this->_internal_options_size(); + for (const auto& msg : this->options_) { + total_size += + ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::MessageSize(msg); + } + + // string name = 1; + if (!this->_internal_name().empty()) { + total_size += 1 + + ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::StringSize( + this->_internal_name()); + } + + // .google.protobuf.SourceContext source_context = 5; + if (this->_internal_has_source_context()) { + total_size += 1 + + ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::MessageSize( + *source_context_); + } + + // .google.protobuf.Syntax syntax = 6; + if (this->_internal_syntax() != 0) { + total_size += 1 + + ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::EnumSize(this->_internal_syntax()); + } + + return MaybeComputeUnknownFieldsSize(total_size, &_cached_size_); +} + +const ::PROTOBUF_NAMESPACE_ID::Message::ClassData Type::_class_data_ = { + ::PROTOBUF_NAMESPACE_ID::Message::CopyWithSizeCheck, + Type::MergeImpl +}; +const ::PROTOBUF_NAMESPACE_ID::Message::ClassData*Type::GetClassData() const { return &_class_data_; } + +void Type::MergeImpl(::PROTOBUF_NAMESPACE_ID::Message* to, + const ::PROTOBUF_NAMESPACE_ID::Message& from) { + static_cast<Type *>(to)->MergeFrom( + static_cast<const Type &>(from)); +} + + +void Type::MergeFrom(const Type& from) { +// @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.Type) + GOOGLE_DCHECK_NE(&from, this); + arc_ui32 cached_has_bits = 0; + (void) cached_has_bits; + + fields_.MergeFrom(from.fields_); + oneofs_.MergeFrom(from.oneofs_); + options_.MergeFrom(from.options_); + if (!from._internal_name().empty()) { + _internal_set_name(from._internal_name()); + } + if (from._internal_has_source_context()) { + _internal_mutable_source_context()->::PROTOBUF_NAMESPACE_ID::SourceContext::MergeFrom(from._internal_source_context()); + } + if (from._internal_syntax() != 0) { + _internal_set_syntax(from._internal_syntax()); + } + _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_); +} + +void Type::CopyFrom(const Type& from) { +// @@protoc_insertion_point(class_specific_copy_from_start:google.protobuf.Type) + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool Type::IsInitialized() const { + return true; +} + +void Type::InternalSwap(Type* other) { + using std::swap; + auto* lhs_arena = GetArenaForAllocation(); + auto* rhs_arena = other->GetArenaForAllocation(); + _internal_metadata_.InternalSwap(&other->_internal_metadata_); + fields_.InternalSwap(&other->fields_); + oneofs_.InternalSwap(&other->oneofs_); + options_.InternalSwap(&other->options_); + ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::InternalSwap( + &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), + &name_, lhs_arena, + &other->name_, rhs_arena + ); + ::PROTOBUF_NAMESPACE_ID::internal::memswap< + PROTOBUF_FIELD_OFFSET(Type, syntax_) + + sizeof(Type::syntax_) + - PROTOBUF_FIELD_OFFSET(Type, source_context_)>( + reinterpret_cast<char*>(&source_context_), + reinterpret_cast<char*>(&other->source_context_)); +} + +::PROTOBUF_NAMESPACE_ID::Metadata Type::GetMetadata() const { + return ::PROTOBUF_NAMESPACE_ID::internal::AssignDescriptors( + &descriptor_table_google_2fprotobuf_2ftype_2eproto_getter, &descriptor_table_google_2fprotobuf_2ftype_2eproto_once, + file_level_metadata_google_2fprotobuf_2ftype_2eproto[0]); +} + +// =================================================================== + +class Field::_Internal { + public: +}; + +Field::Field(::PROTOBUF_NAMESPACE_ID::Arena* arena, + bool is_message_owned) + : ::PROTOBUF_NAMESPACE_ID::Message(arena, is_message_owned), + options_(arena) { + SharedCtor(); + if (!is_message_owned) { + RegisterArenaDtor(arena); + } + // @@protoc_insertion_point(arena_constructor:google.protobuf.Field) +} +Field::Field(const Field& from) + : ::PROTOBUF_NAMESPACE_ID::Message(), + options_(from.options_) { + _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_); + name_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); + #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING + name_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation()); + #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING + if (!from._internal_name().empty()) { + name_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, from._internal_name(), + GetArenaForAllocation()); + } + type_url_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); + #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING + type_url_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation()); + #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING + if (!from._internal_type_url().empty()) { + type_url_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, from._internal_type_url(), + GetArenaForAllocation()); + } + json_name_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); + #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING + json_name_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation()); + #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING + if (!from._internal_json_name().empty()) { + json_name_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, from._internal_json_name(), + GetArenaForAllocation()); + } + default_value_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); + #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING + default_value_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation()); + #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING + if (!from._internal_default_value().empty()) { + default_value_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, from._internal_default_value(), + GetArenaForAllocation()); + } + ::memcpy(&kind_, &from.kind_, + static_cast<size_t>(reinterpret_cast<char*>(&packed_) - + reinterpret_cast<char*>(&kind_)) + sizeof(packed_)); + // @@protoc_insertion_point(copy_constructor:google.protobuf.Field) +} + +inline void Field::SharedCtor() { +name_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); +#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING + name_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation()); +#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING +type_url_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); +#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING + type_url_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation()); +#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING +json_name_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); +#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING + json_name_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation()); +#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING +default_value_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); +#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING + default_value_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation()); +#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING +::memset(reinterpret_cast<char*>(this) + static_cast<size_t>( + reinterpret_cast<char*>(&kind_) - reinterpret_cast<char*>(this)), + 0, static_cast<size_t>(reinterpret_cast<char*>(&packed_) - + reinterpret_cast<char*>(&kind_)) + sizeof(packed_)); +} + +Field::~Field() { + // @@protoc_insertion_point(destructor:google.protobuf.Field) + if (GetArenaForAllocation() != nullptr) return; + SharedDtor(); + _internal_metadata_.Delete<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(); +} + +inline void Field::SharedDtor() { + GOOGLE_DCHECK(GetArenaForAllocation() == nullptr); + name_.DestroyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); + type_url_.DestroyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); + json_name_.DestroyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); + default_value_.DestroyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); +} + +void Field::ArenaDtor(void* object) { + Field* _this = reinterpret_cast< Field* >(object); + (void)_this; +} +void Field::RegisterArenaDtor(::PROTOBUF_NAMESPACE_ID::Arena*) { +} +void Field::SetCachedSize(int size) const { + _cached_size_.Set(size); +} + +void Field::Clear() { +// @@protoc_insertion_point(message_clear_start:google.protobuf.Field) + arc_ui32 cached_has_bits = 0; + // Prevent compiler warnings about cached_has_bits being unused + (void) cached_has_bits; + + options_.Clear(); + name_.ClearToEmpty(); + type_url_.ClearToEmpty(); + json_name_.ClearToEmpty(); + default_value_.ClearToEmpty(); + ::memset(&kind_, 0, static_cast<size_t>( + reinterpret_cast<char*>(&packed_) - + reinterpret_cast<char*>(&kind_)) + sizeof(packed_)); + _internal_metadata_.Clear<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(); +} + +const char* Field::_InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) { +#define CHK_(x) if (PROTOBUF_PREDICT_FALSE(!(x))) goto failure + while (!ctx->Done(&ptr)) { + arc_ui32 tag; + ptr = ::PROTOBUF_NAMESPACE_ID::internal::ReadTag(ptr, &tag); + switch (tag >> 3) { + // .google.protobuf.Field.Kind kind = 1; + case 1: + if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 8)) { + arc_ui64 val = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint64(&ptr); + CHK_(ptr); + _internal_set_kind(static_cast<::PROTOBUF_NAMESPACE_ID::Field_Kind>(val)); + } else + goto handle_unusual; + continue; + // .google.protobuf.Field.Cardinality cardinality = 2; + case 2: + if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 16)) { + arc_ui64 val = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint64(&ptr); + CHK_(ptr); + _internal_set_cardinality(static_cast<::PROTOBUF_NAMESPACE_ID::Field_Cardinality>(val)); + } else + goto handle_unusual; + continue; + // int32 number = 3; + case 3: + if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 24)) { + number_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint32(&ptr); + CHK_(ptr); + } else + goto handle_unusual; + continue; + // string name = 4; + case 4: + if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 34)) { + auto str = _internal_mutable_name(); + ptr = ::PROTOBUF_NAMESPACE_ID::internal::InlineGreedyStringParser(str, ptr, ctx); + CHK_(::PROTOBUF_NAMESPACE_ID::internal::VerifyUTF8(str, "google.protobuf.Field.name")); + CHK_(ptr); + } else + goto handle_unusual; + continue; + // string type_url = 6; + case 6: + if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 50)) { + auto str = _internal_mutable_type_url(); + ptr = ::PROTOBUF_NAMESPACE_ID::internal::InlineGreedyStringParser(str, ptr, ctx); + CHK_(::PROTOBUF_NAMESPACE_ID::internal::VerifyUTF8(str, "google.protobuf.Field.type_url")); + CHK_(ptr); + } else + goto handle_unusual; + continue; + // int32 oneof_index = 7; + case 7: + if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 56)) { + oneof_index_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint32(&ptr); + CHK_(ptr); + } else + goto handle_unusual; + continue; + // bool packed = 8; + case 8: + if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 64)) { + packed_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint64(&ptr); + CHK_(ptr); + } else + goto handle_unusual; + continue; + // repeated .google.protobuf.Option options = 9; + case 9: + if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 74)) { + ptr -= 1; + do { + ptr += 1; + ptr = ctx->ParseMessage(_internal_add_options(), ptr); + CHK_(ptr); + if (!ctx->DataAvailable(ptr)) break; + } while (::PROTOBUF_NAMESPACE_ID::internal::ExpectTag<74>(ptr)); + } else + goto handle_unusual; + continue; + // string json_name = 10; + case 10: + if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 82)) { + auto str = _internal_mutable_json_name(); + ptr = ::PROTOBUF_NAMESPACE_ID::internal::InlineGreedyStringParser(str, ptr, ctx); + CHK_(::PROTOBUF_NAMESPACE_ID::internal::VerifyUTF8(str, "google.protobuf.Field.json_name")); + CHK_(ptr); + } else + goto handle_unusual; + continue; + // string default_value = 11; + case 11: + if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 90)) { + auto str = _internal_mutable_default_value(); + ptr = ::PROTOBUF_NAMESPACE_ID::internal::InlineGreedyStringParser(str, ptr, ctx); + CHK_(::PROTOBUF_NAMESPACE_ID::internal::VerifyUTF8(str, "google.protobuf.Field.default_value")); + CHK_(ptr); + } else + goto handle_unusual; + continue; + default: + goto handle_unusual; + } // switch + handle_unusual: + if ((tag == 0) || ((tag & 7) == 4)) { + CHK_(ptr); + ctx->SetLastTag(tag); + goto message_done; + } + ptr = UnknownFieldParse( + tag, + _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(), + ptr, ctx); + CHK_(ptr != nullptr); + } // while +message_done: + return ptr; +failure: + ptr = nullptr; + goto message_done; +#undef CHK_ +} + +uint8_t* Field::_InternalSerialize( + uint8_t* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const { + // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.Field) + arc_ui32 cached_has_bits = 0; + (void) cached_has_bits; + + // .google.protobuf.Field.Kind kind = 1; + if (this->_internal_kind() != 0) { + target = stream->EnsureSpace(target); + target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteEnumToArray( + 1, this->_internal_kind(), target); + } + + // .google.protobuf.Field.Cardinality cardinality = 2; + if (this->_internal_cardinality() != 0) { + target = stream->EnsureSpace(target); + target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteEnumToArray( + 2, this->_internal_cardinality(), target); + } + + // int32 number = 3; + if (this->_internal_number() != 0) { + target = stream->EnsureSpace(target); + target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteInt32ToArray(3, this->_internal_number(), target); + } + + // string name = 4; + if (!this->_internal_name().empty()) { + ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::VerifyUtf8String( + this->_internal_name().data(), static_cast<int>(this->_internal_name().length()), + ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::SERIALIZE, + "google.protobuf.Field.name"); + target = stream->WriteStringMaybeAliased( + 4, this->_internal_name(), target); + } + + // string type_url = 6; + if (!this->_internal_type_url().empty()) { + ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::VerifyUtf8String( + this->_internal_type_url().data(), static_cast<int>(this->_internal_type_url().length()), + ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::SERIALIZE, + "google.protobuf.Field.type_url"); + target = stream->WriteStringMaybeAliased( + 6, this->_internal_type_url(), target); + } + + // int32 oneof_index = 7; + if (this->_internal_oneof_index() != 0) { + target = stream->EnsureSpace(target); + target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteInt32ToArray(7, this->_internal_oneof_index(), target); + } + + // bool packed = 8; + if (this->_internal_packed() != 0) { + target = stream->EnsureSpace(target); + target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteBoolToArray(8, this->_internal_packed(), target); + } + + // repeated .google.protobuf.Option options = 9; + for (unsigned int i = 0, + n = static_cast<unsigned int>(this->_internal_options_size()); i < n; i++) { + target = stream->EnsureSpace(target); + target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite:: + InternalWriteMessage(9, this->_internal_options(i), target, stream); + } + + // string json_name = 10; + if (!this->_internal_json_name().empty()) { + ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::VerifyUtf8String( + this->_internal_json_name().data(), static_cast<int>(this->_internal_json_name().length()), + ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::SERIALIZE, + "google.protobuf.Field.json_name"); + target = stream->WriteStringMaybeAliased( + 10, this->_internal_json_name(), target); + } + + // string default_value = 11; + if (!this->_internal_default_value().empty()) { + ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::VerifyUtf8String( + this->_internal_default_value().data(), static_cast<int>(this->_internal_default_value().length()), + ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::SERIALIZE, + "google.protobuf.Field.default_value"); + target = stream->WriteStringMaybeAliased( + 11, this->_internal_default_value(), target); + } + + if (PROTOBUF_PREDICT_FALSE(_internal_metadata_.have_unknown_fields())) { + target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::InternalSerializeUnknownFieldsToArray( + _internal_metadata_.unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(::PROTOBUF_NAMESPACE_ID::UnknownFieldSet::default_instance), target, stream); + } + // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.Field) + return target; +} + +size_t Field::ByteSizeLong() const { +// @@protoc_insertion_point(message_byte_size_start:google.protobuf.Field) + size_t total_size = 0; + + arc_ui32 cached_has_bits = 0; + // Prevent compiler warnings about cached_has_bits being unused + (void) cached_has_bits; + + // repeated .google.protobuf.Option options = 9; + total_size += 1UL * this->_internal_options_size(); + for (const auto& msg : this->options_) { + total_size += + ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::MessageSize(msg); + } + + // string name = 4; + if (!this->_internal_name().empty()) { + total_size += 1 + + ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::StringSize( + this->_internal_name()); + } + + // string type_url = 6; + if (!this->_internal_type_url().empty()) { + total_size += 1 + + ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::StringSize( + this->_internal_type_url()); + } + + // string json_name = 10; + if (!this->_internal_json_name().empty()) { + total_size += 1 + + ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::StringSize( + this->_internal_json_name()); + } + + // string default_value = 11; + if (!this->_internal_default_value().empty()) { + total_size += 1 + + ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::StringSize( + this->_internal_default_value()); + } + + // .google.protobuf.Field.Kind kind = 1; + if (this->_internal_kind() != 0) { + total_size += 1 + + ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::EnumSize(this->_internal_kind()); + } + + // .google.protobuf.Field.Cardinality cardinality = 2; + if (this->_internal_cardinality() != 0) { + total_size += 1 + + ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::EnumSize(this->_internal_cardinality()); + } + + // int32 number = 3; + if (this->_internal_number() != 0) { + total_size += ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::Int32SizePlusOne(this->_internal_number()); + } + + // int32 oneof_index = 7; + if (this->_internal_oneof_index() != 0) { + total_size += ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::Int32SizePlusOne(this->_internal_oneof_index()); + } + + // bool packed = 8; + if (this->_internal_packed() != 0) { + total_size += 1 + 1; + } + + return MaybeComputeUnknownFieldsSize(total_size, &_cached_size_); +} + +const ::PROTOBUF_NAMESPACE_ID::Message::ClassData Field::_class_data_ = { + ::PROTOBUF_NAMESPACE_ID::Message::CopyWithSizeCheck, + Field::MergeImpl +}; +const ::PROTOBUF_NAMESPACE_ID::Message::ClassData*Field::GetClassData() const { return &_class_data_; } + +void Field::MergeImpl(::PROTOBUF_NAMESPACE_ID::Message* to, + const ::PROTOBUF_NAMESPACE_ID::Message& from) { + static_cast<Field *>(to)->MergeFrom( + static_cast<const Field &>(from)); +} + + +void Field::MergeFrom(const Field& from) { +// @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.Field) + GOOGLE_DCHECK_NE(&from, this); + arc_ui32 cached_has_bits = 0; + (void) cached_has_bits; + + options_.MergeFrom(from.options_); + if (!from._internal_name().empty()) { + _internal_set_name(from._internal_name()); + } + if (!from._internal_type_url().empty()) { + _internal_set_type_url(from._internal_type_url()); + } + if (!from._internal_json_name().empty()) { + _internal_set_json_name(from._internal_json_name()); + } + if (!from._internal_default_value().empty()) { + _internal_set_default_value(from._internal_default_value()); + } + if (from._internal_kind() != 0) { + _internal_set_kind(from._internal_kind()); + } + if (from._internal_cardinality() != 0) { + _internal_set_cardinality(from._internal_cardinality()); + } + if (from._internal_number() != 0) { + _internal_set_number(from._internal_number()); + } + if (from._internal_oneof_index() != 0) { + _internal_set_oneof_index(from._internal_oneof_index()); + } + if (from._internal_packed() != 0) { + _internal_set_packed(from._internal_packed()); + } + _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_); +} + +void Field::CopyFrom(const Field& from) { +// @@protoc_insertion_point(class_specific_copy_from_start:google.protobuf.Field) + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool Field::IsInitialized() const { + return true; +} + +void Field::InternalSwap(Field* other) { + using std::swap; + auto* lhs_arena = GetArenaForAllocation(); + auto* rhs_arena = other->GetArenaForAllocation(); + _internal_metadata_.InternalSwap(&other->_internal_metadata_); + options_.InternalSwap(&other->options_); + ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::InternalSwap( + &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), + &name_, lhs_arena, + &other->name_, rhs_arena + ); + ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::InternalSwap( + &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), + &type_url_, lhs_arena, + &other->type_url_, rhs_arena + ); + ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::InternalSwap( + &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), + &json_name_, lhs_arena, + &other->json_name_, rhs_arena + ); + ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::InternalSwap( + &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), + &default_value_, lhs_arena, + &other->default_value_, rhs_arena + ); + ::PROTOBUF_NAMESPACE_ID::internal::memswap< + PROTOBUF_FIELD_OFFSET(Field, packed_) + + sizeof(Field::packed_) + - PROTOBUF_FIELD_OFFSET(Field, kind_)>( + reinterpret_cast<char*>(&kind_), + reinterpret_cast<char*>(&other->kind_)); +} + +::PROTOBUF_NAMESPACE_ID::Metadata Field::GetMetadata() const { + return ::PROTOBUF_NAMESPACE_ID::internal::AssignDescriptors( + &descriptor_table_google_2fprotobuf_2ftype_2eproto_getter, &descriptor_table_google_2fprotobuf_2ftype_2eproto_once, + file_level_metadata_google_2fprotobuf_2ftype_2eproto[1]); +} + +// =================================================================== + +class Enum::_Internal { + public: + static const ::PROTOBUF_NAMESPACE_ID::SourceContext& source_context(const Enum* msg); +}; + +const ::PROTOBUF_NAMESPACE_ID::SourceContext& +Enum::_Internal::source_context(const Enum* msg) { + return *msg->source_context_; +} +void Enum::clear_source_context() { + if (GetArenaForAllocation() == nullptr && source_context_ != nullptr) { + delete source_context_; + } + source_context_ = nullptr; +} +Enum::Enum(::PROTOBUF_NAMESPACE_ID::Arena* arena, + bool is_message_owned) + : ::PROTOBUF_NAMESPACE_ID::Message(arena, is_message_owned), + enumvalue_(arena), + options_(arena) { + SharedCtor(); + if (!is_message_owned) { + RegisterArenaDtor(arena); + } + // @@protoc_insertion_point(arena_constructor:google.protobuf.Enum) +} +Enum::Enum(const Enum& from) + : ::PROTOBUF_NAMESPACE_ID::Message(), + enumvalue_(from.enumvalue_), + options_(from.options_) { + _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_); + name_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); + #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING + name_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation()); + #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING + if (!from._internal_name().empty()) { + name_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, from._internal_name(), + GetArenaForAllocation()); + } + if (from._internal_has_source_context()) { + source_context_ = new ::PROTOBUF_NAMESPACE_ID::SourceContext(*from.source_context_); + } else { + source_context_ = nullptr; + } + syntax_ = from.syntax_; + // @@protoc_insertion_point(copy_constructor:google.protobuf.Enum) +} + +inline void Enum::SharedCtor() { +name_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); +#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING + name_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation()); +#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING +::memset(reinterpret_cast<char*>(this) + static_cast<size_t>( + reinterpret_cast<char*>(&source_context_) - reinterpret_cast<char*>(this)), + 0, static_cast<size_t>(reinterpret_cast<char*>(&syntax_) - + reinterpret_cast<char*>(&source_context_)) + sizeof(syntax_)); +} + +Enum::~Enum() { + // @@protoc_insertion_point(destructor:google.protobuf.Enum) + if (GetArenaForAllocation() != nullptr) return; + SharedDtor(); + _internal_metadata_.Delete<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(); +} + +inline void Enum::SharedDtor() { + GOOGLE_DCHECK(GetArenaForAllocation() == nullptr); + name_.DestroyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); + if (this != internal_default_instance()) delete source_context_; +} + +void Enum::ArenaDtor(void* object) { + Enum* _this = reinterpret_cast< Enum* >(object); + (void)_this; +} +void Enum::RegisterArenaDtor(::PROTOBUF_NAMESPACE_ID::Arena*) { +} +void Enum::SetCachedSize(int size) const { + _cached_size_.Set(size); +} + +void Enum::Clear() { +// @@protoc_insertion_point(message_clear_start:google.protobuf.Enum) + arc_ui32 cached_has_bits = 0; + // Prevent compiler warnings about cached_has_bits being unused + (void) cached_has_bits; + + enumvalue_.Clear(); + options_.Clear(); + name_.ClearToEmpty(); + if (GetArenaForAllocation() == nullptr && source_context_ != nullptr) { + delete source_context_; + } + source_context_ = nullptr; + syntax_ = 0; + _internal_metadata_.Clear<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(); +} + +const char* Enum::_InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) { +#define CHK_(x) if (PROTOBUF_PREDICT_FALSE(!(x))) goto failure + while (!ctx->Done(&ptr)) { + arc_ui32 tag; + ptr = ::PROTOBUF_NAMESPACE_ID::internal::ReadTag(ptr, &tag); + switch (tag >> 3) { + // string name = 1; + case 1: + if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 10)) { + auto str = _internal_mutable_name(); + ptr = ::PROTOBUF_NAMESPACE_ID::internal::InlineGreedyStringParser(str, ptr, ctx); + CHK_(::PROTOBUF_NAMESPACE_ID::internal::VerifyUTF8(str, "google.protobuf.Enum.name")); + CHK_(ptr); + } else + goto handle_unusual; + continue; + // repeated .google.protobuf.EnumValue enumvalue = 2; + case 2: + if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 18)) { + ptr -= 1; + do { + ptr += 1; + ptr = ctx->ParseMessage(_internal_add_enumvalue(), ptr); + CHK_(ptr); + if (!ctx->DataAvailable(ptr)) break; + } while (::PROTOBUF_NAMESPACE_ID::internal::ExpectTag<18>(ptr)); + } else + goto handle_unusual; + continue; + // repeated .google.protobuf.Option options = 3; + case 3: + if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 26)) { + ptr -= 1; + do { + ptr += 1; + ptr = ctx->ParseMessage(_internal_add_options(), ptr); + CHK_(ptr); + if (!ctx->DataAvailable(ptr)) break; + } while (::PROTOBUF_NAMESPACE_ID::internal::ExpectTag<26>(ptr)); + } else + goto handle_unusual; + continue; + // .google.protobuf.SourceContext source_context = 4; + case 4: + if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 34)) { + ptr = ctx->ParseMessage(_internal_mutable_source_context(), ptr); + CHK_(ptr); + } else + goto handle_unusual; + continue; + // .google.protobuf.Syntax syntax = 5; + case 5: + if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 40)) { + arc_ui64 val = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint64(&ptr); + CHK_(ptr); + _internal_set_syntax(static_cast<::PROTOBUF_NAMESPACE_ID::Syntax>(val)); + } else + goto handle_unusual; + continue; + default: + goto handle_unusual; + } // switch + handle_unusual: + if ((tag == 0) || ((tag & 7) == 4)) { + CHK_(ptr); + ctx->SetLastTag(tag); + goto message_done; + } + ptr = UnknownFieldParse( + tag, + _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(), + ptr, ctx); + CHK_(ptr != nullptr); + } // while +message_done: + return ptr; +failure: + ptr = nullptr; + goto message_done; +#undef CHK_ +} + +uint8_t* Enum::_InternalSerialize( + uint8_t* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const { + // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.Enum) + arc_ui32 cached_has_bits = 0; + (void) cached_has_bits; + + // string name = 1; + if (!this->_internal_name().empty()) { + ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::VerifyUtf8String( + this->_internal_name().data(), static_cast<int>(this->_internal_name().length()), + ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::SERIALIZE, + "google.protobuf.Enum.name"); + target = stream->WriteStringMaybeAliased( + 1, this->_internal_name(), target); + } + + // repeated .google.protobuf.EnumValue enumvalue = 2; + for (unsigned int i = 0, + n = static_cast<unsigned int>(this->_internal_enumvalue_size()); i < n; i++) { + target = stream->EnsureSpace(target); + target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite:: + InternalWriteMessage(2, this->_internal_enumvalue(i), target, stream); + } + + // repeated .google.protobuf.Option options = 3; + for (unsigned int i = 0, + n = static_cast<unsigned int>(this->_internal_options_size()); i < n; i++) { + target = stream->EnsureSpace(target); + target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite:: + InternalWriteMessage(3, this->_internal_options(i), target, stream); + } + + // .google.protobuf.SourceContext source_context = 4; + if (this->_internal_has_source_context()) { + target = stream->EnsureSpace(target); + target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite:: + InternalWriteMessage( + 4, _Internal::source_context(this), target, stream); + } + + // .google.protobuf.Syntax syntax = 5; + if (this->_internal_syntax() != 0) { + target = stream->EnsureSpace(target); + target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteEnumToArray( + 5, this->_internal_syntax(), target); + } + + if (PROTOBUF_PREDICT_FALSE(_internal_metadata_.have_unknown_fields())) { + target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::InternalSerializeUnknownFieldsToArray( + _internal_metadata_.unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(::PROTOBUF_NAMESPACE_ID::UnknownFieldSet::default_instance), target, stream); + } + // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.Enum) + return target; +} + +size_t Enum::ByteSizeLong() const { +// @@protoc_insertion_point(message_byte_size_start:google.protobuf.Enum) + size_t total_size = 0; + + arc_ui32 cached_has_bits = 0; + // Prevent compiler warnings about cached_has_bits being unused + (void) cached_has_bits; + + // repeated .google.protobuf.EnumValue enumvalue = 2; + total_size += 1UL * this->_internal_enumvalue_size(); + for (const auto& msg : this->enumvalue_) { + total_size += + ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::MessageSize(msg); + } + + // repeated .google.protobuf.Option options = 3; + total_size += 1UL * this->_internal_options_size(); + for (const auto& msg : this->options_) { + total_size += + ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::MessageSize(msg); + } + + // string name = 1; + if (!this->_internal_name().empty()) { + total_size += 1 + + ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::StringSize( + this->_internal_name()); + } + + // .google.protobuf.SourceContext source_context = 4; + if (this->_internal_has_source_context()) { + total_size += 1 + + ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::MessageSize( + *source_context_); + } + + // .google.protobuf.Syntax syntax = 5; + if (this->_internal_syntax() != 0) { + total_size += 1 + + ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::EnumSize(this->_internal_syntax()); + } + + return MaybeComputeUnknownFieldsSize(total_size, &_cached_size_); +} + +const ::PROTOBUF_NAMESPACE_ID::Message::ClassData Enum::_class_data_ = { + ::PROTOBUF_NAMESPACE_ID::Message::CopyWithSizeCheck, + Enum::MergeImpl +}; +const ::PROTOBUF_NAMESPACE_ID::Message::ClassData*Enum::GetClassData() const { return &_class_data_; } + +void Enum::MergeImpl(::PROTOBUF_NAMESPACE_ID::Message* to, + const ::PROTOBUF_NAMESPACE_ID::Message& from) { + static_cast<Enum *>(to)->MergeFrom( + static_cast<const Enum &>(from)); +} + + +void Enum::MergeFrom(const Enum& from) { +// @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.Enum) + GOOGLE_DCHECK_NE(&from, this); + arc_ui32 cached_has_bits = 0; + (void) cached_has_bits; + + enumvalue_.MergeFrom(from.enumvalue_); + options_.MergeFrom(from.options_); + if (!from._internal_name().empty()) { + _internal_set_name(from._internal_name()); + } + if (from._internal_has_source_context()) { + _internal_mutable_source_context()->::PROTOBUF_NAMESPACE_ID::SourceContext::MergeFrom(from._internal_source_context()); + } + if (from._internal_syntax() != 0) { + _internal_set_syntax(from._internal_syntax()); + } + _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_); +} + +void Enum::CopyFrom(const Enum& from) { +// @@protoc_insertion_point(class_specific_copy_from_start:google.protobuf.Enum) + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool Enum::IsInitialized() const { + return true; +} + +void Enum::InternalSwap(Enum* other) { + using std::swap; + auto* lhs_arena = GetArenaForAllocation(); + auto* rhs_arena = other->GetArenaForAllocation(); + _internal_metadata_.InternalSwap(&other->_internal_metadata_); + enumvalue_.InternalSwap(&other->enumvalue_); + options_.InternalSwap(&other->options_); + ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::InternalSwap( + &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), + &name_, lhs_arena, + &other->name_, rhs_arena + ); + ::PROTOBUF_NAMESPACE_ID::internal::memswap< + PROTOBUF_FIELD_OFFSET(Enum, syntax_) + + sizeof(Enum::syntax_) + - PROTOBUF_FIELD_OFFSET(Enum, source_context_)>( + reinterpret_cast<char*>(&source_context_), + reinterpret_cast<char*>(&other->source_context_)); +} + +::PROTOBUF_NAMESPACE_ID::Metadata Enum::GetMetadata() const { + return ::PROTOBUF_NAMESPACE_ID::internal::AssignDescriptors( + &descriptor_table_google_2fprotobuf_2ftype_2eproto_getter, &descriptor_table_google_2fprotobuf_2ftype_2eproto_once, + file_level_metadata_google_2fprotobuf_2ftype_2eproto[2]); +} + +// =================================================================== + +class EnumValue::_Internal { + public: +}; + +EnumValue::EnumValue(::PROTOBUF_NAMESPACE_ID::Arena* arena, + bool is_message_owned) + : ::PROTOBUF_NAMESPACE_ID::Message(arena, is_message_owned), + options_(arena) { + SharedCtor(); + if (!is_message_owned) { + RegisterArenaDtor(arena); + } + // @@protoc_insertion_point(arena_constructor:google.protobuf.EnumValue) +} +EnumValue::EnumValue(const EnumValue& from) + : ::PROTOBUF_NAMESPACE_ID::Message(), + options_(from.options_) { + _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_); + name_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); + #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING + name_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation()); + #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING + if (!from._internal_name().empty()) { + name_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, from._internal_name(), + GetArenaForAllocation()); + } + number_ = from.number_; + // @@protoc_insertion_point(copy_constructor:google.protobuf.EnumValue) +} + +inline void EnumValue::SharedCtor() { +name_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); +#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING + name_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation()); +#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING +number_ = 0; +} + +EnumValue::~EnumValue() { + // @@protoc_insertion_point(destructor:google.protobuf.EnumValue) + if (GetArenaForAllocation() != nullptr) return; + SharedDtor(); + _internal_metadata_.Delete<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(); +} + +inline void EnumValue::SharedDtor() { + GOOGLE_DCHECK(GetArenaForAllocation() == nullptr); + name_.DestroyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); +} + +void EnumValue::ArenaDtor(void* object) { + EnumValue* _this = reinterpret_cast< EnumValue* >(object); + (void)_this; +} +void EnumValue::RegisterArenaDtor(::PROTOBUF_NAMESPACE_ID::Arena*) { +} +void EnumValue::SetCachedSize(int size) const { + _cached_size_.Set(size); +} + +void EnumValue::Clear() { +// @@protoc_insertion_point(message_clear_start:google.protobuf.EnumValue) + arc_ui32 cached_has_bits = 0; + // Prevent compiler warnings about cached_has_bits being unused + (void) cached_has_bits; + + options_.Clear(); + name_.ClearToEmpty(); + number_ = 0; + _internal_metadata_.Clear<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(); +} + +const char* EnumValue::_InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) { +#define CHK_(x) if (PROTOBUF_PREDICT_FALSE(!(x))) goto failure + while (!ctx->Done(&ptr)) { + arc_ui32 tag; + ptr = ::PROTOBUF_NAMESPACE_ID::internal::ReadTag(ptr, &tag); + switch (tag >> 3) { + // string name = 1; + case 1: + if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 10)) { + auto str = _internal_mutable_name(); + ptr = ::PROTOBUF_NAMESPACE_ID::internal::InlineGreedyStringParser(str, ptr, ctx); + CHK_(::PROTOBUF_NAMESPACE_ID::internal::VerifyUTF8(str, "google.protobuf.EnumValue.name")); + CHK_(ptr); + } else + goto handle_unusual; + continue; + // int32 number = 2; + case 2: + if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 16)) { + number_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint32(&ptr); + CHK_(ptr); + } else + goto handle_unusual; + continue; + // repeated .google.protobuf.Option options = 3; + case 3: + if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 26)) { + ptr -= 1; + do { + ptr += 1; + ptr = ctx->ParseMessage(_internal_add_options(), ptr); + CHK_(ptr); + if (!ctx->DataAvailable(ptr)) break; + } while (::PROTOBUF_NAMESPACE_ID::internal::ExpectTag<26>(ptr)); + } else + goto handle_unusual; + continue; + default: + goto handle_unusual; + } // switch + handle_unusual: + if ((tag == 0) || ((tag & 7) == 4)) { + CHK_(ptr); + ctx->SetLastTag(tag); + goto message_done; + } + ptr = UnknownFieldParse( + tag, + _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(), + ptr, ctx); + CHK_(ptr != nullptr); + } // while +message_done: + return ptr; +failure: + ptr = nullptr; + goto message_done; +#undef CHK_ +} + +uint8_t* EnumValue::_InternalSerialize( + uint8_t* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const { + // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.EnumValue) + arc_ui32 cached_has_bits = 0; + (void) cached_has_bits; + + // string name = 1; + if (!this->_internal_name().empty()) { + ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::VerifyUtf8String( + this->_internal_name().data(), static_cast<int>(this->_internal_name().length()), + ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::SERIALIZE, + "google.protobuf.EnumValue.name"); + target = stream->WriteStringMaybeAliased( + 1, this->_internal_name(), target); + } + + // int32 number = 2; + if (this->_internal_number() != 0) { + target = stream->EnsureSpace(target); + target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteInt32ToArray(2, this->_internal_number(), target); + } + + // repeated .google.protobuf.Option options = 3; + for (unsigned int i = 0, + n = static_cast<unsigned int>(this->_internal_options_size()); i < n; i++) { + target = stream->EnsureSpace(target); + target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite:: + InternalWriteMessage(3, this->_internal_options(i), target, stream); + } + + if (PROTOBUF_PREDICT_FALSE(_internal_metadata_.have_unknown_fields())) { + target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::InternalSerializeUnknownFieldsToArray( + _internal_metadata_.unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(::PROTOBUF_NAMESPACE_ID::UnknownFieldSet::default_instance), target, stream); + } + // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.EnumValue) + return target; +} + +size_t EnumValue::ByteSizeLong() const { +// @@protoc_insertion_point(message_byte_size_start:google.protobuf.EnumValue) + size_t total_size = 0; + + arc_ui32 cached_has_bits = 0; + // Prevent compiler warnings about cached_has_bits being unused + (void) cached_has_bits; + + // repeated .google.protobuf.Option options = 3; + total_size += 1UL * this->_internal_options_size(); + for (const auto& msg : this->options_) { + total_size += + ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::MessageSize(msg); + } + + // string name = 1; + if (!this->_internal_name().empty()) { + total_size += 1 + + ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::StringSize( + this->_internal_name()); + } + + // int32 number = 2; + if (this->_internal_number() != 0) { + total_size += ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::Int32SizePlusOne(this->_internal_number()); + } + + return MaybeComputeUnknownFieldsSize(total_size, &_cached_size_); +} + +const ::PROTOBUF_NAMESPACE_ID::Message::ClassData EnumValue::_class_data_ = { + ::PROTOBUF_NAMESPACE_ID::Message::CopyWithSizeCheck, + EnumValue::MergeImpl +}; +const ::PROTOBUF_NAMESPACE_ID::Message::ClassData*EnumValue::GetClassData() const { return &_class_data_; } + +void EnumValue::MergeImpl(::PROTOBUF_NAMESPACE_ID::Message* to, + const ::PROTOBUF_NAMESPACE_ID::Message& from) { + static_cast<EnumValue *>(to)->MergeFrom( + static_cast<const EnumValue &>(from)); +} + + +void EnumValue::MergeFrom(const EnumValue& from) { +// @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.EnumValue) + GOOGLE_DCHECK_NE(&from, this); + arc_ui32 cached_has_bits = 0; + (void) cached_has_bits; + + options_.MergeFrom(from.options_); + if (!from._internal_name().empty()) { + _internal_set_name(from._internal_name()); + } + if (from._internal_number() != 0) { + _internal_set_number(from._internal_number()); + } + _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_); +} + +void EnumValue::CopyFrom(const EnumValue& from) { +// @@protoc_insertion_point(class_specific_copy_from_start:google.protobuf.EnumValue) + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool EnumValue::IsInitialized() const { + return true; +} + +void EnumValue::InternalSwap(EnumValue* other) { + using std::swap; + auto* lhs_arena = GetArenaForAllocation(); + auto* rhs_arena = other->GetArenaForAllocation(); + _internal_metadata_.InternalSwap(&other->_internal_metadata_); + options_.InternalSwap(&other->options_); + ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::InternalSwap( + &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), + &name_, lhs_arena, + &other->name_, rhs_arena + ); + swap(number_, other->number_); +} + +::PROTOBUF_NAMESPACE_ID::Metadata EnumValue::GetMetadata() const { + return ::PROTOBUF_NAMESPACE_ID::internal::AssignDescriptors( + &descriptor_table_google_2fprotobuf_2ftype_2eproto_getter, &descriptor_table_google_2fprotobuf_2ftype_2eproto_once, + file_level_metadata_google_2fprotobuf_2ftype_2eproto[3]); +} + +// =================================================================== + +class Option::_Internal { + public: + static const ::PROTOBUF_NAMESPACE_ID::Any& value(const Option* msg); +}; + +const ::PROTOBUF_NAMESPACE_ID::Any& +Option::_Internal::value(const Option* msg) { + return *msg->value_; +} +void Option::clear_value() { + if (GetArenaForAllocation() == nullptr && value_ != nullptr) { + delete value_; + } + value_ = nullptr; +} +Option::Option(::PROTOBUF_NAMESPACE_ID::Arena* arena, + bool is_message_owned) + : ::PROTOBUF_NAMESPACE_ID::Message(arena, is_message_owned) { + SharedCtor(); + if (!is_message_owned) { + RegisterArenaDtor(arena); + } + // @@protoc_insertion_point(arena_constructor:google.protobuf.Option) +} +Option::Option(const Option& from) + : ::PROTOBUF_NAMESPACE_ID::Message() { + _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_); + name_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); + #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING + name_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation()); + #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING + if (!from._internal_name().empty()) { + name_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, from._internal_name(), + GetArenaForAllocation()); + } + if (from._internal_has_value()) { + value_ = new ::PROTOBUF_NAMESPACE_ID::Any(*from.value_); + } else { + value_ = nullptr; + } + // @@protoc_insertion_point(copy_constructor:google.protobuf.Option) +} + +inline void Option::SharedCtor() { +name_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); +#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING + name_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation()); +#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING +value_ = nullptr; +} + +Option::~Option() { + // @@protoc_insertion_point(destructor:google.protobuf.Option) + if (GetArenaForAllocation() != nullptr) return; + SharedDtor(); + _internal_metadata_.Delete<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(); +} + +inline void Option::SharedDtor() { + GOOGLE_DCHECK(GetArenaForAllocation() == nullptr); + name_.DestroyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); + if (this != internal_default_instance()) delete value_; +} + +void Option::ArenaDtor(void* object) { + Option* _this = reinterpret_cast< Option* >(object); + (void)_this; +} +void Option::RegisterArenaDtor(::PROTOBUF_NAMESPACE_ID::Arena*) { +} +void Option::SetCachedSize(int size) const { + _cached_size_.Set(size); +} + +void Option::Clear() { +// @@protoc_insertion_point(message_clear_start:google.protobuf.Option) + arc_ui32 cached_has_bits = 0; + // Prevent compiler warnings about cached_has_bits being unused + (void) cached_has_bits; + + name_.ClearToEmpty(); + if (GetArenaForAllocation() == nullptr && value_ != nullptr) { + delete value_; + } + value_ = nullptr; + _internal_metadata_.Clear<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(); +} + +const char* Option::_InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) { +#define CHK_(x) if (PROTOBUF_PREDICT_FALSE(!(x))) goto failure + while (!ctx->Done(&ptr)) { + arc_ui32 tag; + ptr = ::PROTOBUF_NAMESPACE_ID::internal::ReadTag(ptr, &tag); + switch (tag >> 3) { + // string name = 1; + case 1: + if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 10)) { + auto str = _internal_mutable_name(); + ptr = ::PROTOBUF_NAMESPACE_ID::internal::InlineGreedyStringParser(str, ptr, ctx); + CHK_(::PROTOBUF_NAMESPACE_ID::internal::VerifyUTF8(str, "google.protobuf.Option.name")); + CHK_(ptr); + } else + goto handle_unusual; + continue; + // .google.protobuf.Any value = 2; + case 2: + if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 18)) { + ptr = ctx->ParseMessage(_internal_mutable_value(), ptr); + CHK_(ptr); + } else + goto handle_unusual; + continue; + default: + goto handle_unusual; + } // switch + handle_unusual: + if ((tag == 0) || ((tag & 7) == 4)) { + CHK_(ptr); + ctx->SetLastTag(tag); + goto message_done; + } + ptr = UnknownFieldParse( + tag, + _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(), + ptr, ctx); + CHK_(ptr != nullptr); + } // while +message_done: + return ptr; +failure: + ptr = nullptr; + goto message_done; +#undef CHK_ +} + +uint8_t* Option::_InternalSerialize( + uint8_t* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const { + // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.Option) + arc_ui32 cached_has_bits = 0; + (void) cached_has_bits; + + // string name = 1; + if (!this->_internal_name().empty()) { + ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::VerifyUtf8String( + this->_internal_name().data(), static_cast<int>(this->_internal_name().length()), + ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::SERIALIZE, + "google.protobuf.Option.name"); + target = stream->WriteStringMaybeAliased( + 1, this->_internal_name(), target); + } + + // .google.protobuf.Any value = 2; + if (this->_internal_has_value()) { + target = stream->EnsureSpace(target); + target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite:: + InternalWriteMessage( + 2, _Internal::value(this), target, stream); + } + + if (PROTOBUF_PREDICT_FALSE(_internal_metadata_.have_unknown_fields())) { + target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::InternalSerializeUnknownFieldsToArray( + _internal_metadata_.unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(::PROTOBUF_NAMESPACE_ID::UnknownFieldSet::default_instance), target, stream); + } + // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.Option) + return target; +} + +size_t Option::ByteSizeLong() const { +// @@protoc_insertion_point(message_byte_size_start:google.protobuf.Option) + size_t total_size = 0; + + arc_ui32 cached_has_bits = 0; + // Prevent compiler warnings about cached_has_bits being unused + (void) cached_has_bits; + + // string name = 1; + if (!this->_internal_name().empty()) { + total_size += 1 + + ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::StringSize( + this->_internal_name()); + } + + // .google.protobuf.Any value = 2; + if (this->_internal_has_value()) { + total_size += 1 + + ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::MessageSize( + *value_); + } + + return MaybeComputeUnknownFieldsSize(total_size, &_cached_size_); +} + +const ::PROTOBUF_NAMESPACE_ID::Message::ClassData Option::_class_data_ = { + ::PROTOBUF_NAMESPACE_ID::Message::CopyWithSizeCheck, + Option::MergeImpl +}; +const ::PROTOBUF_NAMESPACE_ID::Message::ClassData*Option::GetClassData() const { return &_class_data_; } + +void Option::MergeImpl(::PROTOBUF_NAMESPACE_ID::Message* to, + const ::PROTOBUF_NAMESPACE_ID::Message& from) { + static_cast<Option *>(to)->MergeFrom( + static_cast<const Option &>(from)); +} + + +void Option::MergeFrom(const Option& from) { +// @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.Option) + GOOGLE_DCHECK_NE(&from, this); + arc_ui32 cached_has_bits = 0; + (void) cached_has_bits; + + if (!from._internal_name().empty()) { + _internal_set_name(from._internal_name()); + } + if (from._internal_has_value()) { + _internal_mutable_value()->::PROTOBUF_NAMESPACE_ID::Any::MergeFrom(from._internal_value()); + } + _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_); +} + +void Option::CopyFrom(const Option& from) { +// @@protoc_insertion_point(class_specific_copy_from_start:google.protobuf.Option) + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool Option::IsInitialized() const { + return true; +} + +void Option::InternalSwap(Option* other) { + using std::swap; + auto* lhs_arena = GetArenaForAllocation(); + auto* rhs_arena = other->GetArenaForAllocation(); + _internal_metadata_.InternalSwap(&other->_internal_metadata_); + ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::InternalSwap( + &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), + &name_, lhs_arena, + &other->name_, rhs_arena + ); + swap(value_, other->value_); +} + +::PROTOBUF_NAMESPACE_ID::Metadata Option::GetMetadata() const { + return ::PROTOBUF_NAMESPACE_ID::internal::AssignDescriptors( + &descriptor_table_google_2fprotobuf_2ftype_2eproto_getter, &descriptor_table_google_2fprotobuf_2ftype_2eproto_once, + file_level_metadata_google_2fprotobuf_2ftype_2eproto[4]); +} + +// @@protoc_insertion_point(namespace_scope) +PROTOBUF_NAMESPACE_CLOSE +PROTOBUF_NAMESPACE_OPEN +template<> PROTOBUF_NOINLINE ::PROTOBUF_NAMESPACE_ID::Type* Arena::CreateMaybeMessage< ::PROTOBUF_NAMESPACE_ID::Type >(Arena* arena) { + return Arena::CreateMessageInternal< ::PROTOBUF_NAMESPACE_ID::Type >(arena); +} +template<> PROTOBUF_NOINLINE ::PROTOBUF_NAMESPACE_ID::Field* Arena::CreateMaybeMessage< ::PROTOBUF_NAMESPACE_ID::Field >(Arena* arena) { + return Arena::CreateMessageInternal< ::PROTOBUF_NAMESPACE_ID::Field >(arena); +} +template<> PROTOBUF_NOINLINE ::PROTOBUF_NAMESPACE_ID::Enum* Arena::CreateMaybeMessage< ::PROTOBUF_NAMESPACE_ID::Enum >(Arena* arena) { + return Arena::CreateMessageInternal< ::PROTOBUF_NAMESPACE_ID::Enum >(arena); +} +template<> PROTOBUF_NOINLINE ::PROTOBUF_NAMESPACE_ID::EnumValue* Arena::CreateMaybeMessage< ::PROTOBUF_NAMESPACE_ID::EnumValue >(Arena* arena) { + return Arena::CreateMessageInternal< ::PROTOBUF_NAMESPACE_ID::EnumValue >(arena); +} +template<> PROTOBUF_NOINLINE ::PROTOBUF_NAMESPACE_ID::Option* Arena::CreateMaybeMessage< ::PROTOBUF_NAMESPACE_ID::Option >(Arena* arena) { + return Arena::CreateMessageInternal< ::PROTOBUF_NAMESPACE_ID::Option >(arena); +} +PROTOBUF_NAMESPACE_CLOSE + +// @@protoc_insertion_point(global_scope) +#include <google/protobuf/port_undef.inc> diff --git a/contrib/libs/protobuf_old/src/google/protobuf/type.pb.h b/contrib/libs/protobuf_old/src/google/protobuf/type.pb.h new file mode 100644 index 0000000000..c3d703ba40 --- /dev/null +++ b/contrib/libs/protobuf_old/src/google/protobuf/type.pb.h @@ -0,0 +1,2581 @@ +// Generated by the protocol buffer compiler. DO NOT EDIT! +// source: google/protobuf/type.proto + +#ifndef GOOGLE_PROTOBUF_INCLUDED_google_2fprotobuf_2ftype_2eproto +#define GOOGLE_PROTOBUF_INCLUDED_google_2fprotobuf_2ftype_2eproto + +#include <limits> +#include <string> + +#include <google/protobuf/port_def.inc> +#if PROTOBUF_VERSION < 3019000 +#error This file was generated by a newer version of protoc which is +#error incompatible with your Protocol Buffer headers. Please update +#error your headers. +#endif +#if 3019000 < PROTOBUF_MIN_PROTOC_VERSION +#error This file was generated by an older version of protoc which is +#error incompatible with your Protocol Buffer headers. Please +#error regenerate this file with a newer version of protoc. +#endif + +#include <google/protobuf/port_undef.inc> +#include <google/protobuf/io/coded_stream.h> +#include <google/protobuf/arena.h> +#include <google/protobuf/arenastring.h> +#include <google/protobuf/generated_message_table_driven.h> +#include <google/protobuf/generated_message_util.h> +#include <google/protobuf/metadata_lite.h> +#include <google/protobuf/generated_message_reflection.h> +#include <google/protobuf/message.h> +#include <google/protobuf/repeated_field.h> // IWYU pragma: export +#include <google/protobuf/extension_set.h> // IWYU pragma: export +#include <google/protobuf/generated_enum_reflection.h> +#include <google/protobuf/unknown_field_set.h> +#include <google/protobuf/any.pb.h> +#include <google/protobuf/source_context.pb.h> +// @@protoc_insertion_point(includes) +#include <google/protobuf/port_def.inc> +#define PROTOBUF_INTERNAL_EXPORT_google_2fprotobuf_2ftype_2eproto PROTOBUF_EXPORT +PROTOBUF_NAMESPACE_OPEN +namespace internal { +class AnyMetadata; +} // namespace internal +PROTOBUF_NAMESPACE_CLOSE + +// Internal implementation detail -- do not use these members. +struct PROTOBUF_EXPORT TableStruct_google_2fprotobuf_2ftype_2eproto { + static const ::PROTOBUF_NAMESPACE_ID::internal::ParseTableField entries[] + PROTOBUF_SECTION_VARIABLE(protodesc_cold); + static const ::PROTOBUF_NAMESPACE_ID::internal::AuxiliaryParseTableField aux[] + PROTOBUF_SECTION_VARIABLE(protodesc_cold); + static const ::PROTOBUF_NAMESPACE_ID::internal::ParseTable schema[5] + PROTOBUF_SECTION_VARIABLE(protodesc_cold); + static const ::PROTOBUF_NAMESPACE_ID::internal::FieldMetadata field_metadata[]; + static const ::PROTOBUF_NAMESPACE_ID::internal::SerializationTable serialization_table[]; + static const arc_ui32 offsets[]; +}; +PROTOBUF_EXPORT extern const ::PROTOBUF_NAMESPACE_ID::internal::DescriptorTable descriptor_table_google_2fprotobuf_2ftype_2eproto; +PROTOBUF_NAMESPACE_OPEN +class Enum; +struct EnumDefaultTypeInternal; +PROTOBUF_EXPORT extern EnumDefaultTypeInternal _Enum_default_instance_; +class EnumValue; +struct EnumValueDefaultTypeInternal; +PROTOBUF_EXPORT extern EnumValueDefaultTypeInternal _EnumValue_default_instance_; +class Field; +struct FieldDefaultTypeInternal; +PROTOBUF_EXPORT extern FieldDefaultTypeInternal _Field_default_instance_; +class Option; +struct OptionDefaultTypeInternal; +PROTOBUF_EXPORT extern OptionDefaultTypeInternal _Option_default_instance_; +class Type; +struct TypeDefaultTypeInternal; +PROTOBUF_EXPORT extern TypeDefaultTypeInternal _Type_default_instance_; +PROTOBUF_NAMESPACE_CLOSE +PROTOBUF_NAMESPACE_OPEN +template<> PROTOBUF_EXPORT ::PROTOBUF_NAMESPACE_ID::Enum* Arena::CreateMaybeMessage<::PROTOBUF_NAMESPACE_ID::Enum>(Arena*); +template<> PROTOBUF_EXPORT ::PROTOBUF_NAMESPACE_ID::EnumValue* Arena::CreateMaybeMessage<::PROTOBUF_NAMESPACE_ID::EnumValue>(Arena*); +template<> PROTOBUF_EXPORT ::PROTOBUF_NAMESPACE_ID::Field* Arena::CreateMaybeMessage<::PROTOBUF_NAMESPACE_ID::Field>(Arena*); +template<> PROTOBUF_EXPORT ::PROTOBUF_NAMESPACE_ID::Option* Arena::CreateMaybeMessage<::PROTOBUF_NAMESPACE_ID::Option>(Arena*); +template<> PROTOBUF_EXPORT ::PROTOBUF_NAMESPACE_ID::Type* Arena::CreateMaybeMessage<::PROTOBUF_NAMESPACE_ID::Type>(Arena*); +PROTOBUF_NAMESPACE_CLOSE +PROTOBUF_NAMESPACE_OPEN + +enum Field_Kind : int { + Field_Kind_TYPE_UNKNOWN = 0, + Field_Kind_TYPE_DOUBLE = 1, + Field_Kind_TYPE_FLOAT = 2, + Field_Kind_TYPE_INT64 = 3, + Field_Kind_TYPE_UINT64 = 4, + Field_Kind_TYPE_INT32 = 5, + Field_Kind_TYPE_FIXED64 = 6, + Field_Kind_TYPE_FIXED32 = 7, + Field_Kind_TYPE_BOOL = 8, + Field_Kind_TYPE_STRING = 9, + Field_Kind_TYPE_GROUP = 10, + Field_Kind_TYPE_MESSAGE = 11, + Field_Kind_TYPE_BYTES = 12, + Field_Kind_TYPE_UINT32 = 13, + Field_Kind_TYPE_ENUM = 14, + Field_Kind_TYPE_SFIXED32 = 15, + Field_Kind_TYPE_SFIXED64 = 16, + Field_Kind_TYPE_SINT32 = 17, + Field_Kind_TYPE_SINT64 = 18, + Field_Kind_Field_Kind_INT_MIN_SENTINEL_DO_NOT_USE_ = std::numeric_limits<arc_i32>::min(), + Field_Kind_Field_Kind_INT_MAX_SENTINEL_DO_NOT_USE_ = std::numeric_limits<arc_i32>::max() +}; +PROTOBUF_EXPORT bool Field_Kind_IsValid(int value); +constexpr Field_Kind Field_Kind_Kind_MIN = Field_Kind_TYPE_UNKNOWN; +constexpr Field_Kind Field_Kind_Kind_MAX = Field_Kind_TYPE_SINT64; +constexpr int Field_Kind_Kind_ARRAYSIZE = Field_Kind_Kind_MAX + 1; + +PROTOBUF_EXPORT const ::PROTOBUF_NAMESPACE_ID::EnumDescriptor* Field_Kind_descriptor(); +template<typename T> +inline const TProtoStringType& Field_Kind_Name(T enum_t_value) { + static_assert(::std::is_same<T, Field_Kind>::value || + ::std::is_integral<T>::value, + "Incorrect type passed to function Field_Kind_Name."); + return ::PROTOBUF_NAMESPACE_ID::internal::NameOfEnum( + Field_Kind_descriptor(), enum_t_value); +} +inline bool Field_Kind_Parse( + ::PROTOBUF_NAMESPACE_ID::ConstStringParam name, Field_Kind* value) { + return ::PROTOBUF_NAMESPACE_ID::internal::ParseNamedEnum<Field_Kind>( + Field_Kind_descriptor(), name, value); +} +enum Field_Cardinality : int { + Field_Cardinality_CARDINALITY_UNKNOWN = 0, + Field_Cardinality_CARDINALITY_OPTIONAL = 1, + Field_Cardinality_CARDINALITY_REQUIRED = 2, + Field_Cardinality_CARDINALITY_REPEATED = 3, + Field_Cardinality_Field_Cardinality_INT_MIN_SENTINEL_DO_NOT_USE_ = std::numeric_limits<arc_i32>::min(), + Field_Cardinality_Field_Cardinality_INT_MAX_SENTINEL_DO_NOT_USE_ = std::numeric_limits<arc_i32>::max() +}; +PROTOBUF_EXPORT bool Field_Cardinality_IsValid(int value); +constexpr Field_Cardinality Field_Cardinality_Cardinality_MIN = Field_Cardinality_CARDINALITY_UNKNOWN; +constexpr Field_Cardinality Field_Cardinality_Cardinality_MAX = Field_Cardinality_CARDINALITY_REPEATED; +constexpr int Field_Cardinality_Cardinality_ARRAYSIZE = Field_Cardinality_Cardinality_MAX + 1; + +PROTOBUF_EXPORT const ::PROTOBUF_NAMESPACE_ID::EnumDescriptor* Field_Cardinality_descriptor(); +template<typename T> +inline const TProtoStringType& Field_Cardinality_Name(T enum_t_value) { + static_assert(::std::is_same<T, Field_Cardinality>::value || + ::std::is_integral<T>::value, + "Incorrect type passed to function Field_Cardinality_Name."); + return ::PROTOBUF_NAMESPACE_ID::internal::NameOfEnum( + Field_Cardinality_descriptor(), enum_t_value); +} +inline bool Field_Cardinality_Parse( + ::PROTOBUF_NAMESPACE_ID::ConstStringParam name, Field_Cardinality* value) { + return ::PROTOBUF_NAMESPACE_ID::internal::ParseNamedEnum<Field_Cardinality>( + Field_Cardinality_descriptor(), name, value); +} +enum Syntax : int { + SYNTAX_PROTO2 = 0, + SYNTAX_PROTO3 = 1, + Syntax_INT_MIN_SENTINEL_DO_NOT_USE_ = std::numeric_limits<arc_i32>::min(), + Syntax_INT_MAX_SENTINEL_DO_NOT_USE_ = std::numeric_limits<arc_i32>::max() +}; +PROTOBUF_EXPORT bool Syntax_IsValid(int value); +constexpr Syntax Syntax_MIN = SYNTAX_PROTO2; +constexpr Syntax Syntax_MAX = SYNTAX_PROTO3; +constexpr int Syntax_ARRAYSIZE = Syntax_MAX + 1; + +PROTOBUF_EXPORT const ::PROTOBUF_NAMESPACE_ID::EnumDescriptor* Syntax_descriptor(); +template<typename T> +inline const TProtoStringType& Syntax_Name(T enum_t_value) { + static_assert(::std::is_same<T, Syntax>::value || + ::std::is_integral<T>::value, + "Incorrect type passed to function Syntax_Name."); + return ::PROTOBUF_NAMESPACE_ID::internal::NameOfEnum( + Syntax_descriptor(), enum_t_value); +} +inline bool Syntax_Parse( + ::PROTOBUF_NAMESPACE_ID::ConstStringParam name, Syntax* value) { + return ::PROTOBUF_NAMESPACE_ID::internal::ParseNamedEnum<Syntax>( + Syntax_descriptor(), name, value); +} +// =================================================================== + +class PROTOBUF_EXPORT Type final : + public ::PROTOBUF_NAMESPACE_ID::Message /* @@protoc_insertion_point(class_definition:google.protobuf.Type) */ { + public: + inline Type() : Type(nullptr) {} + ~Type() override; + explicit constexpr Type(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized); + + Type(const Type& from); + Type(Type&& from) noexcept + : Type() { + *this = ::std::move(from); + } + + inline Type& operator=(const Type& from) { + CopyFrom(from); + return *this; + } + inline Type& operator=(Type&& from) noexcept { + if (this == &from) return *this; + if (GetOwningArena() == from.GetOwningArena() + #ifdef PROTOBUF_FORCE_COPY_IN_MOVE + && GetOwningArena() != nullptr + #endif // !PROTOBUF_FORCE_COPY_IN_MOVE + ) { + InternalSwap(&from); + } else { + CopyFrom(from); + } + return *this; + } + + static const ::PROTOBUF_NAMESPACE_ID::Descriptor* descriptor() { + return GetDescriptor(); + } + static const ::PROTOBUF_NAMESPACE_ID::Descriptor* GetDescriptor() { + return default_instance().GetMetadata().descriptor; + } + static const ::PROTOBUF_NAMESPACE_ID::Reflection* GetReflection() { + return default_instance().GetMetadata().reflection; + } + static const Type& default_instance() { + return *internal_default_instance(); + } + static inline const Type* internal_default_instance() { + return reinterpret_cast<const Type*>( + &_Type_default_instance_); + } + static constexpr int kIndexInFileMessages = + 0; + + friend void swap(Type& a, Type& b) { + a.Swap(&b); + } + inline void Swap(Type* other) { + if (other == this) return; + #ifdef PROTOBUF_FORCE_COPY_IN_SWAP + if (GetOwningArena() != nullptr && + GetOwningArena() == other->GetOwningArena()) { + #else // PROTOBUF_FORCE_COPY_IN_SWAP + if (GetOwningArena() == other->GetOwningArena()) { + #endif // !PROTOBUF_FORCE_COPY_IN_SWAP + InternalSwap(other); + } else { + ::PROTOBUF_NAMESPACE_ID::internal::GenericSwap(this, other); + } + } + void UnsafeArenaSwap(Type* other) { + if (other == this) return; + GOOGLE_DCHECK(GetOwningArena() == other->GetOwningArena()); + InternalSwap(other); + } + + // implements Message ---------------------------------------------- + + Type* New(::PROTOBUF_NAMESPACE_ID::Arena* arena = nullptr) const final { + return CreateMaybeMessage<Type>(arena); + } + using ::PROTOBUF_NAMESPACE_ID::Message::CopyFrom; + void CopyFrom(const Type& from); + using ::PROTOBUF_NAMESPACE_ID::Message::MergeFrom; + void MergeFrom(const Type& 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; + + size_t ByteSizeLong() const final; + const char* _InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) final; + uint8_t* _InternalSerialize( + uint8_t* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const final; + int GetCachedSize() const final { return _cached_size_.Get(); } + + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const final; + void InternalSwap(Type* other); + + private: + friend class ::PROTOBUF_NAMESPACE_ID::internal::AnyMetadata; + static ::PROTOBUF_NAMESPACE_ID::StringPiece FullMessageName() { + return "google.protobuf.Type"; + } + protected: + explicit Type(::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 ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + enum : int { + kFieldsFieldNumber = 2, + kOneofsFieldNumber = 3, + kOptionsFieldNumber = 4, + kNameFieldNumber = 1, + kSourceContextFieldNumber = 5, + kSyntaxFieldNumber = 6, + }; + // repeated .google.protobuf.Field fields = 2; + int fields_size() const; + private: + int _internal_fields_size() const; + public: + void clear_fields(); + ::PROTOBUF_NAMESPACE_ID::Field* mutable_fields(int index); + ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::Field >* + mutable_fields(); + private: + const ::PROTOBUF_NAMESPACE_ID::Field& _internal_fields(int index) const; + ::PROTOBUF_NAMESPACE_ID::Field* _internal_add_fields(); + public: + const ::PROTOBUF_NAMESPACE_ID::Field& fields(int index) const; + ::PROTOBUF_NAMESPACE_ID::Field* add_fields(); + const ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::Field >& + fields() const; + + // repeated string oneofs = 3; + int oneofs_size() const; + private: + int _internal_oneofs_size() const; + public: + void clear_oneofs(); + const TProtoStringType& oneofs(int index) const; + TProtoStringType* mutable_oneofs(int index); + void set_oneofs(int index, const TProtoStringType& value); + void set_oneofs(int index, TProtoStringType&& value); + void set_oneofs(int index, const char* value); + void set_oneofs(int index, const char* value, size_t size); + TProtoStringType* add_oneofs(); + void add_oneofs(const TProtoStringType& value); + void add_oneofs(TProtoStringType&& value); + void add_oneofs(const char* value); + void add_oneofs(const char* value, size_t size); + const ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField<TProtoStringType>& oneofs() const; + ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField<TProtoStringType>* mutable_oneofs(); + private: + const TProtoStringType& _internal_oneofs(int index) const; + TProtoStringType* _internal_add_oneofs(); + public: + + // repeated .google.protobuf.Option options = 4; + int options_size() const; + private: + int _internal_options_size() const; + public: + void clear_options(); + ::PROTOBUF_NAMESPACE_ID::Option* mutable_options(int index); + ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::Option >* + mutable_options(); + private: + const ::PROTOBUF_NAMESPACE_ID::Option& _internal_options(int index) const; + ::PROTOBUF_NAMESPACE_ID::Option* _internal_add_options(); + public: + const ::PROTOBUF_NAMESPACE_ID::Option& options(int index) const; + ::PROTOBUF_NAMESPACE_ID::Option* add_options(); + const ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::Option >& + options() const; + + // string name = 1; + void clear_name(); + const TProtoStringType& name() const; + template <typename ArgT0 = const TProtoStringType&, typename... ArgT> + void set_name(ArgT0&& arg0, ArgT... args); + TProtoStringType* mutable_name(); + PROTOBUF_NODISCARD TProtoStringType* release_name(); + void set_allocated_name(TProtoStringType* name); + private: + const TProtoStringType& _internal_name() const; + inline PROTOBUF_ALWAYS_INLINE void _internal_set_name(const TProtoStringType& value); + TProtoStringType* _internal_mutable_name(); + public: + + // .google.protobuf.SourceContext source_context = 5; + bool has_source_context() const; + private: + bool _internal_has_source_context() const; + public: + void clear_source_context(); + const ::PROTOBUF_NAMESPACE_ID::SourceContext& source_context() const; + PROTOBUF_NODISCARD ::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: + const ::PROTOBUF_NAMESPACE_ID::SourceContext& _internal_source_context() const; + ::PROTOBUF_NAMESPACE_ID::SourceContext* _internal_mutable_source_context(); + public: + void unsafe_arena_set_allocated_source_context( + ::PROTOBUF_NAMESPACE_ID::SourceContext* source_context); + ::PROTOBUF_NAMESPACE_ID::SourceContext* unsafe_arena_release_source_context(); + + // .google.protobuf.Syntax syntax = 6; + void clear_syntax(); + ::PROTOBUF_NAMESPACE_ID::Syntax syntax() const; + void set_syntax(::PROTOBUF_NAMESPACE_ID::Syntax value); + private: + ::PROTOBUF_NAMESPACE_ID::Syntax _internal_syntax() const; + void _internal_set_syntax(::PROTOBUF_NAMESPACE_ID::Syntax value); + public: + + // @@protoc_insertion_point(class_scope:google.protobuf.Type) + private: + class _Internal; + + template <typename T> friend class ::PROTOBUF_NAMESPACE_ID::Arena::InternalHelper; + typedef void InternalArenaConstructable_; + typedef void DestructorSkippable_; + ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::Field > fields_; + ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField<TProtoStringType> oneofs_; + ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::Option > options_; + ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr name_; + ::PROTOBUF_NAMESPACE_ID::SourceContext* source_context_; + int syntax_; + mutable ::PROTOBUF_NAMESPACE_ID::internal::CachedSize _cached_size_; + friend struct ::TableStruct_google_2fprotobuf_2ftype_2eproto; +}; +// ------------------------------------------------------------------- + +class PROTOBUF_EXPORT Field final : + public ::PROTOBUF_NAMESPACE_ID::Message /* @@protoc_insertion_point(class_definition:google.protobuf.Field) */ { + public: + inline Field() : Field(nullptr) {} + ~Field() override; + explicit constexpr Field(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized); + + Field(const Field& from); + Field(Field&& from) noexcept + : Field() { + *this = ::std::move(from); + } + + inline Field& operator=(const Field& from) { + CopyFrom(from); + return *this; + } + inline Field& operator=(Field&& from) noexcept { + if (this == &from) return *this; + if (GetOwningArena() == from.GetOwningArena() + #ifdef PROTOBUF_FORCE_COPY_IN_MOVE + && GetOwningArena() != nullptr + #endif // !PROTOBUF_FORCE_COPY_IN_MOVE + ) { + InternalSwap(&from); + } else { + CopyFrom(from); + } + return *this; + } + + static const ::PROTOBUF_NAMESPACE_ID::Descriptor* descriptor() { + return GetDescriptor(); + } + static const ::PROTOBUF_NAMESPACE_ID::Descriptor* GetDescriptor() { + return default_instance().GetMetadata().descriptor; + } + static const ::PROTOBUF_NAMESPACE_ID::Reflection* GetReflection() { + return default_instance().GetMetadata().reflection; + } + static const Field& default_instance() { + return *internal_default_instance(); + } + static inline const Field* internal_default_instance() { + return reinterpret_cast<const Field*>( + &_Field_default_instance_); + } + static constexpr int kIndexInFileMessages = + 1; + + friend void swap(Field& a, Field& b) { + a.Swap(&b); + } + inline void Swap(Field* other) { + if (other == this) return; + #ifdef PROTOBUF_FORCE_COPY_IN_SWAP + if (GetOwningArena() != nullptr && + GetOwningArena() == other->GetOwningArena()) { + #else // PROTOBUF_FORCE_COPY_IN_SWAP + if (GetOwningArena() == other->GetOwningArena()) { + #endif // !PROTOBUF_FORCE_COPY_IN_SWAP + InternalSwap(other); + } else { + ::PROTOBUF_NAMESPACE_ID::internal::GenericSwap(this, other); + } + } + void UnsafeArenaSwap(Field* other) { + if (other == this) return; + GOOGLE_DCHECK(GetOwningArena() == other->GetOwningArena()); + InternalSwap(other); + } + + // implements Message ---------------------------------------------- + + Field* New(::PROTOBUF_NAMESPACE_ID::Arena* arena = nullptr) const final { + return CreateMaybeMessage<Field>(arena); + } + using ::PROTOBUF_NAMESPACE_ID::Message::CopyFrom; + void CopyFrom(const Field& from); + using ::PROTOBUF_NAMESPACE_ID::Message::MergeFrom; + void MergeFrom(const Field& 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; + + size_t ByteSizeLong() const final; + const char* _InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) final; + uint8_t* _InternalSerialize( + uint8_t* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const final; + int GetCachedSize() const final { return _cached_size_.Get(); } + + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const final; + void InternalSwap(Field* other); + + private: + friend class ::PROTOBUF_NAMESPACE_ID::internal::AnyMetadata; + static ::PROTOBUF_NAMESPACE_ID::StringPiece FullMessageName() { + return "google.protobuf.Field"; + } + protected: + explicit Field(::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 ---------------------------------------------------- + + typedef Field_Kind Kind; + static constexpr Kind TYPE_UNKNOWN = + Field_Kind_TYPE_UNKNOWN; + static constexpr Kind TYPE_DOUBLE = + Field_Kind_TYPE_DOUBLE; + static constexpr Kind TYPE_FLOAT = + Field_Kind_TYPE_FLOAT; + static constexpr Kind TYPE_INT64 = + Field_Kind_TYPE_INT64; + static constexpr Kind TYPE_UINT64 = + Field_Kind_TYPE_UINT64; + static constexpr Kind TYPE_INT32 = + Field_Kind_TYPE_INT32; + static constexpr Kind TYPE_FIXED64 = + Field_Kind_TYPE_FIXED64; + static constexpr Kind TYPE_FIXED32 = + Field_Kind_TYPE_FIXED32; + static constexpr Kind TYPE_BOOL = + Field_Kind_TYPE_BOOL; + static constexpr Kind TYPE_STRING = + Field_Kind_TYPE_STRING; + static constexpr Kind TYPE_GROUP = + Field_Kind_TYPE_GROUP; + static constexpr Kind TYPE_MESSAGE = + Field_Kind_TYPE_MESSAGE; + static constexpr Kind TYPE_BYTES = + Field_Kind_TYPE_BYTES; + static constexpr Kind TYPE_UINT32 = + Field_Kind_TYPE_UINT32; + static constexpr Kind TYPE_ENUM = + Field_Kind_TYPE_ENUM; + static constexpr Kind TYPE_SFIXED32 = + Field_Kind_TYPE_SFIXED32; + static constexpr Kind TYPE_SFIXED64 = + Field_Kind_TYPE_SFIXED64; + static constexpr Kind TYPE_SINT32 = + Field_Kind_TYPE_SINT32; + static constexpr Kind TYPE_SINT64 = + Field_Kind_TYPE_SINT64; + static inline bool Kind_IsValid(int value) { + return Field_Kind_IsValid(value); + } + static constexpr Kind Kind_MIN = + Field_Kind_Kind_MIN; + static constexpr Kind Kind_MAX = + Field_Kind_Kind_MAX; + static constexpr int Kind_ARRAYSIZE = + Field_Kind_Kind_ARRAYSIZE; + static inline const ::PROTOBUF_NAMESPACE_ID::EnumDescriptor* + Kind_descriptor() { + return Field_Kind_descriptor(); + } + template<typename T> + static inline const TProtoStringType& Kind_Name(T enum_t_value) { + static_assert(::std::is_same<T, Kind>::value || + ::std::is_integral<T>::value, + "Incorrect type passed to function Kind_Name."); + return Field_Kind_Name(enum_t_value); + } + static inline bool Kind_Parse(::PROTOBUF_NAMESPACE_ID::ConstStringParam name, + Kind* value) { + return Field_Kind_Parse(name, value); + } + + typedef Field_Cardinality Cardinality; + static constexpr Cardinality CARDINALITY_UNKNOWN = + Field_Cardinality_CARDINALITY_UNKNOWN; + static constexpr Cardinality CARDINALITY_OPTIONAL = + Field_Cardinality_CARDINALITY_OPTIONAL; + static constexpr Cardinality CARDINALITY_REQUIRED = + Field_Cardinality_CARDINALITY_REQUIRED; + static constexpr Cardinality CARDINALITY_REPEATED = + Field_Cardinality_CARDINALITY_REPEATED; + static inline bool Cardinality_IsValid(int value) { + return Field_Cardinality_IsValid(value); + } + static constexpr Cardinality Cardinality_MIN = + Field_Cardinality_Cardinality_MIN; + static constexpr Cardinality Cardinality_MAX = + Field_Cardinality_Cardinality_MAX; + static constexpr int Cardinality_ARRAYSIZE = + Field_Cardinality_Cardinality_ARRAYSIZE; + static inline const ::PROTOBUF_NAMESPACE_ID::EnumDescriptor* + Cardinality_descriptor() { + return Field_Cardinality_descriptor(); + } + template<typename T> + static inline const TProtoStringType& Cardinality_Name(T enum_t_value) { + static_assert(::std::is_same<T, Cardinality>::value || + ::std::is_integral<T>::value, + "Incorrect type passed to function Cardinality_Name."); + return Field_Cardinality_Name(enum_t_value); + } + static inline bool Cardinality_Parse(::PROTOBUF_NAMESPACE_ID::ConstStringParam name, + Cardinality* value) { + return Field_Cardinality_Parse(name, value); + } + + // accessors ------------------------------------------------------- + + enum : int { + kOptionsFieldNumber = 9, + kNameFieldNumber = 4, + kTypeUrlFieldNumber = 6, + kJsonNameFieldNumber = 10, + kDefaultValueFieldNumber = 11, + kKindFieldNumber = 1, + kCardinalityFieldNumber = 2, + kNumberFieldNumber = 3, + kOneofIndexFieldNumber = 7, + kPackedFieldNumber = 8, + }; + // repeated .google.protobuf.Option options = 9; + int options_size() const; + private: + int _internal_options_size() const; + public: + void clear_options(); + ::PROTOBUF_NAMESPACE_ID::Option* mutable_options(int index); + ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::Option >* + mutable_options(); + private: + const ::PROTOBUF_NAMESPACE_ID::Option& _internal_options(int index) const; + ::PROTOBUF_NAMESPACE_ID::Option* _internal_add_options(); + public: + const ::PROTOBUF_NAMESPACE_ID::Option& options(int index) const; + ::PROTOBUF_NAMESPACE_ID::Option* add_options(); + const ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::Option >& + options() const; + + // string name = 4; + void clear_name(); + const TProtoStringType& name() const; + template <typename ArgT0 = const TProtoStringType&, typename... ArgT> + void set_name(ArgT0&& arg0, ArgT... args); + TProtoStringType* mutable_name(); + PROTOBUF_NODISCARD TProtoStringType* release_name(); + void set_allocated_name(TProtoStringType* name); + private: + const TProtoStringType& _internal_name() const; + inline PROTOBUF_ALWAYS_INLINE void _internal_set_name(const TProtoStringType& value); + TProtoStringType* _internal_mutable_name(); + public: + + // string type_url = 6; + void clear_type_url(); + const TProtoStringType& type_url() const; + template <typename ArgT0 = const TProtoStringType&, typename... ArgT> + void set_type_url(ArgT0&& arg0, ArgT... args); + TProtoStringType* mutable_type_url(); + PROTOBUF_NODISCARD TProtoStringType* release_type_url(); + void set_allocated_type_url(TProtoStringType* type_url); + private: + const TProtoStringType& _internal_type_url() const; + inline PROTOBUF_ALWAYS_INLINE void _internal_set_type_url(const TProtoStringType& value); + TProtoStringType* _internal_mutable_type_url(); + public: + + // string json_name = 10; + void clear_json_name(); + const TProtoStringType& json_name() const; + template <typename ArgT0 = const TProtoStringType&, typename... ArgT> + void set_json_name(ArgT0&& arg0, ArgT... args); + TProtoStringType* mutable_json_name(); + PROTOBUF_NODISCARD TProtoStringType* release_json_name(); + void set_allocated_json_name(TProtoStringType* json_name); + private: + const TProtoStringType& _internal_json_name() const; + inline PROTOBUF_ALWAYS_INLINE void _internal_set_json_name(const TProtoStringType& value); + TProtoStringType* _internal_mutable_json_name(); + public: + + // string default_value = 11; + void clear_default_value(); + const TProtoStringType& default_value() const; + template <typename ArgT0 = const TProtoStringType&, typename... ArgT> + void set_default_value(ArgT0&& arg0, ArgT... args); + TProtoStringType* mutable_default_value(); + PROTOBUF_NODISCARD TProtoStringType* release_default_value(); + void set_allocated_default_value(TProtoStringType* default_value); + private: + const TProtoStringType& _internal_default_value() const; + inline PROTOBUF_ALWAYS_INLINE void _internal_set_default_value(const TProtoStringType& value); + TProtoStringType* _internal_mutable_default_value(); + public: + + // .google.protobuf.Field.Kind kind = 1; + void clear_kind(); + ::PROTOBUF_NAMESPACE_ID::Field_Kind kind() const; + void set_kind(::PROTOBUF_NAMESPACE_ID::Field_Kind value); + private: + ::PROTOBUF_NAMESPACE_ID::Field_Kind _internal_kind() const; + void _internal_set_kind(::PROTOBUF_NAMESPACE_ID::Field_Kind value); + public: + + // .google.protobuf.Field.Cardinality cardinality = 2; + void clear_cardinality(); + ::PROTOBUF_NAMESPACE_ID::Field_Cardinality cardinality() const; + void set_cardinality(::PROTOBUF_NAMESPACE_ID::Field_Cardinality value); + private: + ::PROTOBUF_NAMESPACE_ID::Field_Cardinality _internal_cardinality() const; + void _internal_set_cardinality(::PROTOBUF_NAMESPACE_ID::Field_Cardinality value); + public: + + // int32 number = 3; + void clear_number(); + arc_i32 number() const; + void set_number(arc_i32 value); + private: + arc_i32 _internal_number() const; + void _internal_set_number(arc_i32 value); + public: + + // int32 oneof_index = 7; + void clear_oneof_index(); + arc_i32 oneof_index() const; + void set_oneof_index(arc_i32 value); + private: + arc_i32 _internal_oneof_index() const; + void _internal_set_oneof_index(arc_i32 value); + public: + + // bool packed = 8; + void clear_packed(); + bool packed() const; + void set_packed(bool value); + private: + bool _internal_packed() const; + void _internal_set_packed(bool value); + public: + + // @@protoc_insertion_point(class_scope:google.protobuf.Field) + private: + class _Internal; + + template <typename T> friend class ::PROTOBUF_NAMESPACE_ID::Arena::InternalHelper; + typedef void InternalArenaConstructable_; + typedef void DestructorSkippable_; + ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::Option > options_; + ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr name_; + ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr type_url_; + ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr json_name_; + ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr default_value_; + int kind_; + int cardinality_; + arc_i32 number_; + arc_i32 oneof_index_; + bool packed_; + mutable ::PROTOBUF_NAMESPACE_ID::internal::CachedSize _cached_size_; + friend struct ::TableStruct_google_2fprotobuf_2ftype_2eproto; +}; +// ------------------------------------------------------------------- + +class PROTOBUF_EXPORT Enum final : + public ::PROTOBUF_NAMESPACE_ID::Message /* @@protoc_insertion_point(class_definition:google.protobuf.Enum) */ { + public: + inline Enum() : Enum(nullptr) {} + ~Enum() override; + explicit constexpr Enum(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized); + + Enum(const Enum& from); + Enum(Enum&& from) noexcept + : Enum() { + *this = ::std::move(from); + } + + inline Enum& operator=(const Enum& from) { + CopyFrom(from); + return *this; + } + inline Enum& operator=(Enum&& from) noexcept { + if (this == &from) return *this; + if (GetOwningArena() == from.GetOwningArena() + #ifdef PROTOBUF_FORCE_COPY_IN_MOVE + && GetOwningArena() != nullptr + #endif // !PROTOBUF_FORCE_COPY_IN_MOVE + ) { + InternalSwap(&from); + } else { + CopyFrom(from); + } + return *this; + } + + static const ::PROTOBUF_NAMESPACE_ID::Descriptor* descriptor() { + return GetDescriptor(); + } + static const ::PROTOBUF_NAMESPACE_ID::Descriptor* GetDescriptor() { + return default_instance().GetMetadata().descriptor; + } + static const ::PROTOBUF_NAMESPACE_ID::Reflection* GetReflection() { + return default_instance().GetMetadata().reflection; + } + static const Enum& default_instance() { + return *internal_default_instance(); + } + static inline const Enum* internal_default_instance() { + return reinterpret_cast<const Enum*>( + &_Enum_default_instance_); + } + static constexpr int kIndexInFileMessages = + 2; + + friend void swap(Enum& a, Enum& b) { + a.Swap(&b); + } + inline void Swap(Enum* other) { + if (other == this) return; + #ifdef PROTOBUF_FORCE_COPY_IN_SWAP + if (GetOwningArena() != nullptr && + GetOwningArena() == other->GetOwningArena()) { + #else // PROTOBUF_FORCE_COPY_IN_SWAP + if (GetOwningArena() == other->GetOwningArena()) { + #endif // !PROTOBUF_FORCE_COPY_IN_SWAP + InternalSwap(other); + } else { + ::PROTOBUF_NAMESPACE_ID::internal::GenericSwap(this, other); + } + } + void UnsafeArenaSwap(Enum* other) { + if (other == this) return; + GOOGLE_DCHECK(GetOwningArena() == other->GetOwningArena()); + InternalSwap(other); + } + + // implements Message ---------------------------------------------- + + Enum* New(::PROTOBUF_NAMESPACE_ID::Arena* arena = nullptr) const final { + return CreateMaybeMessage<Enum>(arena); + } + using ::PROTOBUF_NAMESPACE_ID::Message::CopyFrom; + void CopyFrom(const Enum& from); + using ::PROTOBUF_NAMESPACE_ID::Message::MergeFrom; + void MergeFrom(const Enum& 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; + + size_t ByteSizeLong() const final; + const char* _InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) final; + uint8_t* _InternalSerialize( + uint8_t* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const final; + int GetCachedSize() const final { return _cached_size_.Get(); } + + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const final; + void InternalSwap(Enum* other); + + private: + friend class ::PROTOBUF_NAMESPACE_ID::internal::AnyMetadata; + static ::PROTOBUF_NAMESPACE_ID::StringPiece FullMessageName() { + return "google.protobuf.Enum"; + } + protected: + explicit Enum(::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 ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + enum : int { + kEnumvalueFieldNumber = 2, + kOptionsFieldNumber = 3, + kNameFieldNumber = 1, + kSourceContextFieldNumber = 4, + kSyntaxFieldNumber = 5, + }; + // repeated .google.protobuf.EnumValue enumvalue = 2; + int enumvalue_size() const; + private: + int _internal_enumvalue_size() const; + public: + void clear_enumvalue(); + ::PROTOBUF_NAMESPACE_ID::EnumValue* mutable_enumvalue(int index); + ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::EnumValue >* + mutable_enumvalue(); + private: + const ::PROTOBUF_NAMESPACE_ID::EnumValue& _internal_enumvalue(int index) const; + ::PROTOBUF_NAMESPACE_ID::EnumValue* _internal_add_enumvalue(); + public: + const ::PROTOBUF_NAMESPACE_ID::EnumValue& enumvalue(int index) const; + ::PROTOBUF_NAMESPACE_ID::EnumValue* add_enumvalue(); + const ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::EnumValue >& + enumvalue() const; + + // repeated .google.protobuf.Option options = 3; + int options_size() const; + private: + int _internal_options_size() const; + public: + void clear_options(); + ::PROTOBUF_NAMESPACE_ID::Option* mutable_options(int index); + ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::Option >* + mutable_options(); + private: + const ::PROTOBUF_NAMESPACE_ID::Option& _internal_options(int index) const; + ::PROTOBUF_NAMESPACE_ID::Option* _internal_add_options(); + public: + const ::PROTOBUF_NAMESPACE_ID::Option& options(int index) const; + ::PROTOBUF_NAMESPACE_ID::Option* add_options(); + const ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::Option >& + options() const; + + // string name = 1; + void clear_name(); + const TProtoStringType& name() const; + template <typename ArgT0 = const TProtoStringType&, typename... ArgT> + void set_name(ArgT0&& arg0, ArgT... args); + TProtoStringType* mutable_name(); + PROTOBUF_NODISCARD TProtoStringType* release_name(); + void set_allocated_name(TProtoStringType* name); + private: + const TProtoStringType& _internal_name() const; + inline PROTOBUF_ALWAYS_INLINE void _internal_set_name(const TProtoStringType& value); + TProtoStringType* _internal_mutable_name(); + public: + + // .google.protobuf.SourceContext source_context = 4; + bool has_source_context() const; + private: + bool _internal_has_source_context() const; + public: + void clear_source_context(); + const ::PROTOBUF_NAMESPACE_ID::SourceContext& source_context() const; + PROTOBUF_NODISCARD ::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: + const ::PROTOBUF_NAMESPACE_ID::SourceContext& _internal_source_context() const; + ::PROTOBUF_NAMESPACE_ID::SourceContext* _internal_mutable_source_context(); + public: + void unsafe_arena_set_allocated_source_context( + ::PROTOBUF_NAMESPACE_ID::SourceContext* source_context); + ::PROTOBUF_NAMESPACE_ID::SourceContext* unsafe_arena_release_source_context(); + + // .google.protobuf.Syntax syntax = 5; + void clear_syntax(); + ::PROTOBUF_NAMESPACE_ID::Syntax syntax() const; + void set_syntax(::PROTOBUF_NAMESPACE_ID::Syntax value); + private: + ::PROTOBUF_NAMESPACE_ID::Syntax _internal_syntax() const; + void _internal_set_syntax(::PROTOBUF_NAMESPACE_ID::Syntax value); + public: + + // @@protoc_insertion_point(class_scope:google.protobuf.Enum) + private: + class _Internal; + + template <typename T> friend class ::PROTOBUF_NAMESPACE_ID::Arena::InternalHelper; + typedef void InternalArenaConstructable_; + typedef void DestructorSkippable_; + ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::EnumValue > enumvalue_; + ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::Option > options_; + ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr name_; + ::PROTOBUF_NAMESPACE_ID::SourceContext* source_context_; + int syntax_; + mutable ::PROTOBUF_NAMESPACE_ID::internal::CachedSize _cached_size_; + friend struct ::TableStruct_google_2fprotobuf_2ftype_2eproto; +}; +// ------------------------------------------------------------------- + +class PROTOBUF_EXPORT EnumValue final : + public ::PROTOBUF_NAMESPACE_ID::Message /* @@protoc_insertion_point(class_definition:google.protobuf.EnumValue) */ { + public: + inline EnumValue() : EnumValue(nullptr) {} + ~EnumValue() override; + explicit constexpr EnumValue(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized); + + EnumValue(const EnumValue& from); + EnumValue(EnumValue&& from) noexcept + : EnumValue() { + *this = ::std::move(from); + } + + inline EnumValue& operator=(const EnumValue& from) { + CopyFrom(from); + return *this; + } + inline EnumValue& operator=(EnumValue&& from) noexcept { + if (this == &from) return *this; + if (GetOwningArena() == from.GetOwningArena() + #ifdef PROTOBUF_FORCE_COPY_IN_MOVE + && GetOwningArena() != nullptr + #endif // !PROTOBUF_FORCE_COPY_IN_MOVE + ) { + InternalSwap(&from); + } else { + CopyFrom(from); + } + return *this; + } + + static const ::PROTOBUF_NAMESPACE_ID::Descriptor* descriptor() { + return GetDescriptor(); + } + static const ::PROTOBUF_NAMESPACE_ID::Descriptor* GetDescriptor() { + return default_instance().GetMetadata().descriptor; + } + static const ::PROTOBUF_NAMESPACE_ID::Reflection* GetReflection() { + return default_instance().GetMetadata().reflection; + } + static const EnumValue& default_instance() { + return *internal_default_instance(); + } + static inline const EnumValue* internal_default_instance() { + return reinterpret_cast<const EnumValue*>( + &_EnumValue_default_instance_); + } + static constexpr int kIndexInFileMessages = + 3; + + friend void swap(EnumValue& a, EnumValue& b) { + a.Swap(&b); + } + inline void Swap(EnumValue* other) { + if (other == this) return; + #ifdef PROTOBUF_FORCE_COPY_IN_SWAP + if (GetOwningArena() != nullptr && + GetOwningArena() == other->GetOwningArena()) { + #else // PROTOBUF_FORCE_COPY_IN_SWAP + if (GetOwningArena() == other->GetOwningArena()) { + #endif // !PROTOBUF_FORCE_COPY_IN_SWAP + InternalSwap(other); + } else { + ::PROTOBUF_NAMESPACE_ID::internal::GenericSwap(this, other); + } + } + void UnsafeArenaSwap(EnumValue* other) { + if (other == this) return; + GOOGLE_DCHECK(GetOwningArena() == other->GetOwningArena()); + InternalSwap(other); + } + + // implements Message ---------------------------------------------- + + EnumValue* New(::PROTOBUF_NAMESPACE_ID::Arena* arena = nullptr) const final { + return CreateMaybeMessage<EnumValue>(arena); + } + using ::PROTOBUF_NAMESPACE_ID::Message::CopyFrom; + void CopyFrom(const EnumValue& from); + using ::PROTOBUF_NAMESPACE_ID::Message::MergeFrom; + void MergeFrom(const EnumValue& 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; + + size_t ByteSizeLong() const final; + const char* _InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) final; + uint8_t* _InternalSerialize( + uint8_t* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const final; + int GetCachedSize() const final { return _cached_size_.Get(); } + + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const final; + void InternalSwap(EnumValue* other); + + private: + friend class ::PROTOBUF_NAMESPACE_ID::internal::AnyMetadata; + static ::PROTOBUF_NAMESPACE_ID::StringPiece FullMessageName() { + return "google.protobuf.EnumValue"; + } + protected: + explicit EnumValue(::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 ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + enum : int { + kOptionsFieldNumber = 3, + kNameFieldNumber = 1, + kNumberFieldNumber = 2, + }; + // repeated .google.protobuf.Option options = 3; + int options_size() const; + private: + int _internal_options_size() const; + public: + void clear_options(); + ::PROTOBUF_NAMESPACE_ID::Option* mutable_options(int index); + ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::Option >* + mutable_options(); + private: + const ::PROTOBUF_NAMESPACE_ID::Option& _internal_options(int index) const; + ::PROTOBUF_NAMESPACE_ID::Option* _internal_add_options(); + public: + const ::PROTOBUF_NAMESPACE_ID::Option& options(int index) const; + ::PROTOBUF_NAMESPACE_ID::Option* add_options(); + const ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::Option >& + options() const; + + // string name = 1; + void clear_name(); + const TProtoStringType& name() const; + template <typename ArgT0 = const TProtoStringType&, typename... ArgT> + void set_name(ArgT0&& arg0, ArgT... args); + TProtoStringType* mutable_name(); + PROTOBUF_NODISCARD TProtoStringType* release_name(); + void set_allocated_name(TProtoStringType* name); + private: + const TProtoStringType& _internal_name() const; + inline PROTOBUF_ALWAYS_INLINE void _internal_set_name(const TProtoStringType& value); + TProtoStringType* _internal_mutable_name(); + public: + + // int32 number = 2; + void clear_number(); + arc_i32 number() const; + void set_number(arc_i32 value); + private: + arc_i32 _internal_number() const; + void _internal_set_number(arc_i32 value); + public: + + // @@protoc_insertion_point(class_scope:google.protobuf.EnumValue) + private: + class _Internal; + + template <typename T> friend class ::PROTOBUF_NAMESPACE_ID::Arena::InternalHelper; + typedef void InternalArenaConstructable_; + typedef void DestructorSkippable_; + ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::Option > options_; + ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr name_; + arc_i32 number_; + mutable ::PROTOBUF_NAMESPACE_ID::internal::CachedSize _cached_size_; + friend struct ::TableStruct_google_2fprotobuf_2ftype_2eproto; +}; +// ------------------------------------------------------------------- + +class PROTOBUF_EXPORT Option final : + public ::PROTOBUF_NAMESPACE_ID::Message /* @@protoc_insertion_point(class_definition:google.protobuf.Option) */ { + public: + inline Option() : Option(nullptr) {} + ~Option() override; + explicit constexpr Option(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized); + + Option(const Option& from); + Option(Option&& from) noexcept + : Option() { + *this = ::std::move(from); + } + + inline Option& operator=(const Option& from) { + CopyFrom(from); + return *this; + } + inline Option& operator=(Option&& from) noexcept { + if (this == &from) return *this; + if (GetOwningArena() == from.GetOwningArena() + #ifdef PROTOBUF_FORCE_COPY_IN_MOVE + && GetOwningArena() != nullptr + #endif // !PROTOBUF_FORCE_COPY_IN_MOVE + ) { + InternalSwap(&from); + } else { + CopyFrom(from); + } + return *this; + } + + static const ::PROTOBUF_NAMESPACE_ID::Descriptor* descriptor() { + return GetDescriptor(); + } + static const ::PROTOBUF_NAMESPACE_ID::Descriptor* GetDescriptor() { + return default_instance().GetMetadata().descriptor; + } + static const ::PROTOBUF_NAMESPACE_ID::Reflection* GetReflection() { + return default_instance().GetMetadata().reflection; + } + static const Option& default_instance() { + return *internal_default_instance(); + } + static inline const Option* internal_default_instance() { + return reinterpret_cast<const Option*>( + &_Option_default_instance_); + } + static constexpr int kIndexInFileMessages = + 4; + + friend void swap(Option& a, Option& b) { + a.Swap(&b); + } + inline void Swap(Option* other) { + if (other == this) return; + #ifdef PROTOBUF_FORCE_COPY_IN_SWAP + if (GetOwningArena() != nullptr && + GetOwningArena() == other->GetOwningArena()) { + #else // PROTOBUF_FORCE_COPY_IN_SWAP + if (GetOwningArena() == other->GetOwningArena()) { + #endif // !PROTOBUF_FORCE_COPY_IN_SWAP + InternalSwap(other); + } else { + ::PROTOBUF_NAMESPACE_ID::internal::GenericSwap(this, other); + } + } + void UnsafeArenaSwap(Option* other) { + if (other == this) return; + GOOGLE_DCHECK(GetOwningArena() == other->GetOwningArena()); + InternalSwap(other); + } + + // implements Message ---------------------------------------------- + + Option* New(::PROTOBUF_NAMESPACE_ID::Arena* arena = nullptr) const final { + return CreateMaybeMessage<Option>(arena); + } + using ::PROTOBUF_NAMESPACE_ID::Message::CopyFrom; + void CopyFrom(const Option& from); + using ::PROTOBUF_NAMESPACE_ID::Message::MergeFrom; + void MergeFrom(const Option& 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; + + size_t ByteSizeLong() const final; + const char* _InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) final; + uint8_t* _InternalSerialize( + uint8_t* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const final; + int GetCachedSize() const final { return _cached_size_.Get(); } + + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const final; + void InternalSwap(Option* other); + + private: + friend class ::PROTOBUF_NAMESPACE_ID::internal::AnyMetadata; + static ::PROTOBUF_NAMESPACE_ID::StringPiece FullMessageName() { + return "google.protobuf.Option"; + } + protected: + explicit Option(::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 ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + enum : int { + kNameFieldNumber = 1, + kValueFieldNumber = 2, + }; + // string name = 1; + void clear_name(); + const TProtoStringType& name() const; + template <typename ArgT0 = const TProtoStringType&, typename... ArgT> + void set_name(ArgT0&& arg0, ArgT... args); + TProtoStringType* mutable_name(); + PROTOBUF_NODISCARD TProtoStringType* release_name(); + void set_allocated_name(TProtoStringType* name); + private: + const TProtoStringType& _internal_name() const; + inline PROTOBUF_ALWAYS_INLINE void _internal_set_name(const TProtoStringType& value); + TProtoStringType* _internal_mutable_name(); + public: + + // .google.protobuf.Any value = 2; + bool has_value() const; + private: + bool _internal_has_value() const; + public: + void clear_value(); + const ::PROTOBUF_NAMESPACE_ID::Any& value() const; + PROTOBUF_NODISCARD ::PROTOBUF_NAMESPACE_ID::Any* release_value(); + ::PROTOBUF_NAMESPACE_ID::Any* mutable_value(); + void set_allocated_value(::PROTOBUF_NAMESPACE_ID::Any* value); + private: + const ::PROTOBUF_NAMESPACE_ID::Any& _internal_value() const; + ::PROTOBUF_NAMESPACE_ID::Any* _internal_mutable_value(); + public: + void unsafe_arena_set_allocated_value( + ::PROTOBUF_NAMESPACE_ID::Any* value); + ::PROTOBUF_NAMESPACE_ID::Any* unsafe_arena_release_value(); + + // @@protoc_insertion_point(class_scope:google.protobuf.Option) + private: + class _Internal; + + template <typename T> friend class ::PROTOBUF_NAMESPACE_ID::Arena::InternalHelper; + typedef void InternalArenaConstructable_; + typedef void DestructorSkippable_; + ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr name_; + ::PROTOBUF_NAMESPACE_ID::Any* value_; + mutable ::PROTOBUF_NAMESPACE_ID::internal::CachedSize _cached_size_; + friend struct ::TableStruct_google_2fprotobuf_2ftype_2eproto; +}; +// =================================================================== + + +// =================================================================== + +#ifdef __GNUC__ + #pragma GCC diagnostic push + #pragma GCC diagnostic ignored "-Wstrict-aliasing" +#endif // __GNUC__ +// Type + +// string name = 1; +inline void Type::clear_name() { + name_.ClearToEmpty(); +} +inline const TProtoStringType& Type::name() const { + // @@protoc_insertion_point(field_get:google.protobuf.Type.name) + return _internal_name(); +} +template <typename ArgT0, typename... ArgT> +inline PROTOBUF_ALWAYS_INLINE +void Type::set_name(ArgT0&& arg0, ArgT... args) { + + name_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, static_cast<ArgT0 &&>(arg0), args..., GetArenaForAllocation()); + // @@protoc_insertion_point(field_set:google.protobuf.Type.name) +} +inline TProtoStringType* Type::mutable_name() { + TProtoStringType* _s = _internal_mutable_name(); + // @@protoc_insertion_point(field_mutable:google.protobuf.Type.name) + return _s; +} +inline const TProtoStringType& Type::_internal_name() const { + return name_.Get(); +} +inline void Type::_internal_set_name(const TProtoStringType& value) { + + name_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, value, GetArenaForAllocation()); +} +inline TProtoStringType* Type::_internal_mutable_name() { + + return name_.Mutable(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, GetArenaForAllocation()); +} +inline TProtoStringType* Type::release_name() { + // @@protoc_insertion_point(field_release:google.protobuf.Type.name) + return name_.Release(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArenaForAllocation()); +} +inline void Type::set_allocated_name(TProtoStringType* name) { + if (name != nullptr) { + + } else { + + } + name_.SetAllocated(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), name, + GetArenaForAllocation()); +#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING + if (name_.IsDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited())) { + name_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation()); + } +#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING + // @@protoc_insertion_point(field_set_allocated:google.protobuf.Type.name) +} + +// repeated .google.protobuf.Field fields = 2; +inline int Type::_internal_fields_size() const { + return fields_.size(); +} +inline int Type::fields_size() const { + return _internal_fields_size(); +} +inline void Type::clear_fields() { + fields_.Clear(); +} +inline ::PROTOBUF_NAMESPACE_ID::Field* Type::mutable_fields(int index) { + // @@protoc_insertion_point(field_mutable:google.protobuf.Type.fields) + return fields_.Mutable(index); +} +inline ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::Field >* +Type::mutable_fields() { + // @@protoc_insertion_point(field_mutable_list:google.protobuf.Type.fields) + return &fields_; +} +inline const ::PROTOBUF_NAMESPACE_ID::Field& Type::_internal_fields(int index) const { + return fields_.Get(index); +} +inline const ::PROTOBUF_NAMESPACE_ID::Field& Type::fields(int index) const { + // @@protoc_insertion_point(field_get:google.protobuf.Type.fields) + return _internal_fields(index); +} +inline ::PROTOBUF_NAMESPACE_ID::Field* Type::_internal_add_fields() { + return fields_.Add(); +} +inline ::PROTOBUF_NAMESPACE_ID::Field* Type::add_fields() { + ::PROTOBUF_NAMESPACE_ID::Field* _add = _internal_add_fields(); + // @@protoc_insertion_point(field_add:google.protobuf.Type.fields) + return _add; +} +inline const ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::Field >& +Type::fields() const { + // @@protoc_insertion_point(field_list:google.protobuf.Type.fields) + return fields_; +} + +// repeated string oneofs = 3; +inline int Type::_internal_oneofs_size() const { + return oneofs_.size(); +} +inline int Type::oneofs_size() const { + return _internal_oneofs_size(); +} +inline void Type::clear_oneofs() { + oneofs_.Clear(); +} +inline TProtoStringType* Type::add_oneofs() { + TProtoStringType* _s = _internal_add_oneofs(); + // @@protoc_insertion_point(field_add_mutable:google.protobuf.Type.oneofs) + return _s; +} +inline const TProtoStringType& Type::_internal_oneofs(int index) const { + return oneofs_.Get(index); +} +inline const TProtoStringType& Type::oneofs(int index) const { + // @@protoc_insertion_point(field_get:google.protobuf.Type.oneofs) + return _internal_oneofs(index); +} +inline TProtoStringType* Type::mutable_oneofs(int index) { + // @@protoc_insertion_point(field_mutable:google.protobuf.Type.oneofs) + return oneofs_.Mutable(index); +} +inline void Type::set_oneofs(int index, const TProtoStringType& value) { + oneofs_.Mutable(index)->assign(value); + // @@protoc_insertion_point(field_set:google.protobuf.Type.oneofs) +} +inline void Type::set_oneofs(int index, TProtoStringType&& value) { + oneofs_.Mutable(index)->assign(std::move(value)); + // @@protoc_insertion_point(field_set:google.protobuf.Type.oneofs) +} +inline void Type::set_oneofs(int index, const char* value) { + GOOGLE_DCHECK(value != nullptr); + oneofs_.Mutable(index)->assign(value); + // @@protoc_insertion_point(field_set_char:google.protobuf.Type.oneofs) +} +inline void Type::set_oneofs(int index, const char* value, size_t size) { + oneofs_.Mutable(index)->assign( + reinterpret_cast<const char*>(value), size); + // @@protoc_insertion_point(field_set_pointer:google.protobuf.Type.oneofs) +} +inline TProtoStringType* Type::_internal_add_oneofs() { + return oneofs_.Add(); +} +inline void Type::add_oneofs(const TProtoStringType& value) { + oneofs_.Add()->assign(value); + // @@protoc_insertion_point(field_add:google.protobuf.Type.oneofs) +} +inline void Type::add_oneofs(TProtoStringType&& value) { + oneofs_.Add(std::move(value)); + // @@protoc_insertion_point(field_add:google.protobuf.Type.oneofs) +} +inline void Type::add_oneofs(const char* value) { + GOOGLE_DCHECK(value != nullptr); + oneofs_.Add()->assign(value); + // @@protoc_insertion_point(field_add_char:google.protobuf.Type.oneofs) +} +inline void Type::add_oneofs(const char* value, size_t size) { + oneofs_.Add()->assign(reinterpret_cast<const char*>(value), size); + // @@protoc_insertion_point(field_add_pointer:google.protobuf.Type.oneofs) +} +inline const ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField<TProtoStringType>& +Type::oneofs() const { + // @@protoc_insertion_point(field_list:google.protobuf.Type.oneofs) + return oneofs_; +} +inline ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField<TProtoStringType>* +Type::mutable_oneofs() { + // @@protoc_insertion_point(field_mutable_list:google.protobuf.Type.oneofs) + return &oneofs_; +} + +// repeated .google.protobuf.Option options = 4; +inline int Type::_internal_options_size() const { + return options_.size(); +} +inline int Type::options_size() const { + return _internal_options_size(); +} +inline void Type::clear_options() { + options_.Clear(); +} +inline ::PROTOBUF_NAMESPACE_ID::Option* Type::mutable_options(int index) { + // @@protoc_insertion_point(field_mutable:google.protobuf.Type.options) + return options_.Mutable(index); +} +inline ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::Option >* +Type::mutable_options() { + // @@protoc_insertion_point(field_mutable_list:google.protobuf.Type.options) + return &options_; +} +inline const ::PROTOBUF_NAMESPACE_ID::Option& Type::_internal_options(int index) const { + return options_.Get(index); +} +inline const ::PROTOBUF_NAMESPACE_ID::Option& Type::options(int index) const { + // @@protoc_insertion_point(field_get:google.protobuf.Type.options) + return _internal_options(index); +} +inline ::PROTOBUF_NAMESPACE_ID::Option* Type::_internal_add_options() { + return options_.Add(); +} +inline ::PROTOBUF_NAMESPACE_ID::Option* Type::add_options() { + ::PROTOBUF_NAMESPACE_ID::Option* _add = _internal_add_options(); + // @@protoc_insertion_point(field_add:google.protobuf.Type.options) + return _add; +} +inline const ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::Option >& +Type::options() const { + // @@protoc_insertion_point(field_list:google.protobuf.Type.options) + return options_; +} + +// .google.protobuf.SourceContext source_context = 5; +inline bool Type::_internal_has_source_context() const { + return this != internal_default_instance() && source_context_ != nullptr; +} +inline bool Type::has_source_context() const { + return _internal_has_source_context(); +} +inline const ::PROTOBUF_NAMESPACE_ID::SourceContext& Type::_internal_source_context() const { + const ::PROTOBUF_NAMESPACE_ID::SourceContext* p = source_context_; + return p != nullptr ? *p : reinterpret_cast<const ::PROTOBUF_NAMESPACE_ID::SourceContext&>( + ::PROTOBUF_NAMESPACE_ID::_SourceContext_default_instance_); +} +inline const ::PROTOBUF_NAMESPACE_ID::SourceContext& Type::source_context() const { + // @@protoc_insertion_point(field_get:google.protobuf.Type.source_context) + return _internal_source_context(); +} +inline void Type::unsafe_arena_set_allocated_source_context( + ::PROTOBUF_NAMESPACE_ID::SourceContext* source_context) { + if (GetArenaForAllocation() == nullptr) { + delete reinterpret_cast<::PROTOBUF_NAMESPACE_ID::MessageLite*>(source_context_); + } + source_context_ = source_context; + if (source_context) { + + } else { + + } + // @@protoc_insertion_point(field_unsafe_arena_set_allocated:google.protobuf.Type.source_context) +} +inline ::PROTOBUF_NAMESPACE_ID::SourceContext* Type::release_source_context() { + + ::PROTOBUF_NAMESPACE_ID::SourceContext* temp = source_context_; + source_context_ = nullptr; +#ifdef PROTOBUF_FORCE_COPY_IN_RELEASE + auto* old = reinterpret_cast<::PROTOBUF_NAMESPACE_ID::MessageLite*>(temp); + temp = ::PROTOBUF_NAMESPACE_ID::internal::DuplicateIfNonNull(temp); + if (GetArenaForAllocation() == nullptr) { delete old; } +#else // PROTOBUF_FORCE_COPY_IN_RELEASE + if (GetArenaForAllocation() != nullptr) { + temp = ::PROTOBUF_NAMESPACE_ID::internal::DuplicateIfNonNull(temp); + } +#endif // !PROTOBUF_FORCE_COPY_IN_RELEASE + return temp; +} +inline ::PROTOBUF_NAMESPACE_ID::SourceContext* Type::unsafe_arena_release_source_context() { + // @@protoc_insertion_point(field_release:google.protobuf.Type.source_context) + + ::PROTOBUF_NAMESPACE_ID::SourceContext* temp = source_context_; + source_context_ = nullptr; + return temp; +} +inline ::PROTOBUF_NAMESPACE_ID::SourceContext* Type::_internal_mutable_source_context() { + + if (source_context_ == nullptr) { + auto* p = CreateMaybeMessage<::PROTOBUF_NAMESPACE_ID::SourceContext>(GetArenaForAllocation()); + source_context_ = p; + } + return source_context_; +} +inline ::PROTOBUF_NAMESPACE_ID::SourceContext* Type::mutable_source_context() { + ::PROTOBUF_NAMESPACE_ID::SourceContext* _msg = _internal_mutable_source_context(); + // @@protoc_insertion_point(field_mutable:google.protobuf.Type.source_context) + return _msg; +} +inline void Type::set_allocated_source_context(::PROTOBUF_NAMESPACE_ID::SourceContext* source_context) { + ::PROTOBUF_NAMESPACE_ID::Arena* message_arena = GetArenaForAllocation(); + if (message_arena == nullptr) { + delete reinterpret_cast< ::PROTOBUF_NAMESPACE_ID::MessageLite*>(source_context_); + } + if (source_context) { + ::PROTOBUF_NAMESPACE_ID::Arena* submessage_arena = + ::PROTOBUF_NAMESPACE_ID::Arena::InternalHelper< + ::PROTOBUF_NAMESPACE_ID::MessageLite>::GetOwningArena( + reinterpret_cast<::PROTOBUF_NAMESPACE_ID::MessageLite*>(source_context)); + if (message_arena != submessage_arena) { + source_context = ::PROTOBUF_NAMESPACE_ID::internal::GetOwnedMessage( + message_arena, source_context, submessage_arena); + } + + } else { + + } + source_context_ = source_context; + // @@protoc_insertion_point(field_set_allocated:google.protobuf.Type.source_context) +} + +// .google.protobuf.Syntax syntax = 6; +inline void Type::clear_syntax() { + syntax_ = 0; +} +inline ::PROTOBUF_NAMESPACE_ID::Syntax Type::_internal_syntax() const { + return static_cast< ::PROTOBUF_NAMESPACE_ID::Syntax >(syntax_); +} +inline ::PROTOBUF_NAMESPACE_ID::Syntax Type::syntax() const { + // @@protoc_insertion_point(field_get:google.protobuf.Type.syntax) + return _internal_syntax(); +} +inline void Type::_internal_set_syntax(::PROTOBUF_NAMESPACE_ID::Syntax value) { + + syntax_ = value; +} +inline void Type::set_syntax(::PROTOBUF_NAMESPACE_ID::Syntax value) { + _internal_set_syntax(value); + // @@protoc_insertion_point(field_set:google.protobuf.Type.syntax) +} + +// ------------------------------------------------------------------- + +// Field + +// .google.protobuf.Field.Kind kind = 1; +inline void Field::clear_kind() { + kind_ = 0; +} +inline ::PROTOBUF_NAMESPACE_ID::Field_Kind Field::_internal_kind() const { + return static_cast< ::PROTOBUF_NAMESPACE_ID::Field_Kind >(kind_); +} +inline ::PROTOBUF_NAMESPACE_ID::Field_Kind Field::kind() const { + // @@protoc_insertion_point(field_get:google.protobuf.Field.kind) + return _internal_kind(); +} +inline void Field::_internal_set_kind(::PROTOBUF_NAMESPACE_ID::Field_Kind value) { + + kind_ = value; +} +inline void Field::set_kind(::PROTOBUF_NAMESPACE_ID::Field_Kind value) { + _internal_set_kind(value); + // @@protoc_insertion_point(field_set:google.protobuf.Field.kind) +} + +// .google.protobuf.Field.Cardinality cardinality = 2; +inline void Field::clear_cardinality() { + cardinality_ = 0; +} +inline ::PROTOBUF_NAMESPACE_ID::Field_Cardinality Field::_internal_cardinality() const { + return static_cast< ::PROTOBUF_NAMESPACE_ID::Field_Cardinality >(cardinality_); +} +inline ::PROTOBUF_NAMESPACE_ID::Field_Cardinality Field::cardinality() const { + // @@protoc_insertion_point(field_get:google.protobuf.Field.cardinality) + return _internal_cardinality(); +} +inline void Field::_internal_set_cardinality(::PROTOBUF_NAMESPACE_ID::Field_Cardinality value) { + + cardinality_ = value; +} +inline void Field::set_cardinality(::PROTOBUF_NAMESPACE_ID::Field_Cardinality value) { + _internal_set_cardinality(value); + // @@protoc_insertion_point(field_set:google.protobuf.Field.cardinality) +} + +// int32 number = 3; +inline void Field::clear_number() { + number_ = 0; +} +inline arc_i32 Field::_internal_number() const { + return number_; +} +inline arc_i32 Field::number() const { + // @@protoc_insertion_point(field_get:google.protobuf.Field.number) + return _internal_number(); +} +inline void Field::_internal_set_number(arc_i32 value) { + + number_ = value; +} +inline void Field::set_number(arc_i32 value) { + _internal_set_number(value); + // @@protoc_insertion_point(field_set:google.protobuf.Field.number) +} + +// string name = 4; +inline void Field::clear_name() { + name_.ClearToEmpty(); +} +inline const TProtoStringType& Field::name() const { + // @@protoc_insertion_point(field_get:google.protobuf.Field.name) + return _internal_name(); +} +template <typename ArgT0, typename... ArgT> +inline PROTOBUF_ALWAYS_INLINE +void Field::set_name(ArgT0&& arg0, ArgT... args) { + + name_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, static_cast<ArgT0 &&>(arg0), args..., GetArenaForAllocation()); + // @@protoc_insertion_point(field_set:google.protobuf.Field.name) +} +inline TProtoStringType* Field::mutable_name() { + TProtoStringType* _s = _internal_mutable_name(); + // @@protoc_insertion_point(field_mutable:google.protobuf.Field.name) + return _s; +} +inline const TProtoStringType& Field::_internal_name() const { + return name_.Get(); +} +inline void Field::_internal_set_name(const TProtoStringType& value) { + + name_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, value, GetArenaForAllocation()); +} +inline TProtoStringType* Field::_internal_mutable_name() { + + return name_.Mutable(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, GetArenaForAllocation()); +} +inline TProtoStringType* Field::release_name() { + // @@protoc_insertion_point(field_release:google.protobuf.Field.name) + return name_.Release(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArenaForAllocation()); +} +inline void Field::set_allocated_name(TProtoStringType* name) { + if (name != nullptr) { + + } else { + + } + name_.SetAllocated(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), name, + GetArenaForAllocation()); +#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING + if (name_.IsDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited())) { + name_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation()); + } +#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING + // @@protoc_insertion_point(field_set_allocated:google.protobuf.Field.name) +} + +// string type_url = 6; +inline void Field::clear_type_url() { + type_url_.ClearToEmpty(); +} +inline const TProtoStringType& Field::type_url() const { + // @@protoc_insertion_point(field_get:google.protobuf.Field.type_url) + return _internal_type_url(); +} +template <typename ArgT0, typename... ArgT> +inline PROTOBUF_ALWAYS_INLINE +void Field::set_type_url(ArgT0&& arg0, ArgT... args) { + + type_url_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, static_cast<ArgT0 &&>(arg0), args..., GetArenaForAllocation()); + // @@protoc_insertion_point(field_set:google.protobuf.Field.type_url) +} +inline TProtoStringType* Field::mutable_type_url() { + TProtoStringType* _s = _internal_mutable_type_url(); + // @@protoc_insertion_point(field_mutable:google.protobuf.Field.type_url) + return _s; +} +inline const TProtoStringType& Field::_internal_type_url() const { + return type_url_.Get(); +} +inline void Field::_internal_set_type_url(const TProtoStringType& value) { + + type_url_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, value, GetArenaForAllocation()); +} +inline TProtoStringType* Field::_internal_mutable_type_url() { + + return type_url_.Mutable(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, GetArenaForAllocation()); +} +inline TProtoStringType* Field::release_type_url() { + // @@protoc_insertion_point(field_release:google.protobuf.Field.type_url) + return type_url_.Release(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArenaForAllocation()); +} +inline void Field::set_allocated_type_url(TProtoStringType* type_url) { + if (type_url != nullptr) { + + } else { + + } + type_url_.SetAllocated(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), type_url, + GetArenaForAllocation()); +#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING + if (type_url_.IsDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited())) { + type_url_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation()); + } +#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING + // @@protoc_insertion_point(field_set_allocated:google.protobuf.Field.type_url) +} + +// int32 oneof_index = 7; +inline void Field::clear_oneof_index() { + oneof_index_ = 0; +} +inline arc_i32 Field::_internal_oneof_index() const { + return oneof_index_; +} +inline arc_i32 Field::oneof_index() const { + // @@protoc_insertion_point(field_get:google.protobuf.Field.oneof_index) + return _internal_oneof_index(); +} +inline void Field::_internal_set_oneof_index(arc_i32 value) { + + oneof_index_ = value; +} +inline void Field::set_oneof_index(arc_i32 value) { + _internal_set_oneof_index(value); + // @@protoc_insertion_point(field_set:google.protobuf.Field.oneof_index) +} + +// bool packed = 8; +inline void Field::clear_packed() { + packed_ = false; +} +inline bool Field::_internal_packed() const { + return packed_; +} +inline bool Field::packed() const { + // @@protoc_insertion_point(field_get:google.protobuf.Field.packed) + return _internal_packed(); +} +inline void Field::_internal_set_packed(bool value) { + + packed_ = value; +} +inline void Field::set_packed(bool value) { + _internal_set_packed(value); + // @@protoc_insertion_point(field_set:google.protobuf.Field.packed) +} + +// repeated .google.protobuf.Option options = 9; +inline int Field::_internal_options_size() const { + return options_.size(); +} +inline int Field::options_size() const { + return _internal_options_size(); +} +inline void Field::clear_options() { + options_.Clear(); +} +inline ::PROTOBUF_NAMESPACE_ID::Option* Field::mutable_options(int index) { + // @@protoc_insertion_point(field_mutable:google.protobuf.Field.options) + return options_.Mutable(index); +} +inline ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::Option >* +Field::mutable_options() { + // @@protoc_insertion_point(field_mutable_list:google.protobuf.Field.options) + return &options_; +} +inline const ::PROTOBUF_NAMESPACE_ID::Option& Field::_internal_options(int index) const { + return options_.Get(index); +} +inline const ::PROTOBUF_NAMESPACE_ID::Option& Field::options(int index) const { + // @@protoc_insertion_point(field_get:google.protobuf.Field.options) + return _internal_options(index); +} +inline ::PROTOBUF_NAMESPACE_ID::Option* Field::_internal_add_options() { + return options_.Add(); +} +inline ::PROTOBUF_NAMESPACE_ID::Option* Field::add_options() { + ::PROTOBUF_NAMESPACE_ID::Option* _add = _internal_add_options(); + // @@protoc_insertion_point(field_add:google.protobuf.Field.options) + return _add; +} +inline const ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::Option >& +Field::options() const { + // @@protoc_insertion_point(field_list:google.protobuf.Field.options) + return options_; +} + +// string json_name = 10; +inline void Field::clear_json_name() { + json_name_.ClearToEmpty(); +} +inline const TProtoStringType& Field::json_name() const { + // @@protoc_insertion_point(field_get:google.protobuf.Field.json_name) + return _internal_json_name(); +} +template <typename ArgT0, typename... ArgT> +inline PROTOBUF_ALWAYS_INLINE +void Field::set_json_name(ArgT0&& arg0, ArgT... args) { + + json_name_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, static_cast<ArgT0 &&>(arg0), args..., GetArenaForAllocation()); + // @@protoc_insertion_point(field_set:google.protobuf.Field.json_name) +} +inline TProtoStringType* Field::mutable_json_name() { + TProtoStringType* _s = _internal_mutable_json_name(); + // @@protoc_insertion_point(field_mutable:google.protobuf.Field.json_name) + return _s; +} +inline const TProtoStringType& Field::_internal_json_name() const { + return json_name_.Get(); +} +inline void Field::_internal_set_json_name(const TProtoStringType& value) { + + json_name_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, value, GetArenaForAllocation()); +} +inline TProtoStringType* Field::_internal_mutable_json_name() { + + return json_name_.Mutable(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, GetArenaForAllocation()); +} +inline TProtoStringType* Field::release_json_name() { + // @@protoc_insertion_point(field_release:google.protobuf.Field.json_name) + return json_name_.Release(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArenaForAllocation()); +} +inline void Field::set_allocated_json_name(TProtoStringType* json_name) { + if (json_name != nullptr) { + + } else { + + } + json_name_.SetAllocated(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), json_name, + GetArenaForAllocation()); +#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING + if (json_name_.IsDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited())) { + json_name_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation()); + } +#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING + // @@protoc_insertion_point(field_set_allocated:google.protobuf.Field.json_name) +} + +// string default_value = 11; +inline void Field::clear_default_value() { + default_value_.ClearToEmpty(); +} +inline const TProtoStringType& Field::default_value() const { + // @@protoc_insertion_point(field_get:google.protobuf.Field.default_value) + return _internal_default_value(); +} +template <typename ArgT0, typename... ArgT> +inline PROTOBUF_ALWAYS_INLINE +void Field::set_default_value(ArgT0&& arg0, ArgT... args) { + + default_value_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, static_cast<ArgT0 &&>(arg0), args..., GetArenaForAllocation()); + // @@protoc_insertion_point(field_set:google.protobuf.Field.default_value) +} +inline TProtoStringType* Field::mutable_default_value() { + TProtoStringType* _s = _internal_mutable_default_value(); + // @@protoc_insertion_point(field_mutable:google.protobuf.Field.default_value) + return _s; +} +inline const TProtoStringType& Field::_internal_default_value() const { + return default_value_.Get(); +} +inline void Field::_internal_set_default_value(const TProtoStringType& value) { + + default_value_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, value, GetArenaForAllocation()); +} +inline TProtoStringType* Field::_internal_mutable_default_value() { + + return default_value_.Mutable(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, GetArenaForAllocation()); +} +inline TProtoStringType* Field::release_default_value() { + // @@protoc_insertion_point(field_release:google.protobuf.Field.default_value) + return default_value_.Release(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArenaForAllocation()); +} +inline void Field::set_allocated_default_value(TProtoStringType* default_value) { + if (default_value != nullptr) { + + } else { + + } + default_value_.SetAllocated(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), default_value, + GetArenaForAllocation()); +#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING + if (default_value_.IsDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited())) { + default_value_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation()); + } +#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING + // @@protoc_insertion_point(field_set_allocated:google.protobuf.Field.default_value) +} + +// ------------------------------------------------------------------- + +// Enum + +// string name = 1; +inline void Enum::clear_name() { + name_.ClearToEmpty(); +} +inline const TProtoStringType& Enum::name() const { + // @@protoc_insertion_point(field_get:google.protobuf.Enum.name) + return _internal_name(); +} +template <typename ArgT0, typename... ArgT> +inline PROTOBUF_ALWAYS_INLINE +void Enum::set_name(ArgT0&& arg0, ArgT... args) { + + name_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, static_cast<ArgT0 &&>(arg0), args..., GetArenaForAllocation()); + // @@protoc_insertion_point(field_set:google.protobuf.Enum.name) +} +inline TProtoStringType* Enum::mutable_name() { + TProtoStringType* _s = _internal_mutable_name(); + // @@protoc_insertion_point(field_mutable:google.protobuf.Enum.name) + return _s; +} +inline const TProtoStringType& Enum::_internal_name() const { + return name_.Get(); +} +inline void Enum::_internal_set_name(const TProtoStringType& value) { + + name_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, value, GetArenaForAllocation()); +} +inline TProtoStringType* Enum::_internal_mutable_name() { + + return name_.Mutable(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, GetArenaForAllocation()); +} +inline TProtoStringType* Enum::release_name() { + // @@protoc_insertion_point(field_release:google.protobuf.Enum.name) + return name_.Release(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArenaForAllocation()); +} +inline void Enum::set_allocated_name(TProtoStringType* name) { + if (name != nullptr) { + + } else { + + } + name_.SetAllocated(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), name, + GetArenaForAllocation()); +#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING + if (name_.IsDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited())) { + name_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation()); + } +#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING + // @@protoc_insertion_point(field_set_allocated:google.protobuf.Enum.name) +} + +// repeated .google.protobuf.EnumValue enumvalue = 2; +inline int Enum::_internal_enumvalue_size() const { + return enumvalue_.size(); +} +inline int Enum::enumvalue_size() const { + return _internal_enumvalue_size(); +} +inline void Enum::clear_enumvalue() { + enumvalue_.Clear(); +} +inline ::PROTOBUF_NAMESPACE_ID::EnumValue* Enum::mutable_enumvalue(int index) { + // @@protoc_insertion_point(field_mutable:google.protobuf.Enum.enumvalue) + return enumvalue_.Mutable(index); +} +inline ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::EnumValue >* +Enum::mutable_enumvalue() { + // @@protoc_insertion_point(field_mutable_list:google.protobuf.Enum.enumvalue) + return &enumvalue_; +} +inline const ::PROTOBUF_NAMESPACE_ID::EnumValue& Enum::_internal_enumvalue(int index) const { + return enumvalue_.Get(index); +} +inline const ::PROTOBUF_NAMESPACE_ID::EnumValue& Enum::enumvalue(int index) const { + // @@protoc_insertion_point(field_get:google.protobuf.Enum.enumvalue) + return _internal_enumvalue(index); +} +inline ::PROTOBUF_NAMESPACE_ID::EnumValue* Enum::_internal_add_enumvalue() { + return enumvalue_.Add(); +} +inline ::PROTOBUF_NAMESPACE_ID::EnumValue* Enum::add_enumvalue() { + ::PROTOBUF_NAMESPACE_ID::EnumValue* _add = _internal_add_enumvalue(); + // @@protoc_insertion_point(field_add:google.protobuf.Enum.enumvalue) + return _add; +} +inline const ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::EnumValue >& +Enum::enumvalue() const { + // @@protoc_insertion_point(field_list:google.protobuf.Enum.enumvalue) + return enumvalue_; +} + +// repeated .google.protobuf.Option options = 3; +inline int Enum::_internal_options_size() const { + return options_.size(); +} +inline int Enum::options_size() const { + return _internal_options_size(); +} +inline void Enum::clear_options() { + options_.Clear(); +} +inline ::PROTOBUF_NAMESPACE_ID::Option* Enum::mutable_options(int index) { + // @@protoc_insertion_point(field_mutable:google.protobuf.Enum.options) + return options_.Mutable(index); +} +inline ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::Option >* +Enum::mutable_options() { + // @@protoc_insertion_point(field_mutable_list:google.protobuf.Enum.options) + return &options_; +} +inline const ::PROTOBUF_NAMESPACE_ID::Option& Enum::_internal_options(int index) const { + return options_.Get(index); +} +inline const ::PROTOBUF_NAMESPACE_ID::Option& Enum::options(int index) const { + // @@protoc_insertion_point(field_get:google.protobuf.Enum.options) + return _internal_options(index); +} +inline ::PROTOBUF_NAMESPACE_ID::Option* Enum::_internal_add_options() { + return options_.Add(); +} +inline ::PROTOBUF_NAMESPACE_ID::Option* Enum::add_options() { + ::PROTOBUF_NAMESPACE_ID::Option* _add = _internal_add_options(); + // @@protoc_insertion_point(field_add:google.protobuf.Enum.options) + return _add; +} +inline const ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::Option >& +Enum::options() const { + // @@protoc_insertion_point(field_list:google.protobuf.Enum.options) + return options_; +} + +// .google.protobuf.SourceContext source_context = 4; +inline bool Enum::_internal_has_source_context() const { + return this != internal_default_instance() && source_context_ != nullptr; +} +inline bool Enum::has_source_context() const { + return _internal_has_source_context(); +} +inline const ::PROTOBUF_NAMESPACE_ID::SourceContext& Enum::_internal_source_context() const { + const ::PROTOBUF_NAMESPACE_ID::SourceContext* p = source_context_; + return p != nullptr ? *p : reinterpret_cast<const ::PROTOBUF_NAMESPACE_ID::SourceContext&>( + ::PROTOBUF_NAMESPACE_ID::_SourceContext_default_instance_); +} +inline const ::PROTOBUF_NAMESPACE_ID::SourceContext& Enum::source_context() const { + // @@protoc_insertion_point(field_get:google.protobuf.Enum.source_context) + return _internal_source_context(); +} +inline void Enum::unsafe_arena_set_allocated_source_context( + ::PROTOBUF_NAMESPACE_ID::SourceContext* source_context) { + if (GetArenaForAllocation() == nullptr) { + delete reinterpret_cast<::PROTOBUF_NAMESPACE_ID::MessageLite*>(source_context_); + } + source_context_ = source_context; + if (source_context) { + + } else { + + } + // @@protoc_insertion_point(field_unsafe_arena_set_allocated:google.protobuf.Enum.source_context) +} +inline ::PROTOBUF_NAMESPACE_ID::SourceContext* Enum::release_source_context() { + + ::PROTOBUF_NAMESPACE_ID::SourceContext* temp = source_context_; + source_context_ = nullptr; +#ifdef PROTOBUF_FORCE_COPY_IN_RELEASE + auto* old = reinterpret_cast<::PROTOBUF_NAMESPACE_ID::MessageLite*>(temp); + temp = ::PROTOBUF_NAMESPACE_ID::internal::DuplicateIfNonNull(temp); + if (GetArenaForAllocation() == nullptr) { delete old; } +#else // PROTOBUF_FORCE_COPY_IN_RELEASE + if (GetArenaForAllocation() != nullptr) { + temp = ::PROTOBUF_NAMESPACE_ID::internal::DuplicateIfNonNull(temp); + } +#endif // !PROTOBUF_FORCE_COPY_IN_RELEASE + return temp; +} +inline ::PROTOBUF_NAMESPACE_ID::SourceContext* Enum::unsafe_arena_release_source_context() { + // @@protoc_insertion_point(field_release:google.protobuf.Enum.source_context) + + ::PROTOBUF_NAMESPACE_ID::SourceContext* temp = source_context_; + source_context_ = nullptr; + return temp; +} +inline ::PROTOBUF_NAMESPACE_ID::SourceContext* Enum::_internal_mutable_source_context() { + + if (source_context_ == nullptr) { + auto* p = CreateMaybeMessage<::PROTOBUF_NAMESPACE_ID::SourceContext>(GetArenaForAllocation()); + source_context_ = p; + } + return source_context_; +} +inline ::PROTOBUF_NAMESPACE_ID::SourceContext* Enum::mutable_source_context() { + ::PROTOBUF_NAMESPACE_ID::SourceContext* _msg = _internal_mutable_source_context(); + // @@protoc_insertion_point(field_mutable:google.protobuf.Enum.source_context) + return _msg; +} +inline void Enum::set_allocated_source_context(::PROTOBUF_NAMESPACE_ID::SourceContext* source_context) { + ::PROTOBUF_NAMESPACE_ID::Arena* message_arena = GetArenaForAllocation(); + if (message_arena == nullptr) { + delete reinterpret_cast< ::PROTOBUF_NAMESPACE_ID::MessageLite*>(source_context_); + } + if (source_context) { + ::PROTOBUF_NAMESPACE_ID::Arena* submessage_arena = + ::PROTOBUF_NAMESPACE_ID::Arena::InternalHelper< + ::PROTOBUF_NAMESPACE_ID::MessageLite>::GetOwningArena( + reinterpret_cast<::PROTOBUF_NAMESPACE_ID::MessageLite*>(source_context)); + if (message_arena != submessage_arena) { + source_context = ::PROTOBUF_NAMESPACE_ID::internal::GetOwnedMessage( + message_arena, source_context, submessage_arena); + } + + } else { + + } + source_context_ = source_context; + // @@protoc_insertion_point(field_set_allocated:google.protobuf.Enum.source_context) +} + +// .google.protobuf.Syntax syntax = 5; +inline void Enum::clear_syntax() { + syntax_ = 0; +} +inline ::PROTOBUF_NAMESPACE_ID::Syntax Enum::_internal_syntax() const { + return static_cast< ::PROTOBUF_NAMESPACE_ID::Syntax >(syntax_); +} +inline ::PROTOBUF_NAMESPACE_ID::Syntax Enum::syntax() const { + // @@protoc_insertion_point(field_get:google.protobuf.Enum.syntax) + return _internal_syntax(); +} +inline void Enum::_internal_set_syntax(::PROTOBUF_NAMESPACE_ID::Syntax value) { + + syntax_ = value; +} +inline void Enum::set_syntax(::PROTOBUF_NAMESPACE_ID::Syntax value) { + _internal_set_syntax(value); + // @@protoc_insertion_point(field_set:google.protobuf.Enum.syntax) +} + +// ------------------------------------------------------------------- + +// EnumValue + +// string name = 1; +inline void EnumValue::clear_name() { + name_.ClearToEmpty(); +} +inline const TProtoStringType& EnumValue::name() const { + // @@protoc_insertion_point(field_get:google.protobuf.EnumValue.name) + return _internal_name(); +} +template <typename ArgT0, typename... ArgT> +inline PROTOBUF_ALWAYS_INLINE +void EnumValue::set_name(ArgT0&& arg0, ArgT... args) { + + name_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, static_cast<ArgT0 &&>(arg0), args..., GetArenaForAllocation()); + // @@protoc_insertion_point(field_set:google.protobuf.EnumValue.name) +} +inline TProtoStringType* EnumValue::mutable_name() { + TProtoStringType* _s = _internal_mutable_name(); + // @@protoc_insertion_point(field_mutable:google.protobuf.EnumValue.name) + return _s; +} +inline const TProtoStringType& EnumValue::_internal_name() const { + return name_.Get(); +} +inline void EnumValue::_internal_set_name(const TProtoStringType& value) { + + name_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, value, GetArenaForAllocation()); +} +inline TProtoStringType* EnumValue::_internal_mutable_name() { + + return name_.Mutable(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, GetArenaForAllocation()); +} +inline TProtoStringType* EnumValue::release_name() { + // @@protoc_insertion_point(field_release:google.protobuf.EnumValue.name) + return name_.Release(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArenaForAllocation()); +} +inline void EnumValue::set_allocated_name(TProtoStringType* name) { + if (name != nullptr) { + + } else { + + } + name_.SetAllocated(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), name, + GetArenaForAllocation()); +#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING + if (name_.IsDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited())) { + name_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation()); + } +#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING + // @@protoc_insertion_point(field_set_allocated:google.protobuf.EnumValue.name) +} + +// int32 number = 2; +inline void EnumValue::clear_number() { + number_ = 0; +} +inline arc_i32 EnumValue::_internal_number() const { + return number_; +} +inline arc_i32 EnumValue::number() const { + // @@protoc_insertion_point(field_get:google.protobuf.EnumValue.number) + return _internal_number(); +} +inline void EnumValue::_internal_set_number(arc_i32 value) { + + number_ = value; +} +inline void EnumValue::set_number(arc_i32 value) { + _internal_set_number(value); + // @@protoc_insertion_point(field_set:google.protobuf.EnumValue.number) +} + +// repeated .google.protobuf.Option options = 3; +inline int EnumValue::_internal_options_size() const { + return options_.size(); +} +inline int EnumValue::options_size() const { + return _internal_options_size(); +} +inline void EnumValue::clear_options() { + options_.Clear(); +} +inline ::PROTOBUF_NAMESPACE_ID::Option* EnumValue::mutable_options(int index) { + // @@protoc_insertion_point(field_mutable:google.protobuf.EnumValue.options) + return options_.Mutable(index); +} +inline ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::Option >* +EnumValue::mutable_options() { + // @@protoc_insertion_point(field_mutable_list:google.protobuf.EnumValue.options) + return &options_; +} +inline const ::PROTOBUF_NAMESPACE_ID::Option& EnumValue::_internal_options(int index) const { + return options_.Get(index); +} +inline const ::PROTOBUF_NAMESPACE_ID::Option& EnumValue::options(int index) const { + // @@protoc_insertion_point(field_get:google.protobuf.EnumValue.options) + return _internal_options(index); +} +inline ::PROTOBUF_NAMESPACE_ID::Option* EnumValue::_internal_add_options() { + return options_.Add(); +} +inline ::PROTOBUF_NAMESPACE_ID::Option* EnumValue::add_options() { + ::PROTOBUF_NAMESPACE_ID::Option* _add = _internal_add_options(); + // @@protoc_insertion_point(field_add:google.protobuf.EnumValue.options) + return _add; +} +inline const ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::Option >& +EnumValue::options() const { + // @@protoc_insertion_point(field_list:google.protobuf.EnumValue.options) + return options_; +} + +// ------------------------------------------------------------------- + +// Option + +// string name = 1; +inline void Option::clear_name() { + name_.ClearToEmpty(); +} +inline const TProtoStringType& Option::name() const { + // @@protoc_insertion_point(field_get:google.protobuf.Option.name) + return _internal_name(); +} +template <typename ArgT0, typename... ArgT> +inline PROTOBUF_ALWAYS_INLINE +void Option::set_name(ArgT0&& arg0, ArgT... args) { + + name_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, static_cast<ArgT0 &&>(arg0), args..., GetArenaForAllocation()); + // @@protoc_insertion_point(field_set:google.protobuf.Option.name) +} +inline TProtoStringType* Option::mutable_name() { + TProtoStringType* _s = _internal_mutable_name(); + // @@protoc_insertion_point(field_mutable:google.protobuf.Option.name) + return _s; +} +inline const TProtoStringType& Option::_internal_name() const { + return name_.Get(); +} +inline void Option::_internal_set_name(const TProtoStringType& value) { + + name_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, value, GetArenaForAllocation()); +} +inline TProtoStringType* Option::_internal_mutable_name() { + + return name_.Mutable(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, GetArenaForAllocation()); +} +inline TProtoStringType* Option::release_name() { + // @@protoc_insertion_point(field_release:google.protobuf.Option.name) + return name_.Release(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArenaForAllocation()); +} +inline void Option::set_allocated_name(TProtoStringType* name) { + if (name != nullptr) { + + } else { + + } + name_.SetAllocated(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), name, + GetArenaForAllocation()); +#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING + if (name_.IsDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited())) { + name_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation()); + } +#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING + // @@protoc_insertion_point(field_set_allocated:google.protobuf.Option.name) +} + +// .google.protobuf.Any value = 2; +inline bool Option::_internal_has_value() const { + return this != internal_default_instance() && value_ != nullptr; +} +inline bool Option::has_value() const { + return _internal_has_value(); +} +inline const ::PROTOBUF_NAMESPACE_ID::Any& Option::_internal_value() const { + const ::PROTOBUF_NAMESPACE_ID::Any* p = value_; + return p != nullptr ? *p : reinterpret_cast<const ::PROTOBUF_NAMESPACE_ID::Any&>( + ::PROTOBUF_NAMESPACE_ID::_Any_default_instance_); +} +inline const ::PROTOBUF_NAMESPACE_ID::Any& Option::value() const { + // @@protoc_insertion_point(field_get:google.protobuf.Option.value) + return _internal_value(); +} +inline void Option::unsafe_arena_set_allocated_value( + ::PROTOBUF_NAMESPACE_ID::Any* value) { + if (GetArenaForAllocation() == nullptr) { + delete reinterpret_cast<::PROTOBUF_NAMESPACE_ID::MessageLite*>(value_); + } + value_ = value; + if (value) { + + } else { + + } + // @@protoc_insertion_point(field_unsafe_arena_set_allocated:google.protobuf.Option.value) +} +inline ::PROTOBUF_NAMESPACE_ID::Any* Option::release_value() { + + ::PROTOBUF_NAMESPACE_ID::Any* temp = value_; + value_ = nullptr; +#ifdef PROTOBUF_FORCE_COPY_IN_RELEASE + auto* old = reinterpret_cast<::PROTOBUF_NAMESPACE_ID::MessageLite*>(temp); + temp = ::PROTOBUF_NAMESPACE_ID::internal::DuplicateIfNonNull(temp); + if (GetArenaForAllocation() == nullptr) { delete old; } +#else // PROTOBUF_FORCE_COPY_IN_RELEASE + if (GetArenaForAllocation() != nullptr) { + temp = ::PROTOBUF_NAMESPACE_ID::internal::DuplicateIfNonNull(temp); + } +#endif // !PROTOBUF_FORCE_COPY_IN_RELEASE + return temp; +} +inline ::PROTOBUF_NAMESPACE_ID::Any* Option::unsafe_arena_release_value() { + // @@protoc_insertion_point(field_release:google.protobuf.Option.value) + + ::PROTOBUF_NAMESPACE_ID::Any* temp = value_; + value_ = nullptr; + return temp; +} +inline ::PROTOBUF_NAMESPACE_ID::Any* Option::_internal_mutable_value() { + + if (value_ == nullptr) { + auto* p = CreateMaybeMessage<::PROTOBUF_NAMESPACE_ID::Any>(GetArenaForAllocation()); + value_ = p; + } + return value_; +} +inline ::PROTOBUF_NAMESPACE_ID::Any* Option::mutable_value() { + ::PROTOBUF_NAMESPACE_ID::Any* _msg = _internal_mutable_value(); + // @@protoc_insertion_point(field_mutable:google.protobuf.Option.value) + return _msg; +} +inline void Option::set_allocated_value(::PROTOBUF_NAMESPACE_ID::Any* value) { + ::PROTOBUF_NAMESPACE_ID::Arena* message_arena = GetArenaForAllocation(); + if (message_arena == nullptr) { + delete reinterpret_cast< ::PROTOBUF_NAMESPACE_ID::MessageLite*>(value_); + } + if (value) { + ::PROTOBUF_NAMESPACE_ID::Arena* submessage_arena = + ::PROTOBUF_NAMESPACE_ID::Arena::InternalHelper< + ::PROTOBUF_NAMESPACE_ID::MessageLite>::GetOwningArena( + reinterpret_cast<::PROTOBUF_NAMESPACE_ID::MessageLite*>(value)); + if (message_arena != submessage_arena) { + value = ::PROTOBUF_NAMESPACE_ID::internal::GetOwnedMessage( + message_arena, value, submessage_arena); + } + + } else { + + } + value_ = value; + // @@protoc_insertion_point(field_set_allocated:google.protobuf.Option.value) +} + +#ifdef __GNUC__ + #pragma GCC diagnostic pop +#endif // __GNUC__ +// ------------------------------------------------------------------- + +// ------------------------------------------------------------------- + +// ------------------------------------------------------------------- + +// ------------------------------------------------------------------- + + +// @@protoc_insertion_point(namespace_scope) + +PROTOBUF_NAMESPACE_CLOSE + +PROTOBUF_NAMESPACE_OPEN + +template <> struct is_proto_enum< ::PROTOBUF_NAMESPACE_ID::Field_Kind> : ::std::true_type {}; +template <> +inline const EnumDescriptor* GetEnumDescriptor< ::PROTOBUF_NAMESPACE_ID::Field_Kind>() { + return ::PROTOBUF_NAMESPACE_ID::Field_Kind_descriptor(); +} +template <> struct is_proto_enum< ::PROTOBUF_NAMESPACE_ID::Field_Cardinality> : ::std::true_type {}; +template <> +inline const EnumDescriptor* GetEnumDescriptor< ::PROTOBUF_NAMESPACE_ID::Field_Cardinality>() { + return ::PROTOBUF_NAMESPACE_ID::Field_Cardinality_descriptor(); +} +template <> struct is_proto_enum< ::PROTOBUF_NAMESPACE_ID::Syntax> : ::std::true_type {}; +template <> +inline const EnumDescriptor* GetEnumDescriptor< ::PROTOBUF_NAMESPACE_ID::Syntax>() { + return ::PROTOBUF_NAMESPACE_ID::Syntax_descriptor(); +} + +PROTOBUF_NAMESPACE_CLOSE + +// @@protoc_insertion_point(global_scope) + +#include <google/protobuf/port_undef.inc> +#endif // GOOGLE_PROTOBUF_INCLUDED_GOOGLE_PROTOBUF_INCLUDED_google_2fprotobuf_2ftype_2eproto diff --git a/contrib/libs/protobuf_old/src/google/protobuf/type.proto b/contrib/libs/protobuf_old/src/google/protobuf/type.proto new file mode 100644 index 0000000000..d3f6a68b83 --- /dev/null +++ b/contrib/libs/protobuf_old/src/google/protobuf/type.proto @@ -0,0 +1,187 @@ +// 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 google.protobuf; + +import "google/protobuf/any.proto"; +import "google/protobuf/source_context.proto"; + +option csharp_namespace = "Google.Protobuf.WellKnownTypes"; +option cc_enable_arenas = true; +option java_package = "com.google.protobuf"; +option java_outer_classname = "TypeProto"; +option java_multiple_files = true; +option objc_class_prefix = "GPB"; +option go_package = "google.golang.org/protobuf/types/known/typepb"; + +// A protocol buffer message type. +message Type { + // The fully qualified message name. + string name = 1; + // The list of fields. + repeated Field fields = 2; + // The list of types appearing in `oneof` definitions in this type. + repeated string oneofs = 3; + // The protocol buffer options. + repeated Option options = 4; + // The source context. + SourceContext source_context = 5; + // The source syntax. + Syntax syntax = 6; +} + +// A single field of a message type. +message Field { + // Basic field types. + enum Kind { + // Field type unknown. + TYPE_UNKNOWN = 0; + // Field type double. + TYPE_DOUBLE = 1; + // Field type float. + TYPE_FLOAT = 2; + // Field type int64. + TYPE_INT64 = 3; + // Field type uint64. + TYPE_UINT64 = 4; + // Field type int32. + TYPE_INT32 = 5; + // Field type fixed64. + TYPE_FIXED64 = 6; + // Field type fixed32. + TYPE_FIXED32 = 7; + // Field type bool. + TYPE_BOOL = 8; + // Field type string. + TYPE_STRING = 9; + // Field type group. Proto2 syntax only, and deprecated. + TYPE_GROUP = 10; + // Field type message. + TYPE_MESSAGE = 11; + // Field type bytes. + TYPE_BYTES = 12; + // Field type uint32. + TYPE_UINT32 = 13; + // Field type enum. + TYPE_ENUM = 14; + // Field type sfixed32. + TYPE_SFIXED32 = 15; + // Field type sfixed64. + TYPE_SFIXED64 = 16; + // Field type sint32. + TYPE_SINT32 = 17; + // Field type sint64. + TYPE_SINT64 = 18; + } + + // Whether a field is optional, required, or repeated. + enum Cardinality { + // For fields with unknown cardinality. + CARDINALITY_UNKNOWN = 0; + // For optional fields. + CARDINALITY_OPTIONAL = 1; + // For required fields. Proto2 syntax only. + CARDINALITY_REQUIRED = 2; + // For repeated fields. + CARDINALITY_REPEATED = 3; + } + + // The field type. + Kind kind = 1; + // The field cardinality. + Cardinality cardinality = 2; + // The field number. + int32 number = 3; + // The field name. + string name = 4; + // The field type URL, without the scheme, for message or enumeration + // types. Example: `"type.googleapis.com/google.protobuf.Timestamp"`. + string type_url = 6; + // The index of the field type in `Type.oneofs`, for message or enumeration + // types. The first type has index 1; zero means the type is not in the list. + int32 oneof_index = 7; + // Whether to use alternative packed wire representation. + bool packed = 8; + // The protocol buffer options. + repeated Option options = 9; + // The field JSON name. + string json_name = 10; + // The string value of the default value of this field. Proto2 syntax only. + string default_value = 11; +} + +// Enum type definition. +message Enum { + // Enum type name. + string name = 1; + // Enum value definitions. + repeated EnumValue enumvalue = 2; + // Protocol buffer options. + repeated Option options = 3; + // The source context. + SourceContext source_context = 4; + // The source syntax. + Syntax syntax = 5; +} + +// Enum value definition. +message EnumValue { + // Enum value name. + string name = 1; + // Enum value number. + int32 number = 2; + // Protocol buffer options. + repeated Option options = 3; +} + +// A protocol buffer option, which can be attached to a message, field, +// enumeration, etc. +message Option { + // The option's name. For protobuf built-in options (options defined in + // descriptor.proto), this is the short name. For example, `"map_entry"`. + // For custom options, it should be the fully-qualified name. For example, + // `"google.api.http"`. + string name = 1; + // The option's value packed in an Any message. If the value is a primitive, + // the corresponding wrapper type defined in google/protobuf/wrappers.proto + // should be used. If the value is an enum, it should be stored as an int32 + // value using the google.protobuf.Int32Value type. + Any value = 2; +} + +// The syntax in which a protocol buffer element is defined. +enum Syntax { + // Syntax `proto2`. + SYNTAX_PROTO2 = 0; + // Syntax `proto3`. + SYNTAX_PROTO3 = 1; +} diff --git a/contrib/libs/protobuf_old/src/google/protobuf/unknown_field_set.cc b/contrib/libs/protobuf_old/src/google/protobuf/unknown_field_set.cc new file mode 100644 index 0000000000..5715434b0f --- /dev/null +++ b/contrib/libs/protobuf_old/src/google/protobuf/unknown_field_set.cc @@ -0,0 +1,334 @@ +// 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: kenton@google.com (Kenton Varda) +// Based on original Protocol Buffers design by +// Sanjay Ghemawat, Jeff Dean, and others. + +#include <google/protobuf/unknown_field_set.h> + +#include <google/protobuf/stubs/logging.h> +#include <google/protobuf/stubs/common.h> +#include <google/protobuf/parse_context.h> +#include <google/protobuf/io/coded_stream.h> +#include <google/protobuf/io/zero_copy_stream.h> +#include <google/protobuf/io/zero_copy_stream_impl.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/wire_format.h> +#include <google/protobuf/wire_format_lite.h> +#include <google/protobuf/stubs/stl_util.h> + +#include <google/protobuf/port_def.inc> + +namespace google { +namespace protobuf { + +const UnknownFieldSet& UnknownFieldSet::default_instance() { + static auto instance = internal::OnShutdownDelete(new UnknownFieldSet()); + return *instance; +} + +void UnknownFieldSet::ClearFallback() { + GOOGLE_DCHECK(!fields_.empty()); + int n = fields_.size(); + do { + (fields_)[--n].Delete(); + } while (n > 0); + fields_.clear(); +} + +void UnknownFieldSet::InternalMergeFrom(const UnknownFieldSet& other) { + int other_field_count = other.field_count(); + if (other_field_count > 0) { + fields_.reserve(fields_.size() + other_field_count); + for (int i = 0; i < other_field_count; i++) { + fields_.push_back((other.fields_)[i]); + fields_.back().DeepCopy((other.fields_)[i]); + } + } +} + +void UnknownFieldSet::MergeFrom(const UnknownFieldSet& other) { + int other_field_count = other.field_count(); + if (other_field_count > 0) { + fields_.reserve(fields_.size() + other_field_count); + for (int i = 0; i < other_field_count; i++) { + fields_.push_back((other.fields_)[i]); + fields_.back().DeepCopy((other.fields_)[i]); + } + } +} + +// A specialized MergeFrom for performance when we are merging from an UFS that +// is temporary and can be destroyed in the process. +void UnknownFieldSet::MergeFromAndDestroy(UnknownFieldSet* other) { + if (fields_.empty()) { + fields_ = std::move(other->fields_); + } else { + fields_.insert(fields_.end(), + std::make_move_iterator(other->fields_.begin()), + std::make_move_iterator(other->fields_.end())); + } + other->fields_.clear(); +} + +void UnknownFieldSet::MergeToInternalMetadata( + const UnknownFieldSet& other, internal::InternalMetadata* metadata) { + metadata->mutable_unknown_fields<UnknownFieldSet>()->MergeFrom(other); +} + +size_t UnknownFieldSet::SpaceUsedExcludingSelfLong() const { + if (fields_.empty()) return 0; + + size_t total_size = sizeof(fields_) + sizeof(UnknownField) * fields_.size(); + + for (const UnknownField& field : fields_) { + switch (field.type()) { + case UnknownField::TYPE_LENGTH_DELIMITED: + total_size += sizeof(*field.data_.length_delimited_.string_value) + + internal::StringSpaceUsedExcludingSelfLong( + *field.data_.length_delimited_.string_value); + break; + case UnknownField::TYPE_GROUP: + total_size += field.data_.group_->SpaceUsedLong(); + break; + default: + break; + } + } + return total_size; +} + +size_t UnknownFieldSet::SpaceUsedLong() const { + return sizeof(*this) + SpaceUsedExcludingSelf(); +} + +void UnknownFieldSet::AddVarint(int number, arc_ui64 value) { + UnknownField field; + field.number_ = number; + field.SetType(UnknownField::TYPE_VARINT); + field.data_.varint_ = value; + fields_.push_back(field); +} + +void UnknownFieldSet::AddFixed32(int number, arc_ui32 value) { + UnknownField field; + field.number_ = number; + field.SetType(UnknownField::TYPE_FIXED32); + field.data_.fixed32_ = value; + fields_.push_back(field); +} + +void UnknownFieldSet::AddFixed64(int number, arc_ui64 value) { + UnknownField field; + field.number_ = number; + field.SetType(UnknownField::TYPE_FIXED64); + field.data_.fixed64_ = value; + fields_.push_back(field); +} + +TProtoStringType* UnknownFieldSet::AddLengthDelimited(int number) { + UnknownField field; + field.number_ = number; + field.SetType(UnknownField::TYPE_LENGTH_DELIMITED); + field.data_.length_delimited_.string_value = new TProtoStringType; + fields_.push_back(field); + return field.data_.length_delimited_.string_value; +} + + +UnknownFieldSet* UnknownFieldSet::AddGroup(int number) { + UnknownField field; + field.number_ = number; + field.SetType(UnknownField::TYPE_GROUP); + field.data_.group_ = new UnknownFieldSet; + fields_.push_back(field); + return field.data_.group_; +} + +void UnknownFieldSet::AddField(const UnknownField& field) { + fields_.push_back(field); + fields_.back().DeepCopy(field); +} + +void UnknownFieldSet::DeleteSubrange(int start, int num) { + // Delete the specified fields. + for (int i = 0; i < num; ++i) { + (fields_)[i + start].Delete(); + } + // Slide down the remaining fields. + for (size_t i = start + num; i < fields_.size(); ++i) { + (fields_)[i - num] = (fields_)[i]; + } + // Pop off the # of deleted fields. + for (int i = 0; i < num; ++i) { + fields_.pop_back(); + } +} + +void UnknownFieldSet::DeleteByNumber(int number) { + size_t left = 0; // The number of fields left after deletion. + for (size_t i = 0; i < fields_.size(); ++i) { + UnknownField* field = &(fields_)[i]; + if (field->number() == number) { + field->Delete(); + } else { + if (i != left) { + (fields_)[left] = (fields_)[i]; + } + ++left; + } + } + fields_.resize(left); +} + +bool UnknownFieldSet::MergeFromCodedStream(io::CodedInputStream* input) { + UnknownFieldSet other; + if (internal::WireFormat::SkipMessage(input, &other) && + input->ConsumedEntireMessage()) { + MergeFromAndDestroy(&other); + return true; + } else { + return false; + } +} + +bool UnknownFieldSet::ParseFromCodedStream(io::CodedInputStream* input) { + Clear(); + return MergeFromCodedStream(input); +} + +bool UnknownFieldSet::ParseFromZeroCopyStream(io::ZeroCopyInputStream* input) { + io::CodedInputStream coded_input(input); + return (ParseFromCodedStream(&coded_input) && + coded_input.ConsumedEntireMessage()); +} + +bool UnknownFieldSet::ParseFromArray(const void* data, int size) { + io::ArrayInputStream input(data, size); + return ParseFromZeroCopyStream(&input); +} + +void UnknownField::Delete() { + switch (type()) { + case UnknownField::TYPE_LENGTH_DELIMITED: + delete data_.length_delimited_.string_value; + break; + case UnknownField::TYPE_GROUP: + delete data_.group_; + break; + default: + break; + } +} + +void UnknownField::DeepCopy(const UnknownField& other) { + (void)other; // Parameter is used by Google-internal code. + switch (type()) { + case UnknownField::TYPE_LENGTH_DELIMITED: + data_.length_delimited_.string_value = + new TProtoStringType(*data_.length_delimited_.string_value); + break; + case UnknownField::TYPE_GROUP: { + UnknownFieldSet* group = new UnknownFieldSet(); + group->InternalMergeFrom(*data_.group_); + data_.group_ = group; + break; + } + default: + break; + } +} + + +uint8_t* UnknownField::InternalSerializeLengthDelimitedNoTag( + uint8_t* target, io::EpsCopyOutputStream* stream) const { + GOOGLE_DCHECK_EQ(TYPE_LENGTH_DELIMITED, type()); + const TProtoStringType& data = *data_.length_delimited_.string_value; + target = io::CodedOutputStream::WriteVarint32ToArray(data.size(), target); + target = stream->WriteRaw(data.data(), data.size(), target); + return target; +} + +namespace internal { + +class UnknownFieldParserHelper { + public: + explicit UnknownFieldParserHelper(UnknownFieldSet* unknown) + : unknown_(unknown) {} + + void AddVarint(arc_ui32 num, arc_ui64 value) { + unknown_->AddVarint(num, value); + } + void AddFixed64(arc_ui32 num, arc_ui64 value) { + unknown_->AddFixed64(num, value); + } + const char* ParseLengthDelimited(arc_ui32 num, const char* ptr, + ParseContext* ctx) { + TProtoStringType* s = unknown_->AddLengthDelimited(num); + int size = ReadSize(&ptr); + GOOGLE_PROTOBUF_PARSER_ASSERT(ptr); + return ctx->ReadString(ptr, size, s); + } + const char* ParseGroup(arc_ui32 num, const char* ptr, ParseContext* ctx) { + UnknownFieldParserHelper child(unknown_->AddGroup(num)); + return ctx->ParseGroup(&child, ptr, num * 8 + 3); + } + void AddFixed32(arc_ui32 num, arc_ui32 value) { + unknown_->AddFixed32(num, value); + } + + const char* _InternalParse(const char* ptr, ParseContext* ctx) { + return WireFormatParser(*this, ptr, ctx); + } + + private: + UnknownFieldSet* unknown_; +}; + +const char* UnknownGroupParse(UnknownFieldSet* unknown, const char* ptr, + ParseContext* ctx) { + UnknownFieldParserHelper field_parser(unknown); + return WireFormatParser(field_parser, ptr, ctx); +} + +const char* UnknownFieldParse(arc_ui64 tag, UnknownFieldSet* unknown, + const char* ptr, ParseContext* ctx) { + UnknownFieldParserHelper field_parser(unknown); + return FieldParser(tag, field_parser, ptr, ctx); +} + +} // namespace internal +} // namespace protobuf +} // namespace google + +#include <google/protobuf/port_undef.inc> diff --git a/contrib/libs/protobuf_old/src/google/protobuf/unknown_field_set.h b/contrib/libs/protobuf_old/src/google/protobuf/unknown_field_set.h new file mode 100644 index 0000000000..bfe16d6d7b --- /dev/null +++ b/contrib/libs/protobuf_old/src/google/protobuf/unknown_field_set.h @@ -0,0 +1,411 @@ +// 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: kenton@google.com (Kenton Varda) +// Based on original Protocol Buffers design by +// Sanjay Ghemawat, Jeff Dean, and others. +// +// Contains classes used to keep track of unrecognized fields seen while +// parsing a protocol message. + +#ifndef GOOGLE_PROTOBUF_UNKNOWN_FIELD_SET_H__ +#define GOOGLE_PROTOBUF_UNKNOWN_FIELD_SET_H__ + +#include <assert.h> + +#include <string> +#include <vector> + +#include <google/protobuf/stubs/common.h> +#include <google/protobuf/stubs/logging.h> +#include <google/protobuf/parse_context.h> +#include <google/protobuf/io/coded_stream.h> +#include <google/protobuf/io/zero_copy_stream_impl_lite.h> +#include <google/protobuf/message_lite.h> +#include <google/protobuf/port.h> + +#include <google/protobuf/port_def.inc> + +#ifdef SWIG +#error "You cannot SWIG proto headers" +#endif + +namespace google { +namespace protobuf { +namespace internal { +class InternalMetadata; // metadata_lite.h +class WireFormat; // wire_format.h +class MessageSetFieldSkipperUsingCord; +// extension_set_heavy.cc +} // namespace internal + +class Message; // message.h +class UnknownField; // below + +// An UnknownFieldSet contains fields that were encountered while parsing a +// message but were not defined by its type. Keeping track of these can be +// useful, especially in that they may be written if the message is serialized +// again without being cleared in between. This means that software which +// simply receives messages and forwards them to other servers does not need +// to be updated every time a new field is added to the message definition. +// +// To get the UnknownFieldSet attached to any message, call +// Reflection::GetUnknownFields(). +// +// This class is necessarily tied to the protocol buffer wire format, unlike +// the Reflection interface which is independent of any serialization scheme. +class PROTOBUF_EXPORT UnknownFieldSet { + public: + UnknownFieldSet(); + ~UnknownFieldSet(); + + // Remove all fields. + inline void Clear(); + + // Remove all fields and deallocate internal data objects + void ClearAndFreeMemory(); + + // Is this set empty? + inline bool empty() const; + + // Merge the contents of some other UnknownFieldSet with this one. + void MergeFrom(const UnknownFieldSet& other); + + // Similar to above, but this function will destroy the contents of other. + void MergeFromAndDestroy(UnknownFieldSet* other); + + // Merge the contents an UnknownFieldSet with the UnknownFieldSet in + // *metadata, if there is one. If *metadata doesn't have an UnknownFieldSet + // then add one to it and make it be a copy of the first arg. + static void MergeToInternalMetadata(const UnknownFieldSet& other, + internal::InternalMetadata* metadata); + + // Swaps the contents of some other UnknownFieldSet with this one. + inline void Swap(UnknownFieldSet* x); + + // Computes (an estimate of) the total number of bytes currently used for + // storing the unknown fields in memory. Does NOT include + // sizeof(*this) in the calculation. + size_t SpaceUsedExcludingSelfLong() const; + + int SpaceUsedExcludingSelf() const { + return internal::ToIntSize(SpaceUsedExcludingSelfLong()); + } + + // Version of SpaceUsed() including sizeof(*this). + size_t SpaceUsedLong() const; + + int SpaceUsed() const { return internal::ToIntSize(SpaceUsedLong()); } + + // Returns the number of fields present in the UnknownFieldSet. + inline int field_count() const; + // Get a field in the set, where 0 <= index < field_count(). The fields + // appear in the order in which they were added. + inline const UnknownField& field(int index) const; + // Get a mutable pointer to a field in the set, where + // 0 <= index < field_count(). The fields appear in the order in which + // they were added. + inline UnknownField* mutable_field(int index); + + // Adding fields --------------------------------------------------- + + void AddVarint(int number, arc_ui64 value); + void AddFixed32(int number, arc_ui32 value); + void AddFixed64(int number, arc_ui64 value); + void AddLengthDelimited(int number, const TProtoStringType& value); + TProtoStringType* AddLengthDelimited(int number); + UnknownFieldSet* AddGroup(int number); + + // Adds an unknown field from another set. + void AddField(const UnknownField& field); + + // Delete fields with indices in the range [start .. start+num-1]. + // Caution: implementation moves all fields with indices [start+num .. ]. + void DeleteSubrange(int start, int num); + + // Delete all fields with a specific field number. The order of left fields + // is preserved. + // Caution: implementation moves all fields after the first deleted field. + void DeleteByNumber(int number); + + // Parsing helpers ------------------------------------------------- + // These work exactly like the similarly-named methods of Message. + + bool MergeFromCodedStream(io::CodedInputStream* input); + bool ParseFromCodedStream(io::CodedInputStream* input); + bool ParseFromZeroCopyStream(io::ZeroCopyInputStream* input); + bool ParseFromArray(const void* data, int size); + inline bool ParseFromString(const TProtoStringType& data) { + return ParseFromArray(data.data(), static_cast<int>(data.size())); + } + + // Merges this message's unknown field data (if any). This works whether + // the message is a lite or full proto (for legacy reasons, lite and full + // return different types for MessageType::unknown_fields()). + template <typename MessageType> + bool MergeFromMessage(const MessageType& message); + + static const UnknownFieldSet& default_instance(); + + private: + // For InternalMergeFrom + friend class UnknownField; + // Merges from other UnknownFieldSet. This method assumes, that this object + // is newly created and has no fields. + void InternalMergeFrom(const UnknownFieldSet& other); + void ClearFallback(); + + template <typename MessageType, + typename std::enable_if< + std::is_base_of<Message, MessageType>::value, int>::type = 0> + bool InternalMergeFromMessage(const MessageType& message) { + MergeFrom(message.GetReflection()->GetUnknownFields(message)); + return true; + } + + template <typename MessageType, + typename std::enable_if< + std::is_base_of<MessageLite, MessageType>::value && + !std::is_base_of<Message, MessageType>::value, + int>::type = 0> + bool InternalMergeFromMessage(const MessageType& message) { + const auto& unknown_fields = message.unknown_fields(); + io::ArrayInputStream array_stream(unknown_fields.data(), + unknown_fields.size()); + io::CodedInputStream coded_stream(&array_stream); + return MergeFromCodedStream(&coded_stream); + } + + std::vector<UnknownField> fields_; + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(UnknownFieldSet); +}; + +namespace internal { + +inline void WriteVarint(arc_ui32 num, arc_ui64 val, UnknownFieldSet* unknown) { + unknown->AddVarint(num, val); +} +inline void WriteLengthDelimited(arc_ui32 num, StringPiece val, + UnknownFieldSet* unknown) { + unknown->AddLengthDelimited(num)->assign(val.data(), val.size()); +} + +PROTOBUF_EXPORT +const char* UnknownGroupParse(UnknownFieldSet* unknown, const char* ptr, + ParseContext* ctx); +PROTOBUF_EXPORT +const char* UnknownFieldParse(arc_ui64 tag, UnknownFieldSet* unknown, + const char* ptr, ParseContext* ctx); + +} // namespace internal + +// Represents one field in an UnknownFieldSet. +class PROTOBUF_EXPORT UnknownField { + public: + enum Type { + TYPE_VARINT, + TYPE_FIXED32, + TYPE_FIXED64, + TYPE_LENGTH_DELIMITED, + TYPE_GROUP + }; + + // The field's field number, as seen on the wire. + inline int number() const; + + // The field type. + inline Type type() const; + + // Accessors ------------------------------------------------------- + // Each method works only for UnknownFields of the corresponding type. + + inline arc_ui64 varint() const; + inline arc_ui32 fixed32() const; + inline arc_ui64 fixed64() const; + inline const TProtoStringType& length_delimited() const; + inline const UnknownFieldSet& group() const; + + inline void set_varint(arc_ui64 value); + inline void set_fixed32(arc_ui32 value); + inline void set_fixed64(arc_ui64 value); + inline void set_length_delimited(const TProtoStringType& value); + inline TProtoStringType* mutable_length_delimited(); + inline UnknownFieldSet* mutable_group(); + + // Serialization API. + // These methods can take advantage of the underlying implementation and may + // archieve a better performance than using getters to retrieve the data and + // do the serialization yourself. + void SerializeLengthDelimitedNoTag(io::CodedOutputStream* output) const { + output->SetCur(InternalSerializeLengthDelimitedNoTag(output->Cur(), + output->EpsCopy())); + } + + inline size_t GetLengthDelimitedSize() const; + uint8_t* InternalSerializeLengthDelimitedNoTag( + uint8_t* target, io::EpsCopyOutputStream* stream) const; + + + // If this UnknownField contains a pointer, delete it. + void Delete(); + + // Make a deep copy of any pointers in this UnknownField. + void DeepCopy(const UnknownField& other); + + // Set the wire type of this UnknownField. Should only be used when this + // UnknownField is being created. + inline void SetType(Type type); + + union LengthDelimited { + TProtoStringType* string_value; + }; + + arc_ui32 number_; + arc_ui32 type_; + union { + arc_ui64 varint_; + arc_ui32 fixed32_; + arc_ui64 fixed64_; + mutable union LengthDelimited length_delimited_; + UnknownFieldSet* group_; + } data_; +}; + +// =================================================================== +// inline implementations + +inline UnknownFieldSet::UnknownFieldSet() {} + +inline UnknownFieldSet::~UnknownFieldSet() { Clear(); } + +inline void UnknownFieldSet::ClearAndFreeMemory() { Clear(); } + +inline void UnknownFieldSet::Clear() { + if (!fields_.empty()) { + ClearFallback(); + } +} + +inline bool UnknownFieldSet::empty() const { return fields_.empty(); } + +inline void UnknownFieldSet::Swap(UnknownFieldSet* x) { + fields_.swap(x->fields_); +} + +inline int UnknownFieldSet::field_count() const { + return static_cast<int>(fields_.size()); +} +inline const UnknownField& UnknownFieldSet::field(int index) const { + return (fields_)[static_cast<size_t>(index)]; +} +inline UnknownField* UnknownFieldSet::mutable_field(int index) { + return &(fields_)[static_cast<size_t>(index)]; +} + +inline void UnknownFieldSet::AddLengthDelimited(int number, + const TProtoStringType& value) { + AddLengthDelimited(number)->assign(value); +} + + + + +inline int UnknownField::number() const { return static_cast<int>(number_); } +inline UnknownField::Type UnknownField::type() const { + return static_cast<Type>(type_); +} + +inline arc_ui64 UnknownField::varint() const { + assert(type() == TYPE_VARINT); + return data_.varint_; +} +inline arc_ui32 UnknownField::fixed32() const { + assert(type() == TYPE_FIXED32); + return data_.fixed32_; +} +inline arc_ui64 UnknownField::fixed64() const { + assert(type() == TYPE_FIXED64); + return data_.fixed64_; +} +inline const TProtoStringType& UnknownField::length_delimited() const { + assert(type() == TYPE_LENGTH_DELIMITED); + return *data_.length_delimited_.string_value; +} +inline const UnknownFieldSet& UnknownField::group() const { + assert(type() == TYPE_GROUP); + return *data_.group_; +} + +inline void UnknownField::set_varint(arc_ui64 value) { + assert(type() == TYPE_VARINT); + data_.varint_ = value; +} +inline void UnknownField::set_fixed32(arc_ui32 value) { + assert(type() == TYPE_FIXED32); + data_.fixed32_ = value; +} +inline void UnknownField::set_fixed64(arc_ui64 value) { + assert(type() == TYPE_FIXED64); + data_.fixed64_ = value; +} +inline void UnknownField::set_length_delimited(const TProtoStringType& value) { + assert(type() == TYPE_LENGTH_DELIMITED); + data_.length_delimited_.string_value->assign(value); +} +inline TProtoStringType* UnknownField::mutable_length_delimited() { + assert(type() == TYPE_LENGTH_DELIMITED); + return data_.length_delimited_.string_value; +} +inline UnknownFieldSet* UnknownField::mutable_group() { + assert(type() == TYPE_GROUP); + return data_.group_; +} +template <typename MessageType> +bool UnknownFieldSet::MergeFromMessage(const MessageType& message) { + // SFINAE will route to the right version. + return InternalMergeFromMessage(message); +} + + +inline size_t UnknownField::GetLengthDelimitedSize() const { + GOOGLE_DCHECK_EQ(TYPE_LENGTH_DELIMITED, type()); + return data_.length_delimited_.string_value->size(); +} + +inline void UnknownField::SetType(Type type) { + type_ = type; +} + + +} // namespace protobuf +} // namespace google + +#include <google/protobuf/port_undef.inc> +#endif // GOOGLE_PROTOBUF_UNKNOWN_FIELD_SET_H__ diff --git a/contrib/libs/protobuf_old/src/google/protobuf/util/delimited_message_util.cc b/contrib/libs/protobuf_old/src/google/protobuf/util/delimited_message_util.cc new file mode 100644 index 0000000000..80cab309be --- /dev/null +++ b/contrib/libs/protobuf_old/src/google/protobuf/util/delimited_message_util.cc @@ -0,0 +1,127 @@ +// 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. + +// Adapted from the patch of kenton@google.com (Kenton Varda) +// See https://github.com/protocolbuffers/protobuf/pull/710 for details. + +#include <google/protobuf/util/delimited_message_util.h> +#include <google/protobuf/io/coded_stream.h> + +namespace google { +namespace protobuf { +namespace util { + +bool SerializeDelimitedToFileDescriptor(const MessageLite& message, + int file_descriptor) { + io::FileOutputStream output(file_descriptor); + return SerializeDelimitedToZeroCopyStream(message, &output); +} + +bool SerializeDelimitedToOstream(const MessageLite& message, + std::ostream* output) { + { + io::OstreamOutputStream zero_copy_output(output); + if (!SerializeDelimitedToZeroCopyStream(message, &zero_copy_output)) + return false; + } + return output->good(); +} + +bool ParseDelimitedFromZeroCopyStream(MessageLite* message, + io::ZeroCopyInputStream* input, + bool* clean_eof) { + io::CodedInputStream coded_input(input); + return ParseDelimitedFromCodedStream(message, &coded_input, clean_eof); +} + +bool ParseDelimitedFromCodedStream(MessageLite* message, + io::CodedInputStream* input, + bool* clean_eof) { + if (clean_eof != NULL) *clean_eof = false; + int start = input->CurrentPosition(); + + // Read the size. + uint32 size; + if (!input->ReadVarint32(&size)) { + if (clean_eof != NULL) *clean_eof = input->CurrentPosition() == start; + return false; + } + + // Get the position after any size bytes have been read (and only the message + // itself remains). + int position_after_size = input->CurrentPosition(); + + // Tell the stream not to read beyond that size. + io::CodedInputStream::Limit limit = input->PushLimit(size); + + // Parse the message. + if (!message->MergeFromCodedStream(input)) return false; + if (!input->ConsumedEntireMessage()) return false; + if (input->CurrentPosition() - position_after_size != static_cast<int>(size)) + return false; + + // Release the limit. + input->PopLimit(limit); + + return true; +} + +bool SerializeDelimitedToZeroCopyStream(const MessageLite& message, + io::ZeroCopyOutputStream* output) { + io::CodedOutputStream coded_output(output); + return SerializeDelimitedToCodedStream(message, &coded_output); +} + +bool SerializeDelimitedToCodedStream(const MessageLite& message, + io::CodedOutputStream* output) { + // Write the size. + size_t size = message.ByteSizeLong(); + if (size > INT_MAX) return false; + + output->WriteVarint32(size); + + // Write the content. + uint8* buffer = output->GetDirectBufferForNBytesAndAdvance(size); + if (buffer != NULL) { + // Optimization: The message fits in one buffer, so use the faster + // direct-to-array serialization path. + message.SerializeWithCachedSizesToArray(buffer); + } else { + // Slightly-slower path when the message is multiple buffers. + message.SerializeWithCachedSizes(output); + if (output->HadError()) return false; + } + + return true; +} + +} // namespace util +} // namespace protobuf +} // namespace google diff --git a/contrib/libs/protobuf_old/src/google/protobuf/util/delimited_message_util.h b/contrib/libs/protobuf_old/src/google/protobuf/util/delimited_message_util.h new file mode 100644 index 0000000000..d3f7dbe8ad --- /dev/null +++ b/contrib/libs/protobuf_old/src/google/protobuf/util/delimited_message_util.h @@ -0,0 +1,108 @@ +// 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. + +// Adapted from the patch of kenton@google.com (Kenton Varda) +// See https://github.com/protocolbuffers/protobuf/pull/710 for details. + +#ifndef GOOGLE_PROTOBUF_UTIL_DELIMITED_MESSAGE_UTIL_H__ +#define GOOGLE_PROTOBUF_UTIL_DELIMITED_MESSAGE_UTIL_H__ + + +#include <ostream> + +#include <google/protobuf/message_lite.h> +#include <google/protobuf/io/coded_stream.h> +#include <google/protobuf/io/zero_copy_stream_impl.h> + +#include <google/protobuf/port_def.inc> + +namespace google { +namespace protobuf { +namespace util { + +// Write a single size-delimited message from the given stream. Delimited +// format allows a single file or stream to contain multiple messages, +// whereas normally writing multiple non-delimited messages to the same +// stream would cause them to be merged. A delimited message is a varint +// encoding the message size followed by a message of exactly that size. +// +// Note that if you want to *read* a delimited message from a file descriptor +// or istream, you will need to construct an io::FileInputStream or +// io::OstreamInputStream (implementations of io::ZeroCopyStream) and use the +// utility function ParseDelimitedFromZeroCopyStream(). You must then +// continue to use the same ZeroCopyInputStream to read all further data from +// the stream until EOF. This is because these ZeroCopyInputStream +// implementations are buffered: they read a big chunk of data at a time, +// then parse it. As a result, they may read past the end of the delimited +// message. There is no way for them to push the extra data back into the +// underlying source, so instead you must keep using the same stream object. +bool PROTOBUF_EXPORT SerializeDelimitedToFileDescriptor( + const MessageLite& message, int file_descriptor); + +bool PROTOBUF_EXPORT SerializeDelimitedToOstream(const MessageLite& message, + std::ostream* output); + +// Read a single size-delimited message from the given stream. Delimited +// format allows a single file or stream to contain multiple messages, +// whereas normally parsing consumes the entire input. A delimited message +// is a varint encoding the message size followed by a message of exactly +// that size. +// +// If |clean_eof| is not NULL, then it will be set to indicate whether the +// stream ended cleanly. That is, if the stream ends without this method +// having read any data at all from it, then *clean_eof will be set true, +// otherwise it will be set false. Note that these methods return false +// on EOF, but they also return false on other errors, so |clean_eof| is +// needed to distinguish a clean end from errors. +bool PROTOBUF_EXPORT ParseDelimitedFromZeroCopyStream( + MessageLite* message, io::ZeroCopyInputStream* input, bool* clean_eof); + +bool PROTOBUF_EXPORT ParseDelimitedFromCodedStream(MessageLite* message, + io::CodedInputStream* input, + bool* clean_eof); + +// Write a single size-delimited message from the given stream. Delimited +// format allows a single file or stream to contain multiple messages, +// whereas normally writing multiple non-delimited messages to the same +// stream would cause them to be merged. A delimited message is a varint +// encoding the message size followed by a message of exactly that size. +bool PROTOBUF_EXPORT SerializeDelimitedToZeroCopyStream( + const MessageLite& message, io::ZeroCopyOutputStream* output); + +bool PROTOBUF_EXPORT SerializeDelimitedToCodedStream( + const MessageLite& message, io::CodedOutputStream* output); + +} // namespace util +} // namespace protobuf +} // namespace google + +#include <google/protobuf/port_undef.inc> + +#endif // GOOGLE_PROTOBUF_UTIL_DELIMITED_MESSAGE_UTIL_H__ diff --git a/contrib/libs/protobuf_old/src/google/protobuf/util/field_comparator.cc b/contrib/libs/protobuf_old/src/google/protobuf/util/field_comparator.cc new file mode 100644 index 0000000000..217013c5ed --- /dev/null +++ b/contrib/libs/protobuf_old/src/google/protobuf/util/field_comparator.cc @@ -0,0 +1,210 @@ +// 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: ksroka@google.com (Krzysztof Sroka) + +#include <google/protobuf/util/field_comparator.h> + +#include <limits> +#include <string> + +#include <google/protobuf/descriptor.h> +#include <google/protobuf/message.h> +#include <google/protobuf/util/message_differencer.h> +#include <google/protobuf/stubs/map_util.h> +#include <google/protobuf/stubs/mathutil.h> + +namespace google { +namespace protobuf { +namespace util { + +FieldComparator::FieldComparator() {} +FieldComparator::~FieldComparator() {} + +SimpleFieldComparator::SimpleFieldComparator() + : float_comparison_(EXACT), + treat_nan_as_equal_(false), + has_default_tolerance_(false) {} + +SimpleFieldComparator::~SimpleFieldComparator() {} + +FieldComparator::ComparisonResult SimpleFieldComparator::SimpleCompare( + const Message& message_1, const Message& message_2, + const FieldDescriptor* field, int index_1, int index_2, + const util::FieldContext* /*field_context*/) { + const Reflection* reflection_1 = message_1.GetReflection(); + const Reflection* reflection_2 = message_2.GetReflection(); + + switch (field->cpp_type()) { +#define COMPARE_FIELD(METHOD) \ + if (field->is_repeated()) { \ + return ResultFromBoolean(Compare##METHOD( \ + *field, reflection_1->GetRepeated##METHOD(message_1, field, index_1), \ + reflection_2->GetRepeated##METHOD(message_2, field, index_2))); \ + } else { \ + return ResultFromBoolean( \ + Compare##METHOD(*field, reflection_1->Get##METHOD(message_1, field), \ + reflection_2->Get##METHOD(message_2, field))); \ + } \ + break; // Make sure no fall-through is introduced. + + case FieldDescriptor::CPPTYPE_BOOL: + COMPARE_FIELD(Bool); + case FieldDescriptor::CPPTYPE_DOUBLE: + COMPARE_FIELD(Double); + case FieldDescriptor::CPPTYPE_ENUM: + COMPARE_FIELD(Enum); + case FieldDescriptor::CPPTYPE_FLOAT: + COMPARE_FIELD(Float); + case FieldDescriptor::CPPTYPE_INT32: + COMPARE_FIELD(Int32); + case FieldDescriptor::CPPTYPE_INT64: + COMPARE_FIELD(Int64); + case FieldDescriptor::CPPTYPE_STRING: + if (field->is_repeated()) { + // Allocate scratch strings to store the result if a conversion is + // needed. + TProtoStringType scratch1; + TProtoStringType scratch2; + return ResultFromBoolean( + CompareString(*field, + reflection_1->GetRepeatedStringReference( + message_1, field, index_1, &scratch1), + reflection_2->GetRepeatedStringReference( + message_2, field, index_2, &scratch2))); + } else { + // Allocate scratch strings to store the result if a conversion is + // needed. + TProtoStringType scratch1; + TProtoStringType scratch2; + return ResultFromBoolean(CompareString( + *field, + reflection_1->GetStringReference(message_1, field, &scratch1), + reflection_2->GetStringReference(message_2, field, &scratch2))); + } + break; + case FieldDescriptor::CPPTYPE_UINT32: + COMPARE_FIELD(UInt32); + case FieldDescriptor::CPPTYPE_UINT64: + COMPARE_FIELD(UInt64); + +#undef COMPARE_FIELD + + case FieldDescriptor::CPPTYPE_MESSAGE: + return RECURSE; + + default: + GOOGLE_LOG(FATAL) << "No comparison code for field " << field->full_name() + << " of CppType = " << field->cpp_type(); + return DIFFERENT; + } +} + +bool SimpleFieldComparator::CompareWithDifferencer( + MessageDifferencer* differencer, const Message& message1, + const Message& message2, const util::FieldContext* field_context) { + return differencer->Compare(message1, message2, + field_context->parent_fields()); +} + +void SimpleFieldComparator::SetDefaultFractionAndMargin(double fraction, + double margin) { + default_tolerance_ = Tolerance(fraction, margin); + has_default_tolerance_ = true; +} + +void SimpleFieldComparator::SetFractionAndMargin(const FieldDescriptor* field, + double fraction, + double margin) { + GOOGLE_CHECK(FieldDescriptor::CPPTYPE_FLOAT == field->cpp_type() || + FieldDescriptor::CPPTYPE_DOUBLE == field->cpp_type()) + << "Field has to be float or double type. Field name is: " + << field->full_name(); + map_tolerance_[field] = Tolerance(fraction, margin); +} + +bool SimpleFieldComparator::CompareDouble(const FieldDescriptor& field, + double value_1, double value_2) { + return CompareDoubleOrFloat(field, value_1, value_2); +} + +bool SimpleFieldComparator::CompareEnum(const FieldDescriptor& /*field*/, + const EnumValueDescriptor* value_1, + const EnumValueDescriptor* value_2) { + return value_1->number() == value_2->number(); +} + +bool SimpleFieldComparator::CompareFloat(const FieldDescriptor& field, + float value_1, float value_2) { + return CompareDoubleOrFloat(field, value_1, value_2); +} + +template <typename T> +bool SimpleFieldComparator::CompareDoubleOrFloat(const FieldDescriptor& field, + T value_1, T value_2) { + if (value_1 == value_2) { + // Covers +inf and -inf (which are not within margin or fraction of + // themselves), and is a shortcut for finite values. + return true; + } else if (float_comparison_ == EXACT) { + if (treat_nan_as_equal_ && std::isnan(value_1) && std::isnan(value_2)) { + return true; + } + return false; + } else { + if (treat_nan_as_equal_ && std::isnan(value_1) && std::isnan(value_2)) { + return true; + } + // float_comparison_ == APPROXIMATE covers two use cases. + Tolerance* tolerance = FindOrNull(map_tolerance_, &field); + if (tolerance == NULL && has_default_tolerance_) { + tolerance = &default_tolerance_; + } + if (tolerance == NULL) { + return MathUtil::AlmostEquals(value_1, value_2); + } else { + // Use user-provided fraction and margin. Since they are stored as + // doubles, we explicitly cast them to types of values provided. This + // is very likely to fail if provided values are not numeric. + return MathUtil::WithinFractionOrMargin( + value_1, value_2, static_cast<T>(tolerance->fraction), + static_cast<T>(tolerance->margin)); + } + } +} + +FieldComparator::ComparisonResult SimpleFieldComparator::ResultFromBoolean( + bool boolean_result) const { + return boolean_result ? FieldComparator::SAME : FieldComparator::DIFFERENT; +} + +} // namespace util +} // namespace protobuf +} // namespace google diff --git a/contrib/libs/protobuf_old/src/google/protobuf/util/field_comparator.h b/contrib/libs/protobuf_old/src/google/protobuf/util/field_comparator.h new file mode 100644 index 0000000000..f14bbcca98 --- /dev/null +++ b/contrib/libs/protobuf_old/src/google/protobuf/util/field_comparator.h @@ -0,0 +1,285 @@ +// 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. + +// Defines classes for field comparison. + +#ifndef GOOGLE_PROTOBUF_UTIL_FIELD_COMPARATOR_H__ +#define GOOGLE_PROTOBUF_UTIL_FIELD_COMPARATOR_H__ + +#include <cstdint> +#include <map> +#include <string> +#include <vector> + +#include <google/protobuf/stubs/common.h> +#include <google/protobuf/port_def.inc> + +namespace google { +namespace protobuf { + +class Message; +class EnumValueDescriptor; +class FieldDescriptor; + +namespace util { + +class FieldContext; +class MessageDifferencer; + +// Base class specifying the interface for comparing protocol buffer fields. +// Regular users should consider using or subclassing DefaultFieldComparator +// rather than this interface. +// Currently, this does not support comparing unknown fields. +class PROTOBUF_EXPORT FieldComparator { + public: + FieldComparator(); + virtual ~FieldComparator(); + + enum ComparisonResult { + SAME, // Compared fields are equal. In case of comparing submessages, + // user should not recursively compare their contents. + DIFFERENT, // Compared fields are different. In case of comparing + // submessages, user should not recursively compare their + // contents. + RECURSE, // Compared submessages need to be compared recursively. + // FieldComparator does not specify the semantics of recursive + // comparison. This value should not be returned for simple + // values. + }; + + // Compares the values of a field in two protocol buffer messages. + // Returns SAME or DIFFERENT for simple values, and SAME, DIFFERENT or RECURSE + // for submessages. Returning RECURSE for fields not being submessages is + // illegal. + // In case the given FieldDescriptor points to a repeated field, the indices + // need to be valid. Otherwise they should be ignored. + // + // FieldContext contains information about the specific instances of the + // fields being compared, versus FieldDescriptor which only contains general + // type information about the fields. + virtual ComparisonResult Compare(const Message& message_1, + const Message& message_2, + const FieldDescriptor* field, int index_1, + int index_2, + const util::FieldContext* field_context) = 0; + + private: + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(FieldComparator); +}; + +// Basic implementation of FieldComparator. Supports three modes of floating +// point value comparison: exact, approximate using MathUtil::AlmostEqual +// method, and arbitrarily precise using MathUtil::WithinFractionOrMargin. +class PROTOBUF_EXPORT SimpleFieldComparator : public FieldComparator { + public: + enum FloatComparison { + EXACT, // Floats and doubles are compared exactly. + APPROXIMATE, // Floats and doubles are compared using the + // MathUtil::AlmostEqual method or + // MathUtil::WithinFractionOrMargin method. + // TODO(ksroka): Introduce third value to differentiate uses of AlmostEqual + // and WithinFractionOrMargin. + }; + + // Creates new comparator with float comparison set to EXACT. + SimpleFieldComparator(); + + ~SimpleFieldComparator() override; + + void set_float_comparison(FloatComparison float_comparison) { + float_comparison_ = float_comparison; + } + + FloatComparison float_comparison() const { return float_comparison_; } + + // Set whether the FieldComparator shall treat floats or doubles that are both + // NaN as equal (treat_nan_as_equal = true) or as different + // (treat_nan_as_equal = false). Default is treating NaNs always as different. + void set_treat_nan_as_equal(bool treat_nan_as_equal) { + treat_nan_as_equal_ = treat_nan_as_equal; + } + + bool treat_nan_as_equal() const { return treat_nan_as_equal_; } + + // Sets the fraction and margin for the float comparison of a given field. + // Uses MathUtil::WithinFractionOrMargin to compare the values. + // + // REQUIRES: field->cpp_type == FieldDescriptor::CPPTYPE_DOUBLE or + // field->cpp_type == FieldDescriptor::CPPTYPE_FLOAT + // REQUIRES: float_comparison_ == APPROXIMATE + void SetFractionAndMargin(const FieldDescriptor* field, double fraction, + double margin); + + // Sets the fraction and margin for the float comparison of all float and + // double fields, unless a field has been given a specific setting via + // SetFractionAndMargin() above. + // Uses MathUtil::WithinFractionOrMargin to compare the values. + // + // REQUIRES: float_comparison_ == APPROXIMATE + void SetDefaultFractionAndMargin(double fraction, double margin); + + protected: + // Returns the comparison result for the given field in two messages. + // + // This function is called directly by DefaultFieldComparator::Compare. + // Subclasses can call this function to compare fields they do not need to + // handle specially. + ComparisonResult SimpleCompare(const Message& message_1, + const Message& message_2, + const FieldDescriptor* field, int index_1, + int index_2, + const util::FieldContext* field_context); + + // Compare using the provided message_differencer. For example, a subclass can + // use this method to compare some field in a certain way using the same + // message_differencer instance and the field context. + bool CompareWithDifferencer(MessageDifferencer* differencer, + const Message& message1, const Message& message2, + const util::FieldContext* field_context); + + // Returns FieldComparator::SAME if boolean_result is true and + // FieldComparator::DIFFERENT otherwise. + ComparisonResult ResultFromBoolean(bool boolean_result) const; + + private: + // Defines the tolerance for floating point comparison (fraction and margin). + struct Tolerance { + double fraction; + double margin; + Tolerance() : fraction(0.0), margin(0.0) {} + Tolerance(double f, double m) : fraction(f), margin(m) {} + }; + + // Defines the map to store the tolerances for floating point comparison. + typedef std::map<const FieldDescriptor*, Tolerance> ToleranceMap; + + friend class MessageDifferencer; + // The following methods get executed when CompareFields is called for the + // basic types (instead of submessages). They return true on success. One + // can use ResultFromBoolean() to convert that boolean to a ComparisonResult + // value. + bool CompareBool(const FieldDescriptor& /* unused */, bool value_1, + bool value_2) { + return value_1 == value_2; + } + + // Uses CompareDoubleOrFloat, a helper function used by both CompareDouble and + // CompareFloat. + bool CompareDouble(const FieldDescriptor& field, double value_1, + double value_2); + + bool CompareEnum(const FieldDescriptor& field, + const EnumValueDescriptor* value_1, + const EnumValueDescriptor* value_2); + + // Uses CompareDoubleOrFloat, a helper function used by both CompareDouble and + // CompareFloat. + bool CompareFloat(const FieldDescriptor& field, float value_1, float value_2); + + bool CompareInt32(const FieldDescriptor& /* unused */, arc_i32 value_1, + arc_i32 value_2) { + return value_1 == value_2; + } + + bool CompareInt64(const FieldDescriptor& /* unused */, arc_i64 value_1, + arc_i64 value_2) { + return value_1 == value_2; + } + + bool CompareString(const FieldDescriptor& /* unused */, + const TProtoStringType& value_1, const TProtoStringType& value_2) { + return value_1 == value_2; + } + + bool CompareUInt32(const FieldDescriptor& /* unused */, arc_ui32 value_1, + arc_ui32 value_2) { + return value_1 == value_2; + } + + bool CompareUInt64(const FieldDescriptor& /* unused */, arc_ui64 value_1, + arc_ui64 value_2) { + return value_1 == value_2; + } + + // This function is used by CompareDouble and CompareFloat to avoid code + // duplication. There are no checks done against types of the values passed, + // but it's likely to fail if passed non-numeric arguments. + template <typename T> + bool CompareDoubleOrFloat(const FieldDescriptor& field, T value_1, T value_2); + + FloatComparison float_comparison_; + + // If true, floats and doubles that are both NaN are considered to be + // equal. Otherwise, two floats or doubles that are NaN are considered to be + // different. + bool treat_nan_as_equal_; + + // True iff default_tolerance_ has been explicitly set. + // + // If false, then the default tolerance for floats and doubles is that which + // is used by MathUtil::AlmostEquals(). + bool has_default_tolerance_; + + // Default float/double tolerance. Only meaningful if + // has_default_tolerance_ == true. + Tolerance default_tolerance_; + + // Field-specific float/double tolerances, which override any default for + // those particular fields. + ToleranceMap map_tolerance_; + + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(SimpleFieldComparator); +}; + +// Default field comparison: use the basic implementation of FieldComparator. +#ifdef PROTOBUF_FUTURE_BREAKING_CHANGES +class PROTOBUF_EXPORT DefaultFieldComparator final + : public SimpleFieldComparator +#else // PROTOBUF_FUTURE_BREAKING_CHANGES +class PROTOBUF_EXPORT DefaultFieldComparator : public SimpleFieldComparator +#endif // PROTOBUF_FUTURE_BREAKING_CHANGES +{ + public: + ComparisonResult Compare(const Message& message_1, const Message& message_2, + const FieldDescriptor* field, int index_1, + int index_2, + const util::FieldContext* field_context) override { + return SimpleCompare(message_1, message_2, field, index_1, index_2, + field_context); + } +}; + +} // namespace util +} // namespace protobuf +} // namespace google + +#include <google/protobuf/port_undef.inc> + +#endif // GOOGLE_PROTOBUF_UTIL_FIELD_COMPARATOR_H__ diff --git a/contrib/libs/protobuf_old/src/google/protobuf/util/field_mask_util.cc b/contrib/libs/protobuf_old/src/google/protobuf/util/field_mask_util.cc new file mode 100644 index 0000000000..32db742a2e --- /dev/null +++ b/contrib/libs/protobuf_old/src/google/protobuf/util/field_mask_util.cc @@ -0,0 +1,720 @@ +// 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 <google/protobuf/util/field_mask_util.h> + +#include <cstdint> + +#include <google/protobuf/message.h> +#include <google/protobuf/stubs/strutil.h> +#include <google/protobuf/stubs/map_util.h> + +// Must be included last. +#include <google/protobuf/port_def.inc> + +namespace google { +namespace protobuf { +namespace util { + +using google::protobuf::FieldMask; + +TProtoStringType FieldMaskUtil::ToString(const FieldMask& mask) { + return Join(mask.paths(), ","); +} + +void FieldMaskUtil::FromString(StringPiece str, FieldMask* out) { + out->Clear(); + std::vector<TProtoStringType> paths = Split(str, ","); + for (const TProtoStringType& path : paths) { + if (path.empty()) continue; + out->add_paths(path); + } +} + +bool FieldMaskUtil::SnakeCaseToCamelCase(StringPiece input, + TProtoStringType* output) { + output->clear(); + bool after_underscore = false; + for (char input_char : input) { + if (input_char >= 'A' && input_char <= 'Z') { + // The field name must not contain uppercase letters. + return false; + } + if (after_underscore) { + if (input_char >= 'a' && input_char <= 'z') { + output->push_back(input_char + 'A' - 'a'); + after_underscore = false; + } else { + // The character after a "_" must be a lowercase letter. + return false; + } + } else if (input_char == '_') { + after_underscore = true; + } else { + output->push_back(input_char); + } + } + if (after_underscore) { + // Trailing "_". + return false; + } + return true; +} + +bool FieldMaskUtil::CamelCaseToSnakeCase(StringPiece input, + TProtoStringType* output) { + output->clear(); + for (const char c : input) { + if (c == '_') { + // The field name must not contain "_"s. + return false; + } + if (c >= 'A' && c <= 'Z') { + output->push_back('_'); + output->push_back(c + 'a' - 'A'); + } else { + output->push_back(c); + } + } + return true; +} + +bool FieldMaskUtil::ToJsonString(const FieldMask& mask, TProtoStringType* out) { + out->clear(); + for (int i = 0; i < mask.paths_size(); ++i) { + const TProtoStringType& path = mask.paths(i); + TProtoStringType camelcase_path; + if (!SnakeCaseToCamelCase(path, &camelcase_path)) { + return false; + } + if (i > 0) { + out->push_back(','); + } + out->append(camelcase_path); + } + return true; +} + +bool FieldMaskUtil::FromJsonString(StringPiece str, FieldMask* out) { + out->Clear(); + std::vector<TProtoStringType> paths = Split(str, ","); + for (const TProtoStringType& path : paths) { + if (path.empty()) continue; + TProtoStringType snakecase_path; + if (!CamelCaseToSnakeCase(path, &snakecase_path)) { + return false; + } + out->add_paths(snakecase_path); + } + return true; +} + +bool FieldMaskUtil::GetFieldDescriptors( + const Descriptor* descriptor, StringPiece path, + std::vector<const FieldDescriptor*>* field_descriptors) { + if (field_descriptors != nullptr) { + field_descriptors->clear(); + } + std::vector<TProtoStringType> parts = Split(path, "."); + for (const TProtoStringType& field_name : parts) { + if (descriptor == nullptr) { + return false; + } + const FieldDescriptor* field = descriptor->FindFieldByName(field_name); + if (field == nullptr) { + return false; + } + if (field_descriptors != nullptr) { + field_descriptors->push_back(field); + } + if (!field->is_repeated() && + field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) { + descriptor = field->message_type(); + } else { + descriptor = nullptr; + } + } + return true; +} + +void FieldMaskUtil::GetFieldMaskForAllFields(const Descriptor* descriptor, + FieldMask* out) { + for (int i = 0; i < descriptor->field_count(); ++i) { + out->add_paths(descriptor->field(i)->name()); + } +} + +namespace { +// A FieldMaskTree represents a FieldMask in a tree structure. For example, +// given a FieldMask "foo.bar,foo.baz,bar.baz", the FieldMaskTree will be: +// +// [root] -+- foo -+- bar +// | | +// | +- baz +// | +// +- bar --- baz +// +// In the tree, each leaf node represents a field path. +class FieldMaskTree { + public: + FieldMaskTree(); + ~FieldMaskTree(); + + void MergeFromFieldMask(const FieldMask& mask); + void MergeToFieldMask(FieldMask* mask); + + // Add a field path into the tree. In a FieldMask, each field path matches + // the specified field and also all its sub-fields. If the field path to + // add is a sub-path of an existing field path in the tree (i.e., a leaf + // node), it means the tree already matches the given path so nothing will + // be added to the tree. If the path matches an existing non-leaf node in the + // tree, that non-leaf node will be turned into a leaf node with all its + // children removed because the path matches all the node's children. + void AddPath(const TProtoStringType& path); + + // Remove a path from the tree. + // If the path is a sub-path of an existing field path in the tree, it means + // we need remove the existing field path and add all sub-paths except + // specified path. If the path matches an existing node in the tree, this node + // will be moved. + void RemovePath(const TProtoStringType& path, const Descriptor* descriptor); + + // Calculate the intersection part of a field path with this tree and add + // the intersection field path into out. + void IntersectPath(const TProtoStringType& path, FieldMaskTree* out); + + // Merge all fields specified by this tree from one message to another. + void MergeMessage(const Message& source, + const FieldMaskUtil::MergeOptions& options, + Message* destination) { + // Do nothing if the tree is empty. + if (root_.children.empty()) { + return; + } + MergeMessage(&root_, source, options, destination); + } + + // Add required field path of the message to this tree based on current tree + // structure. If a message is present in the tree, add the path of its + // required field to the tree. This is to make sure that after trimming a + // message with required fields are set, check IsInitialized() will not fail. + void AddRequiredFieldPath(const Descriptor* descriptor) { + // Do nothing if the tree is empty. + if (root_.children.empty()) { + return; + } + AddRequiredFieldPath(&root_, descriptor); + } + + // Trims all fields not specified by this tree from the given message. + // Returns true if the message is modified. + bool TrimMessage(Message* message) { + // Do nothing if the tree is empty. + if (root_.children.empty()) { + return false; + } + return TrimMessage(&root_, message); + } + + private: + struct Node { + Node() {} + + ~Node() { ClearChildren(); } + + void ClearChildren() { + for (std::map<TProtoStringType, Node*>::iterator it = children.begin(); + it != children.end(); ++it) { + delete it->second; + } + children.clear(); + } + + std::map<TProtoStringType, Node*> children; + + private: + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(Node); + }; + + // Merge a sub-tree to mask. This method adds the field paths represented + // by all leaf nodes descended from "node" to mask. + void MergeToFieldMask(const TProtoStringType& prefix, const Node* node, + FieldMask* out); + + // Merge all leaf nodes of a sub-tree to another tree. + void MergeLeafNodesToTree(const TProtoStringType& prefix, const Node* node, + FieldMaskTree* out); + + // Merge all fields specified by a sub-tree from one message to another. + void MergeMessage(const Node* node, const Message& source, + const FieldMaskUtil::MergeOptions& options, + Message* destination); + + // Add required field path of the message to this tree based on current tree + // structure. If a message is present in the tree, add the path of its + // required field to the tree. This is to make sure that after trimming a + // message with required fields are set, check IsInitialized() will not fail. + void AddRequiredFieldPath(Node* node, const Descriptor* descriptor); + + // Trims all fields not specified by this sub-tree from the given message. + // Returns true if the message is actually modified + bool TrimMessage(const Node* node, Message* message); + + Node root_; + + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(FieldMaskTree); +}; + +FieldMaskTree::FieldMaskTree() {} + +FieldMaskTree::~FieldMaskTree() {} + +void FieldMaskTree::MergeFromFieldMask(const FieldMask& mask) { + for (int i = 0; i < mask.paths_size(); ++i) { + AddPath(mask.paths(i)); + } +} + +void FieldMaskTree::MergeToFieldMask(FieldMask* mask) { + MergeToFieldMask("", &root_, mask); +} + +void FieldMaskTree::MergeToFieldMask(const TProtoStringType& prefix, + const Node* node, FieldMask* out) { + if (node->children.empty()) { + if (prefix.empty()) { + // This is the root node. + return; + } + out->add_paths(prefix); + return; + } + for (std::map<TProtoStringType, Node*>::const_iterator it = node->children.begin(); + it != node->children.end(); ++it) { + TProtoStringType current_path = + prefix.empty() ? it->first : prefix + "." + it->first; + MergeToFieldMask(current_path, it->second, out); + } +} + +void FieldMaskTree::AddPath(const TProtoStringType& path) { + std::vector<TProtoStringType> parts = Split(path, "."); + if (parts.empty()) { + return; + } + bool new_branch = false; + Node* node = &root_; + for (const TProtoStringType& node_name : parts) { + if (!new_branch && node != &root_ && node->children.empty()) { + // Path matches an existing leaf node. This means the path is already + // covered by this tree (for example, adding "foo.bar.baz" to a tree + // which already contains "foo.bar"). + return; + } + Node*& child = node->children[node_name]; + if (child == NULL) { + new_branch = true; + child = new Node(); + } + node = child; + } + if (!node->children.empty()) { + node->ClearChildren(); + } +} + +void FieldMaskTree::RemovePath(const TProtoStringType& path, + const Descriptor* descriptor) { + if (root_.children.empty()) { + // Nothing to be removed from an empty tree. We shortcut it here so an empty + // tree won't be interpreted as a field mask containing all fields by the + // code below. + return; + } + std::vector<TProtoStringType> parts = Split(path, "."); + if (parts.empty()) { + return; + } + std::vector<Node*> nodes(parts.size()); + Node* node = &root_; + const Descriptor* current_descriptor = descriptor; + Node* new_branch_node = nullptr; + for (int i = 0; i < parts.size(); ++i) { + nodes[i] = node; + const FieldDescriptor* field_descriptor = + current_descriptor->FindFieldByName(parts[i]); + if (field_descriptor == nullptr || + (field_descriptor->cpp_type() != FieldDescriptor::CPPTYPE_MESSAGE && + i != parts.size() - 1)) { + // Invalid path. + if (new_branch_node != nullptr) { + // If add any new nodes, cleanup. + new_branch_node->ClearChildren(); + } + return; + } + + if (node->children.empty()) { + if (new_branch_node == nullptr) { + new_branch_node = node; + } + for (int j = 0; j < current_descriptor->field_count(); ++j) { + node->children[current_descriptor->field(j)->name()] = new Node(); + } + } + if (ContainsKey(node->children, parts[i])) { + node = node->children[parts[i]]; + if (field_descriptor->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) { + current_descriptor = field_descriptor->message_type(); + } + } else { + // Path does not exist. + return; + } + } + // Remove path. + for (int i = parts.size() - 1; i >= 0; i--) { + delete nodes[i]->children[parts[i]]; + nodes[i]->children.erase(parts[i]); + if (!nodes[i]->children.empty()) { + break; + } + } +} + +void FieldMaskTree::IntersectPath(const TProtoStringType& path, FieldMaskTree* out) { + std::vector<TProtoStringType> parts = Split(path, "."); + if (parts.empty()) { + return; + } + const Node* node = &root_; + for (const TProtoStringType& node_name : parts) { + if (node->children.empty()) { + if (node != &root_) { + out->AddPath(path); + } + return; + } + const Node* result = FindPtrOrNull(node->children, node_name); + if (result == NULL) { + // No intersection found. + return; + } + node = result; + } + // Now we found a matching node with the given path. Add all leaf nodes + // to out. + MergeLeafNodesToTree(path, node, out); +} + +void FieldMaskTree::MergeLeafNodesToTree(const TProtoStringType& prefix, + const Node* node, FieldMaskTree* out) { + if (node->children.empty()) { + out->AddPath(prefix); + } + for (std::map<TProtoStringType, Node*>::const_iterator it = node->children.begin(); + it != node->children.end(); ++it) { + TProtoStringType current_path = + prefix.empty() ? it->first : prefix + "." + it->first; + MergeLeafNodesToTree(current_path, it->second, out); + } +} + +void FieldMaskTree::MergeMessage(const Node* node, const Message& source, + const FieldMaskUtil::MergeOptions& options, + Message* destination) { + GOOGLE_DCHECK(!node->children.empty()); + const Reflection* source_reflection = source.GetReflection(); + const Reflection* destination_reflection = destination->GetReflection(); + const Descriptor* descriptor = source.GetDescriptor(); + for (std::map<TProtoStringType, Node*>::const_iterator it = node->children.begin(); + it != node->children.end(); ++it) { + const TProtoStringType& field_name = it->first; + const Node* child = it->second; + const FieldDescriptor* field = descriptor->FindFieldByName(field_name); + if (field == NULL) { + GOOGLE_LOG(ERROR) << "Cannot find field \"" << field_name << "\" in message " + << descriptor->full_name(); + continue; + } + if (!child->children.empty()) { + // Sub-paths are only allowed for singular message fields. + if (field->is_repeated() || + field->cpp_type() != FieldDescriptor::CPPTYPE_MESSAGE) { + GOOGLE_LOG(ERROR) << "Field \"" << field_name << "\" in message " + << descriptor->full_name() + << " is not a singular message field and cannot " + << "have sub-fields."; + continue; + } + MergeMessage(child, source_reflection->GetMessage(source, field), options, + destination_reflection->MutableMessage(destination, field)); + continue; + } + if (!field->is_repeated()) { + switch (field->cpp_type()) { +#define COPY_VALUE(TYPE, Name) \ + case FieldDescriptor::CPPTYPE_##TYPE: { \ + if (source_reflection->HasField(source, field)) { \ + destination_reflection->Set##Name( \ + destination, field, source_reflection->Get##Name(source, field)); \ + } else { \ + destination_reflection->ClearField(destination, field); \ + } \ + break; \ + } + COPY_VALUE(BOOL, Bool) + COPY_VALUE(INT32, Int32) + COPY_VALUE(INT64, Int64) + COPY_VALUE(UINT32, UInt32) + COPY_VALUE(UINT64, UInt64) + COPY_VALUE(FLOAT, Float) + COPY_VALUE(DOUBLE, Double) + COPY_VALUE(ENUM, Enum) + COPY_VALUE(STRING, String) +#undef COPY_VALUE + case FieldDescriptor::CPPTYPE_MESSAGE: { + if (options.replace_message_fields()) { + destination_reflection->ClearField(destination, field); + } + if (source_reflection->HasField(source, field)) { + destination_reflection->MutableMessage(destination, field) + ->MergeFrom(source_reflection->GetMessage(source, field)); + } + break; + } + } + } else { + if (options.replace_repeated_fields()) { + destination_reflection->ClearField(destination, field); + } + switch (field->cpp_type()) { +#define COPY_REPEATED_VALUE(TYPE, Name) \ + case FieldDescriptor::CPPTYPE_##TYPE: { \ + int size = source_reflection->FieldSize(source, field); \ + for (int i = 0; i < size; ++i) { \ + destination_reflection->Add##Name( \ + destination, field, \ + source_reflection->GetRepeated##Name(source, field, i)); \ + } \ + break; \ + } + COPY_REPEATED_VALUE(BOOL, Bool) + COPY_REPEATED_VALUE(INT32, Int32) + COPY_REPEATED_VALUE(INT64, Int64) + COPY_REPEATED_VALUE(UINT32, UInt32) + COPY_REPEATED_VALUE(UINT64, UInt64) + COPY_REPEATED_VALUE(FLOAT, Float) + COPY_REPEATED_VALUE(DOUBLE, Double) + COPY_REPEATED_VALUE(ENUM, Enum) + COPY_REPEATED_VALUE(STRING, String) +#undef COPY_REPEATED_VALUE + case FieldDescriptor::CPPTYPE_MESSAGE: { + int size = source_reflection->FieldSize(source, field); + for (int i = 0; i < size; ++i) { + destination_reflection->AddMessage(destination, field) + ->MergeFrom( + source_reflection->GetRepeatedMessage(source, field, i)); + } + break; + } + } + } + } +} + +void FieldMaskTree::AddRequiredFieldPath(Node* node, + const Descriptor* descriptor) { + const arc_i32 field_count = descriptor->field_count(); + for (int index = 0; index < field_count; ++index) { + const FieldDescriptor* field = descriptor->field(index); + if (field->is_required()) { + const TProtoStringType& node_name = field->name(); + Node*& child = node->children[node_name]; + if (child == nullptr) { + // Add required field path to the tree + child = new Node(); + } else if (child->children.empty()) { + // If the required field is in the tree and does not have any children, + // do nothing. + continue; + } + // Add required field in the children to the tree if the field is message. + if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) { + AddRequiredFieldPath(child, field->message_type()); + } + } else if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) { + std::map<TProtoStringType, Node*>::const_iterator it = + node->children.find(field->name()); + if (it != node->children.end()) { + // Add required fields in the children to the + // tree if the field is a message and present in the tree. + Node* child = it->second; + if (!child->children.empty()) { + AddRequiredFieldPath(child, field->message_type()); + } + } + } + } +} + +bool FieldMaskTree::TrimMessage(const Node* node, Message* message) { + GOOGLE_DCHECK(!node->children.empty()); + const Reflection* reflection = message->GetReflection(); + const Descriptor* descriptor = message->GetDescriptor(); + const arc_i32 field_count = descriptor->field_count(); + bool modified = false; + for (int index = 0; index < field_count; ++index) { + const FieldDescriptor* field = descriptor->field(index); + std::map<TProtoStringType, Node*>::const_iterator it = + node->children.find(field->name()); + if (it == node->children.end()) { + if (field->is_repeated()) { + if (reflection->FieldSize(*message, field) != 0) { + modified = true; + } + } else { + if (reflection->HasField(*message, field)) { + modified = true; + } + } + reflection->ClearField(message, field); + } else { + if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) { + Node* child = it->second; + if (!child->children.empty() && reflection->HasField(*message, field)) { + bool nestedMessageChanged = + TrimMessage(child, reflection->MutableMessage(message, field)); + modified = nestedMessageChanged || modified; + } + } + } + } + return modified; +} + +} // namespace + +void FieldMaskUtil::ToCanonicalForm(const FieldMask& mask, FieldMask* out) { + FieldMaskTree tree; + tree.MergeFromFieldMask(mask); + out->Clear(); + tree.MergeToFieldMask(out); +} + +void FieldMaskUtil::Union(const FieldMask& mask1, const FieldMask& mask2, + FieldMask* out) { + FieldMaskTree tree; + tree.MergeFromFieldMask(mask1); + tree.MergeFromFieldMask(mask2); + out->Clear(); + tree.MergeToFieldMask(out); +} + +void FieldMaskUtil::Intersect(const FieldMask& mask1, const FieldMask& mask2, + FieldMask* out) { + FieldMaskTree tree, intersection; + tree.MergeFromFieldMask(mask1); + for (int i = 0; i < mask2.paths_size(); ++i) { + tree.IntersectPath(mask2.paths(i), &intersection); + } + out->Clear(); + intersection.MergeToFieldMask(out); +} + +void FieldMaskUtil::Subtract(const Descriptor* descriptor, + const FieldMask& mask1, const FieldMask& mask2, + FieldMask* out) { + if (mask1.paths().empty()) { + out->Clear(); + return; + } + FieldMaskTree tree; + tree.MergeFromFieldMask(mask1); + for (int i = 0; i < mask2.paths_size(); ++i) { + tree.RemovePath(mask2.paths(i), descriptor); + } + out->Clear(); + tree.MergeToFieldMask(out); +} + +bool FieldMaskUtil::IsPathInFieldMask(StringPiece path, + const FieldMask& mask) { + for (int i = 0; i < mask.paths_size(); ++i) { + const TProtoStringType& mask_path = mask.paths(i); + if (path == mask_path) { + return true; + } else if (mask_path.length() < path.length()) { + // Also check whether mask.paths(i) is a prefix of path. + if (path.substr(0, mask_path.length() + 1).compare(mask_path + ".") == + 0) { + return true; + } + } + } + return false; +} + +void FieldMaskUtil::MergeMessageTo(const Message& source, const FieldMask& mask, + const MergeOptions& options, + Message* destination) { + GOOGLE_CHECK(source.GetDescriptor() == destination->GetDescriptor()); + // Build a FieldMaskTree and walk through the tree to merge all specified + // fields. + FieldMaskTree tree; + tree.MergeFromFieldMask(mask); + tree.MergeMessage(source, options, destination); +} + +bool FieldMaskUtil::TrimMessage(const FieldMask& mask, Message* message) { + // Build a FieldMaskTree and walk through the tree to merge all specified + // fields. + FieldMaskTree tree; + tree.MergeFromFieldMask(mask); + return tree.TrimMessage(GOOGLE_CHECK_NOTNULL(message)); +} + +bool FieldMaskUtil::TrimMessage(const FieldMask& mask, Message* message, + const TrimOptions& options) { + // Build a FieldMaskTree and walk through the tree to merge all specified + // fields. + FieldMaskTree tree; + tree.MergeFromFieldMask(mask); + // If keep_required_fields is true, implicitly add required fields of + // a message present in the tree to prevent from trimming. + if (options.keep_required_fields()) { + tree.AddRequiredFieldPath(GOOGLE_CHECK_NOTNULL(message->GetDescriptor())); + } + return tree.TrimMessage(GOOGLE_CHECK_NOTNULL(message)); +} + +} // namespace util +} // namespace protobuf +} // namespace google diff --git a/contrib/libs/protobuf_old/src/google/protobuf/util/field_mask_util.h b/contrib/libs/protobuf_old/src/google/protobuf/util/field_mask_util.h new file mode 100644 index 0000000000..bdfc92c440 --- /dev/null +++ b/contrib/libs/protobuf_old/src/google/protobuf/util/field_mask_util.h @@ -0,0 +1,262 @@ +// 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. + +// Defines utilities for the FieldMask well known type. + +#ifndef GOOGLE_PROTOBUF_UTIL_FIELD_MASK_UTIL_H__ +#define GOOGLE_PROTOBUF_UTIL_FIELD_MASK_UTIL_H__ + +#include <cstdint> +#include <string> + +#include <google/protobuf/field_mask.pb.h> +#include <google/protobuf/descriptor.h> +#include <google/protobuf/stubs/strutil.h> + +// Must be included last. +#include <google/protobuf/port_def.inc> + +namespace google { +namespace protobuf { +namespace util { + +class PROTOBUF_EXPORT FieldMaskUtil { + typedef google::protobuf::FieldMask FieldMask; + + public: + // Converts FieldMask to/from string, formatted by separating each path + // with a comma (e.g., "foo_bar,baz.quz"). + static TProtoStringType ToString(const FieldMask& mask); + static void FromString(StringPiece str, FieldMask* out); + + // Populates the FieldMask with the paths corresponding to the fields with the + // given numbers, after checking that all field numbers are valid. + template <typename T> + static void FromFieldNumbers(const std::vector<arc_i64>& field_numbers, + FieldMask* out) { + for (const auto field_number : field_numbers) { + const FieldDescriptor* field_desc = + T::descriptor()->FindFieldByNumber(field_number); + GOOGLE_CHECK(field_desc != nullptr) + << "Invalid field number for " << T::descriptor()->full_name() << ": " + << field_number; + AddPathToFieldMask<T>(field_desc->lowercase_name(), out); + } + } + + // Converts FieldMask to/from string, formatted according to proto3 JSON + // spec for FieldMask (e.g., "fooBar,baz.quz"). If the field name is not + // style conforming (i.e., not snake_case when converted to string, or not + // camelCase when converted from string), the conversion will fail. + static bool ToJsonString(const FieldMask& mask, TProtoStringType* out); + static bool FromJsonString(StringPiece str, FieldMask* out); + + // Get the descriptors of the fields which the given path from the message + // descriptor traverses, if field_descriptors is not null. + // Return false if the path is not valid, and the content of field_descriptors + // is unspecified. + static bool GetFieldDescriptors( + const Descriptor* descriptor, StringPiece path, + std::vector<const FieldDescriptor*>* field_descriptors); + + // Checks whether the given path is valid for type T. + template <typename T> + static bool IsValidPath(StringPiece path) { + return GetFieldDescriptors(T::descriptor(), path, nullptr); + } + + // Checks whether the given FieldMask is valid for type T. + template <typename T> + static bool IsValidFieldMask(const FieldMask& mask) { + for (int i = 0; i < mask.paths_size(); ++i) { + if (!GetFieldDescriptors(T::descriptor(), mask.paths(i), nullptr)) + return false; + } + return true; + } + + // Adds a path to FieldMask after checking whether the given path is valid. + // This method check-fails if the path is not a valid path for type T. + template <typename T> + static void AddPathToFieldMask(StringPiece path, FieldMask* mask) { + GOOGLE_CHECK(IsValidPath<T>(path)) << path; + mask->add_paths(TProtoStringType(path)); + } + + // Creates a FieldMask with all fields of type T. This FieldMask only + // contains fields of T but not any sub-message fields. + template <typename T> + static FieldMask GetFieldMaskForAllFields() { + FieldMask out; + GetFieldMaskForAllFields(T::descriptor(), &out); + return out; + } + template <typename T> + PROTOBUF_DEPRECATED_MSG("Use *out = GetFieldMaskForAllFields() instead") + static void GetFieldMaskForAllFields(FieldMask* out) { + GetFieldMaskForAllFields(T::descriptor(), out); + } + // This flavor takes the protobuf type descriptor as an argument. + // Useful when the type is not known at compile time. + static void GetFieldMaskForAllFields(const Descriptor* descriptor, + FieldMask* out); + + // Converts a FieldMask to the canonical form. It will: + // 1. Remove paths that are covered by another path. For example, + // "foo.bar" is covered by "foo" and will be removed if "foo" + // is also in the FieldMask. + // 2. Sort all paths in alphabetical order. + static void ToCanonicalForm(const FieldMask& mask, FieldMask* out); + + // Creates an union of two FieldMasks. + static void Union(const FieldMask& mask1, const FieldMask& mask2, + FieldMask* out); + + // Creates an intersection of two FieldMasks. + static void Intersect(const FieldMask& mask1, const FieldMask& mask2, + FieldMask* out); + + // Subtracts mask2 from mask1 base of type T. + template <typename T> + static void Subtract(const FieldMask& mask1, const FieldMask& mask2, + FieldMask* out) { + Subtract(T::descriptor(), mask1, mask2, out); + } + // This flavor takes the protobuf type descriptor as an argument. + // Useful when the type is not known at compile time. + static void Subtract(const Descriptor* descriptor, const FieldMask& mask1, + const FieldMask& mask2, FieldMask* out); + + // Returns true if path is covered by the given FieldMask. Note that path + // "foo.bar" covers all paths like "foo.bar.baz", "foo.bar.quz.x", etc. + // Also note that parent paths are not covered by explicit child path, i.e. + // "foo.bar" does NOT cover "foo", even if "bar" is the only child. + static bool IsPathInFieldMask(StringPiece path, const FieldMask& mask); + + class MergeOptions; + // Merges fields specified in a FieldMask into another message. + static void MergeMessageTo(const Message& source, const FieldMask& mask, + const MergeOptions& options, Message* destination); + + class TrimOptions; + // Removes from 'message' any field that is not represented in the given + // FieldMask. If the FieldMask is empty, does nothing. + // Returns true if the message is modified. + static bool TrimMessage(const FieldMask& mask, Message* message); + + // Removes from 'message' any field that is not represented in the given + // FieldMask with customized TrimOptions. + // If the FieldMask is empty, does nothing. + // Returns true if the message is modified. + static bool TrimMessage(const FieldMask& mask, Message* message, + const TrimOptions& options); + + private: + friend class SnakeCaseCamelCaseTest; + // Converts a field name from snake_case to camelCase: + // 1. Every character after "_" will be converted to uppercase. + // 2. All "_"s are removed. + // The conversion will fail if: + // 1. The field name contains uppercase letters. + // 2. Any character after a "_" is not a lowercase letter. + // If the conversion succeeds, it's guaranteed that the resulted + // camelCase name will yield the original snake_case name when + // converted using CamelCaseToSnakeCase(). + // + // Note that the input can contain characters not allowed in C identifiers. + // For example, "foo_bar,baz_quz" will be converted to "fooBar,bazQuz" + // successfully. + static bool SnakeCaseToCamelCase(StringPiece input, + TProtoStringType* output); + // Converts a field name from camelCase to snake_case: + // 1. Every uppercase letter is converted to lowercase with an additional + // preceding "_". + // The conversion will fail if: + // 1. The field name contains "_"s. + // If the conversion succeeds, it's guaranteed that the resulted + // snake_case name will yield the original camelCase name when + // converted using SnakeCaseToCamelCase(). + // + // Note that the input can contain characters not allowed in C identifiers. + // For example, "fooBar,bazQuz" will be converted to "foo_bar,baz_quz" + // successfully. + static bool CamelCaseToSnakeCase(StringPiece input, + TProtoStringType* output); +}; + +class PROTOBUF_EXPORT FieldMaskUtil::MergeOptions { + public: + MergeOptions() + : replace_message_fields_(false), replace_repeated_fields_(false) {} + // When merging message fields, the default behavior is to merge the + // content of two message fields together. If you instead want to use + // the field from the source message to replace the corresponding field + // in the destination message, set this flag to true. When this flag is set, + // specified submessage fields that are missing in source will be cleared in + // destination. + void set_replace_message_fields(bool value) { + replace_message_fields_ = value; + } + bool replace_message_fields() const { return replace_message_fields_; } + // The default merging behavior will append entries from the source + // repeated field to the destination repeated field. If you only want + // to keep the entries from the source repeated field, set this flag + // to true. + void set_replace_repeated_fields(bool value) { + replace_repeated_fields_ = value; + } + bool replace_repeated_fields() const { return replace_repeated_fields_; } + + private: + bool replace_message_fields_; + bool replace_repeated_fields_; +}; + +class PROTOBUF_EXPORT FieldMaskUtil::TrimOptions { + public: + TrimOptions() : keep_required_fields_(false) {} + // When trimming message fields, the default behavior is to trim required + // fields of the present message if they are not specified in the field mask. + // If you instead want to keep required fields of the present message even + // when they are not specified in the field mask, set this flag to true. + void set_keep_required_fields(bool value) { keep_required_fields_ = value; } + bool keep_required_fields() const { return keep_required_fields_; } + + private: + bool keep_required_fields_; +}; + +} // namespace util +} // namespace protobuf +} // namespace google + +#include <google/protobuf/port_undef.inc> + +#endif // GOOGLE_PROTOBUF_UTIL_FIELD_MASK_UTIL_H__ diff --git a/contrib/libs/protobuf_old/src/google/protobuf/util/internal/constants.h b/contrib/libs/protobuf_old/src/google/protobuf/util/internal/constants.h new file mode 100644 index 0000000000..9dcdfb8ad7 --- /dev/null +++ b/contrib/libs/protobuf_old/src/google/protobuf/util/internal/constants.h @@ -0,0 +1,101 @@ +// 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_UTIL_CONVERTER_CONSTANTS_H__ +#define GOOGLE_PROTOBUF_UTIL_CONVERTER_CONSTANTS_H__ + +#include <cstdint> + +#include <google/protobuf/stubs/common.h> + +// This file contains constants used by //net/proto2/util/converter. + +namespace google { +namespace protobuf { +namespace util { +namespace converter { +// Prefix for type URLs. +const char kTypeServiceBaseUrl[] = "type.googleapis.com"; + +// Format string for RFC3339 timestamp formatting. +const char kRfc3339TimeFormat[] = "%E4Y-%m-%dT%H:%M:%S"; + +// Same as above, but the year value is not zero-padded i.e. this accepts +// timestamps like "1-01-0001T23:59:59Z" instead of "0001-01-0001T23:59:59Z". +const char kRfc3339TimeFormatNoPadding[] = "%Y-%m-%dT%H:%M:%S"; + +// Minimum seconds allowed in a google.protobuf.Timestamp value. +const arc_i64 kTimestampMinSeconds = -62135596800LL; + +// Maximum seconds allowed in a google.protobuf.Timestamp value. +const arc_i64 kTimestampMaxSeconds = 253402300799LL; + +// Minimum seconds allowed in a google.protobuf.Duration value. +const arc_i64 kDurationMinSeconds = -315576000000LL; + +// Maximum seconds allowed in a google.protobuf.Duration value. +const arc_i64 kDurationMaxSeconds = 315576000000LL; + +// Nano seconds in a second. +const arc_i32 kNanosPerSecond = 1000000000; + +// Type url representing NULL values in google.protobuf.Struct type. +const char kStructNullValueTypeUrl[] = + "type.googleapis.com/google.protobuf.NullValue"; + +// Type string for google.protobuf.Struct +const char kStructType[] = "google.protobuf.Struct"; + +// Type string for struct.proto's google.protobuf.Value value type. +const char kStructValueType[] = "google.protobuf.Value"; + +// Type string for struct.proto's google.protobuf.ListValue value type. +const char kStructListValueType[] = "google.protobuf.ListValue"; + +// Type string for google.protobuf.Timestamp +const char kTimestampType[] = "google.protobuf.Timestamp"; + +// Type string for google.protobuf.Duration +const char kDurationType[] = "google.protobuf.Duration"; + +// Type URL for struct value type google.protobuf.Value +const char kStructValueTypeUrl[] = "type.googleapis.com/google.protobuf.Value"; + +// Type string for google.protobuf.Any +const char kAnyType[] = "google.protobuf.Any"; + +// The protobuf option name of jspb.message_id; +const char kOptionJspbMessageId[] = "jspb.message_id"; + +} // namespace converter +} // namespace util +} // namespace protobuf +} // namespace google +#endif // GOOGLE_PROTOBUF_UTIL_CONVERTER_CONSTANTS_H__ diff --git a/contrib/libs/protobuf_old/src/google/protobuf/util/internal/datapiece.cc b/contrib/libs/protobuf_old/src/google/protobuf/util/internal/datapiece.cc new file mode 100644 index 0000000000..6cff38a216 --- /dev/null +++ b/contrib/libs/protobuf_old/src/google/protobuf/util/internal/datapiece.cc @@ -0,0 +1,423 @@ +// 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 <google/protobuf/util/internal/datapiece.h> + +#include <cmath> +#include <cstdint> +#include <limits> + +#include <google/protobuf/struct.pb.h> +#include <google/protobuf/type.pb.h> +#include <google/protobuf/descriptor.h> +#include <google/protobuf/util/internal/utility.h> +#include <google/protobuf/stubs/status.h> +#include <google/protobuf/stubs/strutil.h> +#include <google/protobuf/stubs/mathutil.h> + +namespace google { +namespace protobuf { +namespace util { +namespace converter { + +using util::Status; + +namespace { + +template <typename To, typename From> +util::StatusOr<To> ValidateNumberConversion(To after, From before) { + if (after == before && + MathUtil::Sign<From>(before) == MathUtil::Sign<To>(after)) { + return after; + } else { + return util::InvalidArgumentError( + std::is_integral<From>::value ? ValueAsString(before) + : std::is_same<From, double>::value ? DoubleAsString(before) + : FloatAsString(before)); + } +} + +// For general conversion between +// int32, int64, uint32, uint64, double and float +// except conversion between double and float. +template <typename To, typename From> +util::StatusOr<To> NumberConvertAndCheck(From before) { + if (std::is_same<From, To>::value) return before; + + To after = static_cast<To>(before); + return ValidateNumberConversion(after, before); +} + +// For conversion to integer types (int32, int64, uint32, uint64) from floating +// point types (double, float) only. +template <typename To, typename From> +util::StatusOr<To> FloatingPointToIntConvertAndCheck(From before) { + if (std::is_same<From, To>::value) return before; + + To after = static_cast<To>(before); + return ValidateNumberConversion(after, before); +} + +// For conversion between double and float only. +util::StatusOr<double> FloatToDouble(float before) { + // Casting float to double should just work as double has more precision + // than float. + return static_cast<double>(before); +} + +util::StatusOr<float> DoubleToFloat(double before) { + if (std::isnan(before)) { + return std::numeric_limits<float>::quiet_NaN(); + } else if (!std::isfinite(before)) { + // Converting a double +inf/-inf to float should just work. + return static_cast<float>(before); + } else if (before > std::numeric_limits<float>::max() || + before < -std::numeric_limits<float>::max()) { + // Double value outside of the range of float. + return util::InvalidArgumentError(DoubleAsString(before)); + } else { + return static_cast<float>(before); + } +} + +} // namespace + +util::StatusOr<arc_i32> DataPiece::ToInt32() const { + if (type_ == TYPE_STRING) + return StringToNumber<arc_i32>(safe_strto32); + + if (type_ == TYPE_DOUBLE) + return FloatingPointToIntConvertAndCheck<arc_i32, double>(double_); + + if (type_ == TYPE_FLOAT) + return FloatingPointToIntConvertAndCheck<arc_i32, float>(float_); + + return GenericConvert<arc_i32>(); +} + +util::StatusOr<arc_ui32> DataPiece::ToUint32() const { + if (type_ == TYPE_STRING) + return StringToNumber<arc_ui32>(safe_strtou32); + + if (type_ == TYPE_DOUBLE) + return FloatingPointToIntConvertAndCheck<arc_ui32, double>(double_); + + if (type_ == TYPE_FLOAT) + return FloatingPointToIntConvertAndCheck<arc_ui32, float>(float_); + + return GenericConvert<arc_ui32>(); +} + +util::StatusOr<arc_i64> DataPiece::ToInt64() const { + if (type_ == TYPE_STRING) + return StringToNumber<arc_i64>(safe_strto64); + + if (type_ == TYPE_DOUBLE) + return FloatingPointToIntConvertAndCheck<arc_i64, double>(double_); + + if (type_ == TYPE_FLOAT) + return FloatingPointToIntConvertAndCheck<arc_i64, float>(float_); + + return GenericConvert<arc_i64>(); +} + +util::StatusOr<arc_ui64> DataPiece::ToUint64() const { + if (type_ == TYPE_STRING) + return StringToNumber<arc_ui64>(safe_strtou64); + + if (type_ == TYPE_DOUBLE) + return FloatingPointToIntConvertAndCheck<arc_ui64, double>(double_); + + if (type_ == TYPE_FLOAT) + return FloatingPointToIntConvertAndCheck<arc_ui64, float>(float_); + + return GenericConvert<arc_ui64>(); +} + +util::StatusOr<double> DataPiece::ToDouble() const { + if (type_ == TYPE_FLOAT) { + return FloatToDouble(float_); + } + if (type_ == TYPE_STRING) { + if (str_ == "Infinity") return std::numeric_limits<double>::infinity(); + if (str_ == "-Infinity") return -std::numeric_limits<double>::infinity(); + if (str_ == "NaN") return std::numeric_limits<double>::quiet_NaN(); + util::StatusOr<double> value = StringToNumber<double>(safe_strtod); + if (value.ok() && !std::isfinite(value.value())) { + // safe_strtod converts out-of-range values to +inf/-inf, but we want + // to report them as errors. + return util::InvalidArgumentError(StrCat("\"", str_, "\"")); + } else { + return value; + } + } + return GenericConvert<double>(); +} + +util::StatusOr<float> DataPiece::ToFloat() const { + if (type_ == TYPE_DOUBLE) { + return DoubleToFloat(double_); + } + if (type_ == TYPE_STRING) { + if (str_ == "Infinity") return std::numeric_limits<float>::infinity(); + if (str_ == "-Infinity") return -std::numeric_limits<float>::infinity(); + if (str_ == "NaN") return std::numeric_limits<float>::quiet_NaN(); + // SafeStrToFloat() is used instead of safe_strtof() because the later + // does not fail on inputs like SimpleDtoa(DBL_MAX). + return StringToNumber<float>(SafeStrToFloat); + } + return GenericConvert<float>(); +} + +util::StatusOr<bool> DataPiece::ToBool() const { + switch (type_) { + case TYPE_BOOL: + return bool_; + case TYPE_STRING: + return StringToNumber<bool>(safe_strtob); + default: + return util::InvalidArgumentError( + ValueAsStringOrDefault("Wrong type. Cannot convert to Bool.")); + } +} + +util::StatusOr<TProtoStringType> DataPiece::ToString() const { + switch (type_) { + case TYPE_STRING: + return TProtoStringType(str_); + case TYPE_BYTES: { + TProtoStringType base64; + Base64Escape(str_, &base64); + return base64; + } + default: + return util::InvalidArgumentError( + ValueAsStringOrDefault("Cannot convert to string.")); + } +} + +TProtoStringType DataPiece::ValueAsStringOrDefault( + StringPiece default_string) const { + switch (type_) { + case TYPE_INT32: + return StrCat(i32_); + case TYPE_INT64: + return StrCat(i64_); + case TYPE_UINT32: + return StrCat(u32_); + case TYPE_UINT64: + return StrCat(u64_); + case TYPE_DOUBLE: + return DoubleAsString(double_); + case TYPE_FLOAT: + return FloatAsString(float_); + case TYPE_BOOL: + return SimpleBtoa(bool_); + case TYPE_STRING: + return StrCat("\"", str_.ToString(), "\""); + case TYPE_BYTES: { + TProtoStringType base64; + WebSafeBase64Escape(str_, &base64); + return StrCat("\"", base64, "\""); + } + case TYPE_NULL: + return "null"; + default: + return TProtoStringType(default_string); + } +} + +util::StatusOr<TProtoStringType> DataPiece::ToBytes() const { + if (type_ == TYPE_BYTES) return str_.ToString(); + if (type_ == TYPE_STRING) { + TProtoStringType decoded; + if (!DecodeBase64(str_, &decoded)) { + return util::InvalidArgumentError( + ValueAsStringOrDefault("Invalid data in input.")); + } + return decoded; + } else { + return util::InvalidArgumentError(ValueAsStringOrDefault( + "Wrong type. Only String or Bytes can be converted to Bytes.")); + } +} + +util::StatusOr<int> DataPiece::ToEnum(const google::protobuf::Enum* enum_type, + bool use_lower_camel_for_enums, + bool case_insensitive_enum_parsing, + bool ignore_unknown_enum_values, + bool* is_unknown_enum_value) const { + if (type_ == TYPE_NULL) return google::protobuf::NULL_VALUE; + + if (type_ == TYPE_STRING) { + // First try the given value as a name. + TProtoStringType enum_name = TProtoStringType(str_); + const google::protobuf::EnumValue* value = + FindEnumValueByNameOrNull(enum_type, enum_name); + if (value != nullptr) return value->number(); + + // Check if int version of enum is sent as string. + util::StatusOr<arc_i32> int_value = ToInt32(); + if (int_value.ok()) { + if (const google::protobuf::EnumValue* enum_value = + FindEnumValueByNumberOrNull(enum_type, int_value.value())) { + return enum_value->number(); + } + } + + // Next try a normalized name. + bool should_normalize_enum = + case_insensitive_enum_parsing || use_lower_camel_for_enums; + if (should_normalize_enum) { + for (TProtoStringType::iterator it = enum_name.begin(); it != enum_name.end(); + ++it) { + *it = *it == '-' ? '_' : ascii_toupper(*it); + } + value = FindEnumValueByNameOrNull(enum_type, enum_name); + if (value != nullptr) return value->number(); + } + + // If use_lower_camel_for_enums is true try with enum name without + // underscore. This will also accept camel case names as the enum_name has + // been normalized before. + if (use_lower_camel_for_enums) { + value = FindEnumValueByNameWithoutUnderscoreOrNull(enum_type, enum_name); + if (value != nullptr) return value->number(); + } + + // If ignore_unknown_enum_values is true an unknown enum value is ignored. + if (ignore_unknown_enum_values) { + *is_unknown_enum_value = true; + if (enum_type->enumvalue_size() > 0) { + return enum_type->enumvalue(0).number(); + } + } + } else { + // We don't need to check whether the value is actually declared in the + // enum because we preserve unknown enum values as well. + return ToInt32(); + } + return util::InvalidArgumentError( + ValueAsStringOrDefault("Cannot find enum with given value.")); +} + +template <typename To> +util::StatusOr<To> DataPiece::GenericConvert() const { + switch (type_) { + case TYPE_INT32: + return NumberConvertAndCheck<To, arc_i32>(i32_); + case TYPE_INT64: + return NumberConvertAndCheck<To, arc_i64>(i64_); + case TYPE_UINT32: + return NumberConvertAndCheck<To, arc_ui32>(u32_); + case TYPE_UINT64: + return NumberConvertAndCheck<To, arc_ui64>(u64_); + case TYPE_DOUBLE: + return NumberConvertAndCheck<To, double>(double_); + case TYPE_FLOAT: + return NumberConvertAndCheck<To, float>(float_); + default: // TYPE_ENUM, TYPE_STRING, TYPE_CORD, TYPE_BOOL + return util::InvalidArgumentError(ValueAsStringOrDefault( + "Wrong type. Bool, Enum, String and Cord not supported in " + "GenericConvert.")); + } +} + +template <typename To> +util::StatusOr<To> DataPiece::StringToNumber(bool (*func)(StringPiece, + To*)) const { + if (str_.size() > 0 && (str_[0] == ' ' || str_[str_.size() - 1] == ' ')) { + return util::InvalidArgumentError(StrCat("\"", str_, "\"")); + } + To result; + if (func(str_, &result)) return result; + return util::InvalidArgumentError( + StrCat("\"", TProtoStringType(str_), "\"")); +} + +bool DataPiece::DecodeBase64(StringPiece src, TProtoStringType* dest) const { + // Try web-safe decode first, if it fails, try the non-web-safe decode. + if (WebSafeBase64Unescape(src, dest)) { + if (use_strict_base64_decoding_) { + // In strict mode, check if the escaped version gives us the same value as + // unescaped. + TProtoStringType encoded; + // WebSafeBase64Escape does no padding by default. + WebSafeBase64Escape(*dest, &encoded); + // Remove trailing padding '=' characters before comparison. + StringPiece src_no_padding = StringPiece(src).substr( + 0, HasSuffixString(src, "=") ? src.find_last_not_of('=') + 1 + : src.length()); + return encoded == src_no_padding; + } + return true; + } + + if (Base64Unescape(src, dest)) { + if (use_strict_base64_decoding_) { + TProtoStringType encoded; + Base64Escape(reinterpret_cast<const unsigned char*>(dest->data()), + dest->length(), &encoded, false); + StringPiece src_no_padding = StringPiece(src).substr( + 0, HasSuffixString(src, "=") ? src.find_last_not_of('=') + 1 + : src.length()); + return encoded == src_no_padding; + } + return true; + } + + return false; +} + +void DataPiece::InternalCopy(const DataPiece& other) { + type_ = other.type_; + use_strict_base64_decoding_ = other.use_strict_base64_decoding_; + switch (type_) { + case TYPE_INT32: + case TYPE_INT64: + case TYPE_UINT32: + case TYPE_UINT64: + case TYPE_DOUBLE: + case TYPE_FLOAT: + case TYPE_BOOL: + case TYPE_ENUM: + case TYPE_NULL: + case TYPE_BYTES: + case TYPE_STRING: { + str_ = other.str_; + break; + } + } +} + +} // namespace converter +} // namespace util +} // namespace protobuf +} // namespace google diff --git a/contrib/libs/protobuf_old/src/google/protobuf/util/internal/datapiece.h b/contrib/libs/protobuf_old/src/google/protobuf/util/internal/datapiece.h new file mode 100644 index 0000000000..0a5bdd74af --- /dev/null +++ b/contrib/libs/protobuf_old/src/google/protobuf/util/internal/datapiece.h @@ -0,0 +1,218 @@ +// 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_UTIL_CONVERTER_DATAPIECE_H__ +#define GOOGLE_PROTOBUF_UTIL_CONVERTER_DATAPIECE_H__ + +#include <cstdint> +#include <string> + +#include <google/protobuf/stubs/common.h> +#include <google/protobuf/stubs/logging.h> +#include <google/protobuf/type.pb.h> +#include <google/protobuf/stubs/statusor.h> +#include <google/protobuf/stubs/strutil.h> + +#include <google/protobuf/port_def.inc> + +namespace google { +namespace protobuf { +namespace util { +namespace converter { +class ProtoWriter; + +// Container for a single piece of data together with its data type. +// +// For primitive types (int32, int64, uint32, uint64, double, float, bool), +// the data is stored by value. +// +// For string, a StringPiece is stored. For Cord, a pointer to Cord is stored. +// Just like StringPiece, the DataPiece class does not own the storage for +// the actual string or Cord, so it is the user's responsibility to guarantee +// that the underlying storage is still valid when the DataPiece is accessed. +class PROTOBUF_EXPORT DataPiece { + public: + // Identifies data type of the value. + // These are the types supported by DataPiece. + enum Type { + TYPE_INT32 = 1, + TYPE_INT64 = 2, + TYPE_UINT32 = 3, + TYPE_UINT64 = 4, + TYPE_DOUBLE = 5, + TYPE_FLOAT = 6, + TYPE_BOOL = 7, + TYPE_ENUM = 8, + TYPE_STRING = 9, + TYPE_BYTES = 10, + TYPE_NULL = 11, // explicit NULL type + }; + + // Constructors and Destructor + explicit DataPiece(const arc_i32 value) + : type_(TYPE_INT32), i32_(value), use_strict_base64_decoding_(false) {} + explicit DataPiece(const arc_i64 value) + : type_(TYPE_INT64), i64_(value), use_strict_base64_decoding_(false) {} + explicit DataPiece(const arc_ui32 value) + : type_(TYPE_UINT32), u32_(value), use_strict_base64_decoding_(false) {} + explicit DataPiece(const arc_ui64 value) + : type_(TYPE_UINT64), u64_(value), use_strict_base64_decoding_(false) {} + explicit DataPiece(const double value) + : type_(TYPE_DOUBLE), + double_(value), + use_strict_base64_decoding_(false) {} + explicit DataPiece(const float value) + : type_(TYPE_FLOAT), float_(value), use_strict_base64_decoding_(false) {} + explicit DataPiece(const bool value) + : type_(TYPE_BOOL), bool_(value), use_strict_base64_decoding_(false) {} + DataPiece(StringPiece value, bool use_strict_base64_decoding) + : type_(TYPE_STRING), + str_(value), + use_strict_base64_decoding_(use_strict_base64_decoding) {} + // Constructor for bytes. The second parameter is not used. + DataPiece(StringPiece value, bool /*dummy*/, bool use_strict_base64_decoding) + : type_(TYPE_BYTES), + str_(value), + use_strict_base64_decoding_(use_strict_base64_decoding) {} + + DataPiece(const DataPiece& r) : type_(r.type_) { InternalCopy(r); } + + DataPiece& operator=(const DataPiece& x) { + InternalCopy(x); + return *this; + } + + static DataPiece NullData() { return DataPiece(TYPE_NULL, 0); } + + virtual ~DataPiece() { + } + + // Accessors + Type type() const { return type_; } + + bool use_strict_base64_decoding() { return use_strict_base64_decoding_; } + + StringPiece str() const { + GOOGLE_LOG_IF(DFATAL, type_ != TYPE_STRING) << "Not a string type."; + return str_; + } + + + // Parses, casts or converts the value stored in the DataPiece into an int32. + util::StatusOr<arc_i32> ToInt32() const; + + // Parses, casts or converts the value stored in the DataPiece into a uint32. + util::StatusOr<arc_ui32> ToUint32() const; + + // Parses, casts or converts the value stored in the DataPiece into an int64. + util::StatusOr<arc_i64> ToInt64() const; + + // Parses, casts or converts the value stored in the DataPiece into a uint64. + util::StatusOr<arc_ui64> ToUint64() const; + + // Parses, casts or converts the value stored in the DataPiece into a double. + util::StatusOr<double> ToDouble() const; + + // Parses, casts or converts the value stored in the DataPiece into a float. + util::StatusOr<float> ToFloat() const; + + // Parses, casts or converts the value stored in the DataPiece into a bool. + util::StatusOr<bool> ToBool() const; + + // Parses, casts or converts the value stored in the DataPiece into a string. + util::StatusOr<TProtoStringType> ToString() const; + + // Tries to convert the value contained in this datapiece to string. If the + // conversion fails, it returns the default_string. + TProtoStringType ValueAsStringOrDefault(StringPiece default_string) const; + + util::StatusOr<TProtoStringType> ToBytes() const; + + private: + friend class ProtoWriter; + + // Disallow implicit constructor. + DataPiece(); + + // Helper to create NULL or ENUM types. + DataPiece(Type type, arc_i32 val) + : type_(type), i32_(val), use_strict_base64_decoding_(false) {} + + // Same as the ToEnum() method above but with additional flag to ignore + // unknown enum values. + util::StatusOr<int> ToEnum(const google::protobuf::Enum* enum_type, + bool use_lower_camel_for_enums, + bool case_insensitive_enum_parsing, + bool ignore_unknown_enum_values, + bool* is_unknown_enum_value) const; + + // For numeric conversion between + // int32, int64, uint32, uint64, double, float and bool + template <typename To> + util::StatusOr<To> GenericConvert() const; + + // For conversion from string to + // int32, int64, uint32, uint64, double, float and bool + template <typename To> + util::StatusOr<To> StringToNumber(bool (*func)(StringPiece, To*)) const; + + // Decodes a base64 string. Returns true on success. + bool DecodeBase64(StringPiece src, TProtoStringType* dest) const; + + // Helper function to initialize this DataPiece with 'other'. + void InternalCopy(const DataPiece& other); + + // Data type for this piece of data. + Type type_; + + // Stored piece of data. + union { + arc_i32 i32_; + arc_i64 i64_; + arc_ui32 u32_; + arc_ui64 u64_; + double double_; + float float_; + bool bool_; + StringPiece str_; + }; + + // Uses a stricter version of base64 decoding for byte fields. + bool use_strict_base64_decoding_; +}; + +} // namespace converter +} // namespace util +} // namespace protobuf +} // namespace google + +#include <google/protobuf/port_undef.inc> + +#endif // GOOGLE_PROTOBUF_UTIL_CONVERTER_DATAPIECE_H__ diff --git a/contrib/libs/protobuf_old/src/google/protobuf/util/internal/default_value_objectwriter.cc b/contrib/libs/protobuf_old/src/google/protobuf/util/internal/default_value_objectwriter.cc new file mode 100644 index 0000000000..46b5513d15 --- /dev/null +++ b/contrib/libs/protobuf_old/src/google/protobuf/util/internal/default_value_objectwriter.cc @@ -0,0 +1,642 @@ +// 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 <google/protobuf/util/internal/default_value_objectwriter.h> + +#include <cstdint> +#include <unordered_map> + +#include <google/protobuf/util/internal/constants.h> +#include <google/protobuf/util/internal/utility.h> +#include <google/protobuf/stubs/map_util.h> + +namespace google { +namespace protobuf { +namespace util { +namespace converter { + +namespace { +// Helper function to convert string value to given data type by calling the +// passed converter function on the DataPiece created from "value" argument. +// If value is empty or if conversion fails, the default_value is returned. +template <typename T> +T ConvertTo(StringPiece value, + util::StatusOr<T> (DataPiece::*converter_fn)() const, + T default_value) { + if (value.empty()) return default_value; + util::StatusOr<T> result = (DataPiece(value, true).*converter_fn)(); + return result.ok() ? result.value() : default_value; +} +} // namespace + +DefaultValueObjectWriter::DefaultValueObjectWriter( + TypeResolver* type_resolver, const google::protobuf::Type& type, + ObjectWriter* ow) + : typeinfo_(TypeInfo::NewTypeInfo(type_resolver)), + own_typeinfo_(true), + type_(type), + current_(nullptr), + root_(nullptr), + suppress_empty_list_(false), + preserve_proto_field_names_(false), + use_ints_for_enums_(false), + ow_(ow) {} + +DefaultValueObjectWriter::~DefaultValueObjectWriter() { + if (own_typeinfo_) { + delete typeinfo_; + } +} + +DefaultValueObjectWriter* DefaultValueObjectWriter::RenderBool( + StringPiece name, bool value) { + if (current_ == nullptr) { + ow_->RenderBool(name, value); + } else { + RenderDataPiece(name, DataPiece(value)); + } + return this; +} + +DefaultValueObjectWriter* DefaultValueObjectWriter::RenderInt32( + StringPiece name, arc_i32 value) { + if (current_ == nullptr) { + ow_->RenderInt32(name, value); + } else { + RenderDataPiece(name, DataPiece(value)); + } + return this; +} + +DefaultValueObjectWriter* DefaultValueObjectWriter::RenderUint32( + StringPiece name, arc_ui32 value) { + if (current_ == nullptr) { + ow_->RenderUint32(name, value); + } else { + RenderDataPiece(name, DataPiece(value)); + } + return this; +} + +DefaultValueObjectWriter* DefaultValueObjectWriter::RenderInt64( + StringPiece name, arc_i64 value) { + if (current_ == nullptr) { + ow_->RenderInt64(name, value); + } else { + RenderDataPiece(name, DataPiece(value)); + } + return this; +} + +DefaultValueObjectWriter* DefaultValueObjectWriter::RenderUint64( + StringPiece name, arc_ui64 value) { + if (current_ == nullptr) { + ow_->RenderUint64(name, value); + } else { + RenderDataPiece(name, DataPiece(value)); + } + return this; +} + +DefaultValueObjectWriter* DefaultValueObjectWriter::RenderDouble( + StringPiece name, double value) { + if (current_ == nullptr) { + ow_->RenderDouble(name, value); + } else { + RenderDataPiece(name, DataPiece(value)); + } + return this; +} + +DefaultValueObjectWriter* DefaultValueObjectWriter::RenderFloat( + StringPiece name, float value) { + if (current_ == nullptr) { + ow_->RenderBool(name, value); + } else { + RenderDataPiece(name, DataPiece(value)); + } + return this; +} + +DefaultValueObjectWriter* DefaultValueObjectWriter::RenderString( + StringPiece name, StringPiece value) { + if (current_ == nullptr) { + ow_->RenderString(name, value); + } else { + // Since StringPiece is essentially a pointer, takes a copy of "value" to + // avoid ownership issues. + string_values_.emplace_back(new TProtoStringType(value)); + RenderDataPiece(name, DataPiece(*string_values_.back(), true)); + } + return this; +} + +DefaultValueObjectWriter* DefaultValueObjectWriter::RenderBytes( + StringPiece name, StringPiece value) { + if (current_ == nullptr) { + ow_->RenderBytes(name, value); + } else { + // Since StringPiece is essentially a pointer, takes a copy of "value" to + // avoid ownership issues. + string_values_.emplace_back(new TProtoStringType(value)); + RenderDataPiece(name, DataPiece(*string_values_.back(), false, true)); + } + return this; +} + +DefaultValueObjectWriter* DefaultValueObjectWriter::RenderNull( + StringPiece name) { + if (current_ == nullptr) { + ow_->RenderNull(name); + } else { + RenderDataPiece(name, DataPiece::NullData()); + } + return this; +} + +void DefaultValueObjectWriter::RegisterFieldScrubCallBack( + FieldScrubCallBack field_scrub_callback) { + field_scrub_callback_ = std::move(field_scrub_callback); +} + +DefaultValueObjectWriter::Node* DefaultValueObjectWriter::CreateNewNode( + const TProtoStringType& name, const google::protobuf::Type* type, NodeKind kind, + const DataPiece& data, bool is_placeholder, + const std::vector<TProtoStringType>& path, bool suppress_empty_list, + bool preserve_proto_field_names, bool use_ints_for_enums, + FieldScrubCallBack field_scrub_callback) { + return new Node(name, type, kind, data, is_placeholder, path, + suppress_empty_list, preserve_proto_field_names, + use_ints_for_enums, std::move(field_scrub_callback)); +} + +DefaultValueObjectWriter::Node::Node( + const TProtoStringType& name, const google::protobuf::Type* type, NodeKind kind, + const DataPiece& data, bool is_placeholder, + const std::vector<TProtoStringType>& path, bool suppress_empty_list, + bool preserve_proto_field_names, bool use_ints_for_enums, + FieldScrubCallBack field_scrub_callback) + : name_(name), + type_(type), + kind_(kind), + is_any_(false), + data_(data), + is_placeholder_(is_placeholder), + path_(path), + suppress_empty_list_(suppress_empty_list), + preserve_proto_field_names_(preserve_proto_field_names), + use_ints_for_enums_(use_ints_for_enums), + field_scrub_callback_(std::move(field_scrub_callback)) {} + +DefaultValueObjectWriter::Node* DefaultValueObjectWriter::Node::FindChild( + StringPiece name) { + if (name.empty() || kind_ != OBJECT) { + return nullptr; + } + for (Node* child : children_) { + if (child->name() == name) { + return child; + } + } + return nullptr; +} + +void DefaultValueObjectWriter::Node::WriteTo(ObjectWriter* ow) { + if (kind_ == PRIMITIVE) { + ObjectWriter::RenderDataPieceTo(data_, name_, ow); + return; + } + + // Render maps. Empty maps are rendered as "{}". + if (kind_ == MAP) { + ow->StartObject(name_); + WriteChildren(ow); + ow->EndObject(); + return; + } + + // Write out lists. If we didn't have any list in response, write out empty + // list. + if (kind_ == LIST) { + // Suppress empty lists if requested. + if (suppress_empty_list_ && is_placeholder_) return; + + ow->StartList(name_); + WriteChildren(ow); + ow->EndList(); + return; + } + + // If is_placeholder_ = true, we didn't see this node in the response, so + // skip output. + if (is_placeholder_) return; + + ow->StartObject(name_); + WriteChildren(ow); + ow->EndObject(); +} + +void DefaultValueObjectWriter::Node::WriteChildren(ObjectWriter* ow) { + for (Node* child : children_) { + child->WriteTo(ow); + } +} + +const google::protobuf::Type* DefaultValueObjectWriter::Node::GetMapValueType( + const google::protobuf::Type& found_type, const TypeInfo* typeinfo) { + // If this field is a map, we should use the type of its "Value" as + // the type of the child node. + for (int i = 0; i < found_type.fields_size(); ++i) { + const google::protobuf::Field& sub_field = found_type.fields(i); + if (sub_field.number() != 2) { + continue; + } + if (sub_field.kind() != google::protobuf::Field::TYPE_MESSAGE) { + // This map's value type is not a message type. We don't need to + // get the field_type in this case. + break; + } + util::StatusOr<const google::protobuf::Type*> sub_type = + typeinfo->ResolveTypeUrl(sub_field.type_url()); + if (!sub_type.ok()) { + GOOGLE_LOG(WARNING) << "Cannot resolve type '" << sub_field.type_url() << "'."; + } else { + return sub_type.value(); + } + break; + } + return nullptr; +} + +void DefaultValueObjectWriter::Node::PopulateChildren( + const TypeInfo* typeinfo) { + // Ignores well known types that don't require automatically populating their + // primitive children. For type "Any", we only populate its children when the + // "@type" field is set. + // TODO(tsun): remove "kStructValueType" from the list. It's being checked + // now because of a bug in the tool-chain that causes the "oneof_index" + // of kStructValueType to not be set correctly. + if (type_ == nullptr || type_->name() == kAnyType || + type_->name() == kStructType || type_->name() == kTimestampType || + type_->name() == kDurationType || type_->name() == kStructValueType) { + return; + } + std::vector<Node*> new_children; + std::unordered_map<TProtoStringType, int> orig_children_map; + + // Creates a map of child nodes to speed up lookup. + for (int i = 0; i < children_.size(); ++i) { + InsertIfNotPresent(&orig_children_map, children_[i]->name_, i); + } + + for (int i = 0; i < type_->fields_size(); ++i) { + const google::protobuf::Field& field = type_->fields(i); + + // This code is checking if the field to be added to the tree should be + // scrubbed or not by calling the field_scrub_callback_ callback function. + std::vector<TProtoStringType> path; + if (!path_.empty()) { + path.insert(path.begin(), path_.begin(), path_.end()); + } + path.push_back(field.name()); + if (field_scrub_callback_ && field_scrub_callback_(path, &field)) { + continue; + } + + std::unordered_map<TProtoStringType, int>::iterator found = + orig_children_map.find(field.name()); + // If the child field has already been set, we just add it to the new list + // of children. + if (found != orig_children_map.end()) { + new_children.push_back(children_[found->second]); + children_[found->second] = nullptr; + continue; + } + + const google::protobuf::Type* field_type = nullptr; + bool is_map = false; + NodeKind kind = PRIMITIVE; + + if (field.kind() == google::protobuf::Field::TYPE_MESSAGE) { + kind = OBJECT; + util::StatusOr<const google::protobuf::Type*> found_result = + typeinfo->ResolveTypeUrl(field.type_url()); + if (!found_result.ok()) { + // "field" is of an unknown type. + GOOGLE_LOG(WARNING) << "Cannot resolve type '" << field.type_url() << "'."; + } else { + const google::protobuf::Type* found_type = found_result.value(); + is_map = IsMap(field, *found_type); + + if (!is_map) { + field_type = found_type; + } else { + // If this field is a map, we should use the type of its "Value" as + // the type of the child node. + field_type = GetMapValueType(*found_type, typeinfo); + kind = MAP; + } + } + } + + if (!is_map && + field.cardinality() == google::protobuf::Field::CARDINALITY_REPEATED) { + kind = LIST; + } + + // If oneof_index() != 0, the child field is part of a "oneof", which means + // the child field is optional and we shouldn't populate its default + // primitive value. + if (field.oneof_index() != 0 && kind == PRIMITIVE) continue; + + // If the child field is of primitive type, sets its data to the default + // value of its type. + std::unique_ptr<Node> child( + new Node(preserve_proto_field_names_ ? field.name() : field.json_name(), + field_type, kind, + kind == PRIMITIVE ? CreateDefaultDataPieceForField( + field, typeinfo, use_ints_for_enums_) + : DataPiece::NullData(), + true, path, suppress_empty_list_, preserve_proto_field_names_, + use_ints_for_enums_, field_scrub_callback_)); + new_children.push_back(child.release()); + } + // Adds all leftover nodes in children_ to the beginning of new_child. + for (int i = 0; i < children_.size(); ++i) { + if (children_[i] == nullptr) { + continue; + } + new_children.insert(new_children.begin(), children_[i]); + children_[i] = nullptr; + } + children_.swap(new_children); +} + +void DefaultValueObjectWriter::MaybePopulateChildrenOfAny(Node* node) { + // If this is an "Any" node with "@type" already given and no other children + // have been added, populates its children. + if (node != nullptr && node->is_any() && node->type() != nullptr && + node->type()->name() != kAnyType && node->number_of_children() == 1) { + node->PopulateChildren(typeinfo_); + } +} + +DataPiece DefaultValueObjectWriter::FindEnumDefault( + const google::protobuf::Field& field, const TypeInfo* typeinfo, + bool use_ints_for_enums) { + const google::protobuf::Enum* enum_type = + typeinfo->GetEnumByTypeUrl(field.type_url()); + if (!enum_type) { + GOOGLE_LOG(WARNING) << "Could not find enum with type '" << field.type_url() + << "'"; + return DataPiece::NullData(); + } + if (!field.default_value().empty()) { + if (!use_ints_for_enums) { + return DataPiece(field.default_value(), true); + } else { + const TProtoStringType& enum_default_value_name = field.default_value(); + for (int enum_index = 0; enum_index < enum_type->enumvalue_size(); + ++enum_index) { + auto& enum_value = enum_type->enumvalue(enum_index); + if (enum_value.name() == enum_default_value_name) + return DataPiece(enum_value.number()); + } + GOOGLE_LOG(WARNING) << "Could not find enum value '" << enum_default_value_name + << "' with type '" << field.type_url() << "'"; + return DataPiece::NullData(); + } + } + // We treat the first value as the default if none is specified. + return enum_type->enumvalue_size() > 0 + ? (use_ints_for_enums + ? DataPiece(enum_type->enumvalue(0).number()) + : DataPiece(enum_type->enumvalue(0).name(), true)) + : DataPiece::NullData(); +} + +DataPiece DefaultValueObjectWriter::CreateDefaultDataPieceForField( + const google::protobuf::Field& field, const TypeInfo* typeinfo, + bool use_ints_for_enums) { + switch (field.kind()) { + case google::protobuf::Field::TYPE_DOUBLE: { + return DataPiece(ConvertTo<double>( + field.default_value(), &DataPiece::ToDouble, static_cast<double>(0))); + } + case google::protobuf::Field::TYPE_FLOAT: { + return DataPiece(ConvertTo<float>( + field.default_value(), &DataPiece::ToFloat, static_cast<float>(0))); + } + case google::protobuf::Field::TYPE_INT64: + case google::protobuf::Field::TYPE_SINT64: + case google::protobuf::Field::TYPE_SFIXED64: { + return DataPiece(ConvertTo<arc_i64>( + field.default_value(), &DataPiece::ToInt64, static_cast<arc_i64>(0))); + } + case google::protobuf::Field::TYPE_UINT64: + case google::protobuf::Field::TYPE_FIXED64: { + return DataPiece(ConvertTo<arc_ui64>(field.default_value(), + &DataPiece::ToUint64, + static_cast<arc_ui64>(0))); + } + case google::protobuf::Field::TYPE_INT32: + case google::protobuf::Field::TYPE_SINT32: + case google::protobuf::Field::TYPE_SFIXED32: { + return DataPiece(ConvertTo<arc_i32>( + field.default_value(), &DataPiece::ToInt32, static_cast<arc_i32>(0))); + } + case google::protobuf::Field::TYPE_BOOL: { + return DataPiece( + ConvertTo<bool>(field.default_value(), &DataPiece::ToBool, false)); + } + case google::protobuf::Field::TYPE_STRING: { + return DataPiece(field.default_value(), true); + } + case google::protobuf::Field::TYPE_BYTES: { + return DataPiece(field.default_value(), false, true); + } + case google::protobuf::Field::TYPE_UINT32: + case google::protobuf::Field::TYPE_FIXED32: { + return DataPiece(ConvertTo<arc_ui32>(field.default_value(), + &DataPiece::ToUint32, + static_cast<arc_ui32>(0))); + } + case google::protobuf::Field::TYPE_ENUM: { + return FindEnumDefault(field, typeinfo, use_ints_for_enums); + } + default: { + return DataPiece::NullData(); + } + } +} + +DefaultValueObjectWriter* DefaultValueObjectWriter::StartObject( + StringPiece name) { + if (current_ == nullptr) { + std::vector<TProtoStringType> path; + root_.reset(CreateNewNode(TProtoStringType(name), &type_, OBJECT, + DataPiece::NullData(), false, path, + suppress_empty_list_, preserve_proto_field_names_, + use_ints_for_enums_, field_scrub_callback_)); + root_->PopulateChildren(typeinfo_); + current_ = root_.get(); + return this; + } + MaybePopulateChildrenOfAny(current_); + Node* child = current_->FindChild(name); + if (current_->kind() == LIST || current_->kind() == MAP || child == nullptr) { + // If current_ is a list or a map node, we should create a new child and use + // the type of current_ as the type of the new child. + std::unique_ptr<Node> node( + CreateNewNode(TProtoStringType(name), + ((current_->kind() == LIST || current_->kind() == MAP) + ? current_->type() + : nullptr), + OBJECT, DataPiece::NullData(), false, + child == nullptr ? current_->path() : child->path(), + suppress_empty_list_, preserve_proto_field_names_, + use_ints_for_enums_, field_scrub_callback_)); + child = node.get(); + current_->AddChild(node.release()); + } + + child->set_is_placeholder(false); + if (child->kind() == OBJECT && child->number_of_children() == 0) { + child->PopulateChildren(typeinfo_); + } + + stack_.push(current_); + current_ = child; + return this; +} + +DefaultValueObjectWriter* DefaultValueObjectWriter::EndObject() { + if (stack_.empty()) { + // The root object ends here. Writes out the tree. + WriteRoot(); + return this; + } + current_ = stack_.top(); + stack_.pop(); + return this; +} + +DefaultValueObjectWriter* DefaultValueObjectWriter::StartList( + StringPiece name) { + if (current_ == nullptr) { + std::vector<TProtoStringType> path; + root_.reset(CreateNewNode(TProtoStringType(name), &type_, LIST, + DataPiece::NullData(), false, path, + suppress_empty_list_, preserve_proto_field_names_, + use_ints_for_enums_, field_scrub_callback_)); + current_ = root_.get(); + return this; + } + MaybePopulateChildrenOfAny(current_); + Node* child = current_->FindChild(name); + if (child == nullptr || child->kind() != LIST) { + std::unique_ptr<Node> node(CreateNewNode( + TProtoStringType(name), nullptr, LIST, DataPiece::NullData(), false, + child == nullptr ? current_->path() : child->path(), + suppress_empty_list_, preserve_proto_field_names_, use_ints_for_enums_, + field_scrub_callback_)); + child = node.get(); + current_->AddChild(node.release()); + } + child->set_is_placeholder(false); + + stack_.push(current_); + current_ = child; + return this; +} + +void DefaultValueObjectWriter::WriteRoot() { + root_->WriteTo(ow_); + root_.reset(nullptr); + current_ = nullptr; +} + +DefaultValueObjectWriter* DefaultValueObjectWriter::EndList() { + if (stack_.empty()) { + WriteRoot(); + return this; + } + current_ = stack_.top(); + stack_.pop(); + return this; +} + +void DefaultValueObjectWriter::RenderDataPiece(StringPiece name, + const DataPiece& data) { + MaybePopulateChildrenOfAny(current_); + if (current_->type() != nullptr && current_->type()->name() == kAnyType && + name == "@type") { + util::StatusOr<TProtoStringType> data_string = data.ToString(); + if (data_string.ok()) { + const TProtoStringType& string_value = data_string.value(); + // If the type of current_ is "Any" and its "@type" field is being set + // here, sets the type of current_ to be the type specified by the + // "@type". + util::StatusOr<const google::protobuf::Type*> found_type = + typeinfo_->ResolveTypeUrl(string_value); + if (!found_type.ok()) { + GOOGLE_LOG(WARNING) << "Failed to resolve type '" << string_value << "'."; + } else { + current_->set_type(found_type.value()); + } + current_->set_is_any(true); + // If the "@type" field is placed after other fields, we should populate + // other children of primitive type now. Otherwise, we should wait until + // the first value field is rendered before we populate the children, + // because the "value" field of a Any message could be omitted. + if (current_->number_of_children() > 1 && current_->type() != nullptr) { + current_->PopulateChildren(typeinfo_); + } + } + } + Node* child = current_->FindChild(name); + if (child == nullptr || child->kind() != PRIMITIVE) { + // No children are found, creates a new child. + std::unique_ptr<Node> node( + CreateNewNode(TProtoStringType(name), nullptr, PRIMITIVE, data, false, + child == nullptr ? current_->path() : child->path(), + suppress_empty_list_, preserve_proto_field_names_, + use_ints_for_enums_, field_scrub_callback_)); + current_->AddChild(node.release()); + } else { + child->set_data(data); + child->set_is_placeholder(false); + } +} + +} // namespace converter +} // namespace util +} // namespace protobuf +} // namespace google diff --git a/contrib/libs/protobuf_old/src/google/protobuf/util/internal/default_value_objectwriter.h b/contrib/libs/protobuf_old/src/google/protobuf/util/internal/default_value_objectwriter.h new file mode 100644 index 0000000000..0cb3491a41 --- /dev/null +++ b/contrib/libs/protobuf_old/src/google/protobuf/util/internal/default_value_objectwriter.h @@ -0,0 +1,332 @@ +// 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_UTIL_CONVERTER_DEFAULT_VALUE_OBJECTWRITER_H__ +#define GOOGLE_PROTOBUF_UTIL_CONVERTER_DEFAULT_VALUE_OBJECTWRITER_H__ + +#include <cstdint> +#include <functional> +#include <memory> +#include <stack> +#include <vector> + +#include <google/protobuf/stubs/common.h> +#include <google/protobuf/util/internal/type_info.h> +#include <google/protobuf/util/internal/datapiece.h> +#include <google/protobuf/util/internal/object_writer.h> +#include <google/protobuf/util/internal/utility.h> +#include <google/protobuf/util/type_resolver.h> +#include <google/protobuf/stubs/strutil.h> + +// Must be included last. +#include <google/protobuf/port_def.inc> + +namespace google { +namespace protobuf { +namespace util { +namespace converter { + +// An ObjectWriter that renders non-repeated primitive fields of proto messages +// with their default values. DefaultValueObjectWriter holds objects, lists and +// fields it receives in a tree structure and writes them out to another +// ObjectWriter when EndObject() is called on the root object. It also writes +// out all non-repeated primitive fields that haven't been explicitly rendered +// with their default values (0 for numbers, "" for strings, etc). +class PROTOBUF_EXPORT DefaultValueObjectWriter : public ObjectWriter { + public: + // A Callback function to check whether a field needs to be scrubbed. + // + // Returns true if the field should not be present in the output. Returns + // false otherwise. + // + // The 'path' parameter is a vector of path to the field from root. For + // example: if a nested field "a.b.c" (b is the parent message field of c and + // a is the parent message field of b), then the vector should contain { "a", + // "b", "c" }. + // + // The Field* should point to the google::protobuf::Field of "c". + typedef std::function<bool( + const std::vector<TProtoStringType>& /*path of the field*/, + const google::protobuf::Field* /*field*/)> + FieldScrubCallBack; + + DefaultValueObjectWriter(TypeResolver* type_resolver, + const google::protobuf::Type& type, + ObjectWriter* ow); + + virtual ~DefaultValueObjectWriter(); + + // ObjectWriter methods. + DefaultValueObjectWriter* StartObject(StringPiece name) override; + + DefaultValueObjectWriter* EndObject() override; + + DefaultValueObjectWriter* StartList(StringPiece name) override; + + DefaultValueObjectWriter* EndList() override; + + DefaultValueObjectWriter* RenderBool(StringPiece name, + bool value) override; + + DefaultValueObjectWriter* RenderInt32(StringPiece name, + arc_i32 value) override; + + DefaultValueObjectWriter* RenderUint32(StringPiece name, + arc_ui32 value) override; + + DefaultValueObjectWriter* RenderInt64(StringPiece name, + arc_i64 value) override; + + DefaultValueObjectWriter* RenderUint64(StringPiece name, + arc_ui64 value) override; + + DefaultValueObjectWriter* RenderDouble(StringPiece name, + double value) override; + + DefaultValueObjectWriter* RenderFloat(StringPiece name, + float value) override; + + DefaultValueObjectWriter* RenderString(StringPiece name, + StringPiece value) override; + DefaultValueObjectWriter* RenderBytes(StringPiece name, + StringPiece value) override; + + DefaultValueObjectWriter* RenderNull(StringPiece name) override; + + // Register the callback for scrubbing of fields. + void RegisterFieldScrubCallBack(FieldScrubCallBack field_scrub_callback); + + // If set to true, empty lists are suppressed from output when default values + // are written. + void set_suppress_empty_list(bool value) { suppress_empty_list_ = value; } + + // If set to true, original proto field names are used + void set_preserve_proto_field_names(bool value) { + preserve_proto_field_names_ = value; + } + + // If set to true, enums are rendered as ints from output when default values + // are written. + void set_print_enums_as_ints(bool value) { use_ints_for_enums_ = value; } + + protected: + enum NodeKind { + PRIMITIVE = 0, + OBJECT = 1, + LIST = 2, + MAP = 3, + }; + + // "Node" represents a node in the tree that holds the input of + // DefaultValueObjectWriter. + class PROTOBUF_EXPORT Node { + public: + Node(const TProtoStringType& name, const google::protobuf::Type* type, + NodeKind kind, const DataPiece& data, bool is_placeholder, + const std::vector<TProtoStringType>& path, bool suppress_empty_list, + bool preserve_proto_field_names, bool use_ints_for_enums, + FieldScrubCallBack field_scrub_callback); + virtual ~Node() { + for (int i = 0; i < children_.size(); ++i) { + delete children_[i]; + } + } + + // Adds a child to this node. Takes ownership of this child. + void AddChild(Node* child) { children_.push_back(child); } + + // Finds the child given its name. + Node* FindChild(StringPiece name); + + // Populates children of this Node based on its type. If there are already + // children created, they will be merged to the result. Caller should pass + // in TypeInfo for looking up types of the children. + virtual void PopulateChildren(const TypeInfo* typeinfo); + + // If this node is a leaf (has data), writes the current node to the + // ObjectWriter; if not, then recursively writes the children to the + // ObjectWriter. + virtual void WriteTo(ObjectWriter* ow); + + // Accessors + const TProtoStringType& name() const { return name_; } + + const std::vector<TProtoStringType>& path() const { return path_; } + + const google::protobuf::Type* type() const { return type_; } + + void set_type(const google::protobuf::Type* type) { type_ = type; } + + NodeKind kind() const { return kind_; } + + int number_of_children() const { return children_.size(); } + + void set_data(const DataPiece& data) { data_ = data; } + + bool is_any() const { return is_any_; } + + void set_is_any(bool is_any) { is_any_ = is_any; } + + void set_is_placeholder(bool is_placeholder) { + is_placeholder_ = is_placeholder; + } + + protected: + // Returns the Value Type of a map given the Type of the map entry and a + // TypeInfo instance. + const google::protobuf::Type* GetMapValueType( + const google::protobuf::Type& found_type, const TypeInfo* typeinfo); + + // Calls WriteTo() on every child in children_. + void WriteChildren(ObjectWriter* ow); + + // The name of this node. + TProtoStringType name_; + // google::protobuf::Type of this node. Owned by TypeInfo. + const google::protobuf::Type* type_; + // The kind of this node. + NodeKind kind_; + // Whether this is a node for "Any". + bool is_any_; + // The data of this node when it is a leaf node. + DataPiece data_; + // Children of this node. + std::vector<Node*> children_; + // Whether this node is a placeholder for an object or list automatically + // generated when creating the parent node. Should be set to false after + // the parent node's StartObject()/StartList() method is called with this + // node's name. + bool is_placeholder_; + + // Path of the field of this node + std::vector<TProtoStringType> path_; + + // Whether to suppress empty list output. + bool suppress_empty_list_; + + // Whether to preserve original proto field names + bool preserve_proto_field_names_; + + // Whether to always print enums as ints + bool use_ints_for_enums_; + + // Function for determining whether a field needs to be scrubbed or not. + FieldScrubCallBack field_scrub_callback_; + + private: + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(Node); + }; + + // Creates a new Node and returns it. Caller owns memory of returned object. + virtual Node* CreateNewNode(const TProtoStringType& name, + const google::protobuf::Type* type, NodeKind kind, + const DataPiece& data, bool is_placeholder, + const std::vector<TProtoStringType>& path, + bool suppress_empty_list, + bool preserve_proto_field_names, + bool use_ints_for_enums, + FieldScrubCallBack field_scrub_callback); + + // Creates a DataPiece containing the default value of the type of the field. + static DataPiece CreateDefaultDataPieceForField( + const google::protobuf::Field& field, const TypeInfo* typeinfo) { + return CreateDefaultDataPieceForField(field, typeinfo, false); + } + + // Same as the above but with a flag to use ints instead of enum names. + static DataPiece CreateDefaultDataPieceForField( + const google::protobuf::Field& field, const TypeInfo* typeinfo, + bool use_ints_for_enums); + + protected: + // Returns a pointer to current Node in tree. + Node* current() { return current_; } + + private: + // Populates children of "node" if it is an "any" Node and its real type has + // been given. + void MaybePopulateChildrenOfAny(Node* node); + + // Writes the root_ node to ow_ and resets the root_ and current_ pointer to + // nullptr. + void WriteRoot(); + + // Adds or replaces the data_ of a primitive child node. + void RenderDataPiece(StringPiece name, const DataPiece& data); + + // Returns the default enum value as a DataPiece, or the first enum value if + // there is no default. For proto3, where we cannot specify an explicit + // default, a zero value will always be returned. + static DataPiece FindEnumDefault(const google::protobuf::Field& field, + const TypeInfo* typeinfo, + bool use_ints_for_enums); + + // Type information for all the types used in the descriptor. Used to find + // google::protobuf::Type of nested messages/enums. + const TypeInfo* typeinfo_; + // Whether the TypeInfo object is owned by this class. + bool own_typeinfo_; + // google::protobuf::Type of the root message type. + const google::protobuf::Type& type_; + // Holds copies of strings passed to RenderString. + std::vector<std::unique_ptr<TProtoStringType>> string_values_; + + // The current Node. Owned by its parents. + Node* current_; + // The root Node. + std::unique_ptr<Node> root_; + // The stack to hold the path of Nodes from current_ to root_; + std::stack<Node*> stack_; + + // Whether to suppress output of empty lists. + bool suppress_empty_list_; + + // Whether to preserve original proto field names + bool preserve_proto_field_names_; + + // Whether to always print enums as ints + bool use_ints_for_enums_; + + // Function for determining whether a field needs to be scrubbed or not. + FieldScrubCallBack field_scrub_callback_; + + ObjectWriter* ow_; + + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(DefaultValueObjectWriter); +}; + +} // namespace converter +} // namespace util +} // namespace protobuf +} // namespace google + +#include <google/protobuf/port_undef.inc> + +#endif // GOOGLE_PROTOBUF_UTIL_CONVERTER_DEFAULT_VALUE_OBJECTWRITER_H__ diff --git a/contrib/libs/protobuf_old/src/google/protobuf/util/internal/error_listener.cc b/contrib/libs/protobuf_old/src/google/protobuf/util/internal/error_listener.cc new file mode 100644 index 0000000000..538307bae2 --- /dev/null +++ b/contrib/libs/protobuf_old/src/google/protobuf/util/internal/error_listener.cc @@ -0,0 +1,42 @@ +// 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 <google/protobuf/util/internal/error_listener.h> + +namespace google { +namespace protobuf { +namespace util { +namespace converter { + + +} // namespace converter +} // namespace util +} // namespace protobuf +} // namespace google diff --git a/contrib/libs/protobuf_old/src/google/protobuf/util/internal/error_listener.h b/contrib/libs/protobuf_old/src/google/protobuf/util/internal/error_listener.h new file mode 100644 index 0000000000..745b66a952 --- /dev/null +++ b/contrib/libs/protobuf_old/src/google/protobuf/util/internal/error_listener.h @@ -0,0 +1,109 @@ +// 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_UTIL_CONVERTER_ERROR_LISTENER_H__ +#define GOOGLE_PROTOBUF_UTIL_CONVERTER_ERROR_LISTENER_H__ + +#include <algorithm> +#include <memory> +#include <string> +#include <vector> + +#include <google/protobuf/stubs/callback.h> +#include <google/protobuf/stubs/common.h> +#include <google/protobuf/stubs/logging.h> +#include <google/protobuf/util/internal/location_tracker.h> +#include <google/protobuf/stubs/strutil.h> + +// Must be included last. +#include <google/protobuf/port_def.inc> + +namespace google { +namespace protobuf { +namespace util { +namespace converter { + +// Interface for error listener. +class PROTOBUF_EXPORT ErrorListener { + public: + virtual ~ErrorListener() {} + + // Reports an invalid name at the given location. + virtual void InvalidName(const LocationTrackerInterface& loc, + StringPiece invalid_name, + StringPiece message) = 0; + + // Reports an invalid value for a field. + virtual void InvalidValue(const LocationTrackerInterface& loc, + StringPiece type_name, + StringPiece value) = 0; + + // Reports a missing required field. + virtual void MissingField(const LocationTrackerInterface& loc, + StringPiece missing_name) = 0; + + protected: + ErrorListener() {} + + private: + // Do not add any data members to this class. + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ErrorListener); +}; + +// An error listener that ignores all errors. +class PROTOBUF_EXPORT NoopErrorListener : public ErrorListener { + public: + NoopErrorListener() {} + ~NoopErrorListener() override {} + + void InvalidName(const LocationTrackerInterface& /*loc*/, + StringPiece /* invalid_name */, + StringPiece /* message */) override {} + + void InvalidValue(const LocationTrackerInterface& /*loc*/, + StringPiece /* type_name */, + StringPiece /* value */) override {} + + void MissingField(const LocationTrackerInterface& /* loc */, + StringPiece /* missing_name */) override {} + + private: + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(NoopErrorListener); +}; + + +} // namespace converter +} // namespace util +} // namespace protobuf +} // namespace google + +#include <google/protobuf/port_undef.inc> + +#endif // GOOGLE_PROTOBUF_UTIL_CONVERTER_ERROR_LISTENER_H__ diff --git a/contrib/libs/protobuf_old/src/google/protobuf/util/internal/field_mask_utility.cc b/contrib/libs/protobuf_old/src/google/protobuf/util/internal/field_mask_utility.cc new file mode 100644 index 0000000000..94d2738cf6 --- /dev/null +++ b/contrib/libs/protobuf_old/src/google/protobuf/util/internal/field_mask_utility.cc @@ -0,0 +1,218 @@ +// 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 <google/protobuf/util/internal/field_mask_utility.h> + +#include <google/protobuf/util/internal/utility.h> +#include <google/protobuf/stubs/status.h> +#include <google/protobuf/stubs/strutil.h> +#include <google/protobuf/stubs/status_macros.h> + +// Must be included last. +#include <google/protobuf/port_def.inc> + +namespace google { +namespace protobuf { +namespace util { +namespace converter { + +namespace { + +// Appends a FieldMask path segment to a prefix. +TProtoStringType AppendPathSegmentToPrefix(StringPiece prefix, + StringPiece segment) { + if (prefix.empty()) { + return TProtoStringType(segment); + } + if (segment.empty()) { + return TProtoStringType(prefix); + } + // If the segment is a map key, appends it to the prefix without the ".". + if (HasPrefixString(segment, "[\"")) { + return StrCat(prefix, segment); + } + return StrCat(prefix, ".", segment); +} + +} // namespace + +TProtoStringType ConvertFieldMaskPath(const StringPiece path, + ConverterCallback converter) { + TProtoStringType result; + result.reserve(path.size() << 1); + + bool is_quoted = false; + bool is_escaping = false; + int current_segment_start = 0; + + // Loops until 1 passed the end of the input to make handling the last + // segment easier. + for (size_t i = 0; i <= path.size(); ++i) { + // Outputs quoted string as-is. + if (is_quoted) { + if (i == path.size()) { + break; + } + result.push_back(path[i]); + if (is_escaping) { + is_escaping = false; + } else if (path[i] == '\\') { + is_escaping = true; + } else if (path[i] == '\"') { + current_segment_start = i + 1; + is_quoted = false; + } + continue; + } + if (i == path.size() || path[i] == '.' || path[i] == '(' || + path[i] == ')' || path[i] == '\"') { + result += converter( + path.substr(current_segment_start, i - current_segment_start)); + if (i < path.size()) { + result.push_back(path[i]); + } + current_segment_start = i + 1; + } + if (i < path.size() && path[i] == '\"') { + is_quoted = true; + } + } + return result; +} + +util::Status DecodeCompactFieldMaskPaths(StringPiece paths, + PathSinkCallback path_sink) { + std::stack<TProtoStringType> prefix; + int length = paths.length(); + int previous_position = 0; + bool in_map_key = false; + bool is_escaping = false; + // Loops until 1 passed the end of the input to make the handle of the last + // segment easier. + for (int i = 0; i <= length; ++i) { + if (i != length) { + // Skips everything in a map key until we hit the end of it, which is + // marked by an un-escaped '"' immediately followed by a ']'. + if (in_map_key) { + if (is_escaping) { + is_escaping = false; + continue; + } + if (paths[i] == '\\') { + is_escaping = true; + continue; + } + if (paths[i] != '\"') { + continue; + } + // Un-escaped '"' must be followed with a ']'. + if (i >= length - 1 || paths[i + 1] != ']') { + return util::InvalidArgumentError(StrCat( + "Invalid FieldMask '", paths, + "'. Map keys should be represented as [\"some_key\"].")); + } + // The end of the map key ("\"]") has been found. + in_map_key = false; + // Skips ']'. + i++; + // Checks whether the key ends at the end of a path segment. + if (i < length - 1 && paths[i + 1] != '.' && paths[i + 1] != ',' && + paths[i + 1] != ')' && paths[i + 1] != '(') { + return util::InvalidArgumentError(StrCat( + "Invalid FieldMask '", paths, + "'. Map keys should be at the end of a path segment.")); + } + is_escaping = false; + continue; + } + + // We are not in a map key, look for the start of one. + if (paths[i] == '[') { + if (i >= length - 1 || paths[i + 1] != '\"') { + return util::InvalidArgumentError(StrCat( + "Invalid FieldMask '", paths, + "'. Map keys should be represented as [\"some_key\"].")); + } + // "[\"" starts a map key. + in_map_key = true; + i++; // Skips the '\"'. + continue; + } + // If the current character is not a special character (',', '(' or ')'), + // continue to the next. + if (paths[i] != ',' && paths[i] != ')' && paths[i] != '(') { + continue; + } + } + // Gets the current segment - sub-string between previous position (after + // '(', ')', ',', or the beginning of the input) and the current position. + StringPiece segment = + paths.substr(previous_position, i - previous_position); + TProtoStringType current_prefix = prefix.empty() ? "" : prefix.top(); + + if (i < length && paths[i] == '(') { + // Builds a prefix and save it into the stack. + prefix.push(AppendPathSegmentToPrefix(current_prefix, segment)); + } else if (!segment.empty()) { + // When the current character is ')', ',' or the current position has + // passed the end of the input, builds and outputs a new paths by + // concatenating the last prefix with the current segment. + RETURN_IF_ERROR( + path_sink(AppendPathSegmentToPrefix(current_prefix, segment))); + } + + // Removes the last prefix after seeing a ')'. + if (i < length && paths[i] == ')') { + if (prefix.empty()) { + return util::InvalidArgumentError( + StrCat("Invalid FieldMask '", paths, + "'. Cannot find matching '(' for all ')'.")); + } + prefix.pop(); + } + previous_position = i + 1; + } + if (in_map_key) { + return util::InvalidArgumentError( + StrCat("Invalid FieldMask '", paths, + "'. Cannot find matching ']' for all '['.")); + } + if (!prefix.empty()) { + return util::InvalidArgumentError( + StrCat("Invalid FieldMask '", paths, + "'. Cannot find matching ')' for all '('.")); + } + return util::Status(); +} + +} // namespace converter +} // namespace util +} // namespace protobuf +} // namespace google diff --git a/contrib/libs/protobuf_old/src/google/protobuf/util/internal/field_mask_utility.h b/contrib/libs/protobuf_old/src/google/protobuf/util/internal/field_mask_utility.h new file mode 100644 index 0000000000..5019460dc6 --- /dev/null +++ b/contrib/libs/protobuf_old/src/google/protobuf/util/internal/field_mask_utility.h @@ -0,0 +1,74 @@ +// 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. + +// FieldMask related utility methods. + +#ifndef GOOGLE_PROTOBUF_UTIL_CONVERTER_FIELD_MASK_UTILITY_H__ +#define GOOGLE_PROTOBUF_UTIL_CONVERTER_FIELD_MASK_UTILITY_H__ + +#include <functional> +#include <stack> + +#include <google/protobuf/stubs/callback.h> +#include <google/protobuf/stubs/common.h> +#include <google/protobuf/stubs/status.h> +#include <google/protobuf/stubs/strutil.h> +#include <google/protobuf/stubs/status.h> + +namespace google { +namespace protobuf { +namespace util { +namespace converter { + +typedef std::function<TProtoStringType(StringPiece)> ConverterCallback; +typedef std::function<util::Status(StringPiece)> PathSinkCallback; + +// Applies a 'converter' to each segment of a FieldMask path and returns the +// result. Quoted strings in the 'path' are copied to the output as-is without +// converting their content. Escaping is supported within quoted strings. +// For example, "ab\"_c" will be returned as "ab\"_c" without any changes. +TProtoStringType ConvertFieldMaskPath(const StringPiece path, + ConverterCallback converter); + +// Decodes a compact list of FieldMasks. For example, "a.b,a.c.d,a.c.e" will be +// decoded into a list of field paths - "a.b", "a.c.d", "a.c.e". And the results +// will be sent to 'path_sink', i.e. 'path_sink' will be called once per +// resulting path. +// Note that we also support Apiary style FieldMask form. The above example in +// the Apiary style will look like "a.b,a.c(d,e)". +util::Status DecodeCompactFieldMaskPaths(StringPiece paths, + PathSinkCallback path_sink); + +} // namespace converter +} // namespace util +} // namespace protobuf +} // namespace google + +#endif // GOOGLE_PROTOBUF_UTIL_CONVERTER_FIELD_MASK_UTILITY_H__ diff --git a/contrib/libs/protobuf_old/src/google/protobuf/util/internal/json_escaping.cc b/contrib/libs/protobuf_old/src/google/protobuf/util/internal/json_escaping.cc new file mode 100644 index 0000000000..699de65b0f --- /dev/null +++ b/contrib/libs/protobuf_old/src/google/protobuf/util/internal/json_escaping.cc @@ -0,0 +1,372 @@ +// 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 <google/protobuf/util/internal/json_escaping.h> + +#include <cstdint> + +#include <google/protobuf/stubs/logging.h> +#include <google/protobuf/stubs/common.h> + +namespace google { +namespace protobuf { +namespace util { +namespace converter { + +namespace { + +// Array of hex characters for conversion to hex. +static const char kHex[] = "0123456789abcdef"; + +// Characters 0x00 to 0x9f are very commonly used, so we provide a special +// table lookup. +// +// For unicode code point ch < 0xa0: +// kCommonEscapes[ch] is the escaped string of ch, if escaping is needed; +// or an empty string, if escaping is not needed. +static const char kCommonEscapes[160][7] = { + // C0 (ASCII and derivatives) control characters + "\\u0000", "\\u0001", "\\u0002", "\\u0003", // 0x00 + "\\u0004", "\\u0005", "\\u0006", "\\u0007", "\\b", "\\t", "\\n", "\\u000b", + "\\f", "\\r", "\\u000e", "\\u000f", "\\u0010", "\\u0011", "\\u0012", + "\\u0013", // 0x10 + "\\u0014", "\\u0015", "\\u0016", "\\u0017", "\\u0018", "\\u0019", "\\u001a", + "\\u001b", "\\u001c", "\\u001d", "\\u001e", "\\u001f", + // Escaping of " and \ are required by www.json.org string definition. + // Escaping of < and > are required for HTML security. + "", "", "\\\"", "", "", "", "", "", // 0x20 + "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", // 0x30 + "", "", "", "", "\\u003c", "", "\\u003e", "", "", "", "", "", "", "", "", + "", // 0x40 + "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", // 0x50 + "", "", "", "", "\\\\", "", "", "", "", "", "", "", "", "", "", "", // 0x60 + "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", // 0x70 + "", "", "", "", "", "", "", "\\u007f", + // C1 (ISO 8859 and Unicode) extended control characters + "\\u0080", "\\u0081", "\\u0082", "\\u0083", // 0x80 + "\\u0084", "\\u0085", "\\u0086", "\\u0087", "\\u0088", "\\u0089", "\\u008a", + "\\u008b", "\\u008c", "\\u008d", "\\u008e", "\\u008f", "\\u0090", "\\u0091", + "\\u0092", "\\u0093", // 0x90 + "\\u0094", "\\u0095", "\\u0096", "\\u0097", "\\u0098", "\\u0099", "\\u009a", + "\\u009b", "\\u009c", "\\u009d", "\\u009e", "\\u009f"}; + +// Determines if the given char value is a unicode surrogate code unit (either +// high-surrogate or low-surrogate). +inline bool IsSurrogate(arc_ui32 c) { + // Optimized form of: + // return c >= kMinHighSurrogate && c <= kMaxLowSurrogate; + // (Reduced from 3 ALU instructions to 2 ALU instructions) + return (c & 0xfffff800) == JsonEscaping::kMinHighSurrogate; +} + +// Returns true if the given unicode code point cp is a valid +// unicode code point (i.e. in the range 0 <= cp <= kMaxCodePoint). +inline bool IsValidCodePoint(arc_ui32 cp) { + return cp <= JsonEscaping::kMaxCodePoint; +} + +// Returns the low surrogate for the given unicode code point. The result is +// meaningless if the given code point is not a supplementary character. +inline uint16_t ToLowSurrogate(arc_ui32 cp) { + return (cp & + (JsonEscaping::kMaxLowSurrogate - JsonEscaping::kMinLowSurrogate)) + + JsonEscaping::kMinLowSurrogate; +} + +// Returns the high surrogate for the given unicode code point. The result is +// meaningless if the given code point is not a supplementary character. +inline uint16_t ToHighSurrogate(arc_ui32 cp) { + return (cp >> 10) + (JsonEscaping::kMinHighSurrogate - + (JsonEscaping::kMinSupplementaryCodePoint >> 10)); +} + +// Input str is encoded in UTF-8. A unicode code point could be encoded in +// UTF-8 using anywhere from 1 to 4 characters, and it could span multiple +// reads of the ByteSource. +// +// This function reads the next unicode code point from the input (str) at +// the given position (index), taking into account any left-over partial +// code point from the previous iteration (cp), together with the number +// of characters left to read to complete this code point (num_left). +// +// This function assumes that the input (str) is valid at the given position +// (index). In order words, at least one character could be read successfully. +// +// The code point read (partial or complete) is stored in (cp). Upon return, +// (num_left) stores the number of characters that has yet to be read in +// order to complete the current unicode code point. If the read is complete, +// then (num_left) is 0. Also, (num_read) is the number of characters read. +// +// Returns false if we encounter an invalid UTF-8 string. Returns true +// otherwise, including the case when we reach the end of the input (str) +// before a complete unicode code point is read. +bool ReadCodePoint(StringPiece str, int index, arc_ui32* cp, + int* num_left, int* num_read) { + if (*num_left == 0) { + // Last read was complete. Start reading a new unicode code point. + *cp = static_cast<uint8_t>(str[index++]); + *num_read = 1; + // The length of the code point is determined from reading the first byte. + // + // If the first byte is between: + // 0..0x7f: that's the value of the code point. + // 0x80..0xbf: <invalid> + // 0xc0..0xdf: 11-bit code point encoded in 2 bytes. + // bit 10-6, bit 5-0 + // 0xe0..0xef: 16-bit code point encoded in 3 bytes. + // bit 15-12, bit 11-6, bit 5-0 + // 0xf0..0xf7: 21-bit code point encoded in 4 bytes. + // bit 20-18, bit 17-12, bit 11-6, bit 5-0 + // 0xf8..0xff: <invalid> + // + // Meaning of each bit: + // <msb> bit 7: 0 - single byte code point: bits 6-0 are values. + // 1 - multibyte code point + // bit 6: 0 - subsequent bytes of multibyte code point: + // bits 5-0 are values. + // 1 - first byte of multibyte code point + // bit 5: 0 - first byte of 2-byte code point: bits 4-0 are values. + // 1 - first byte of code point with >= 3 bytes. + // bit 4: 0 - first byte of 3-byte code point: bits 3-0 are values. + // 1 - first byte of code point with >= 4 bytes. + // bit 3: 0 - first byte of 4-byte code point: bits 2-0 are values. + // 1 - reserved for future expansion. + if (*cp <= 0x7f) { + return true; + } else if (*cp <= 0xbf) { + return false; + } else if (*cp <= 0xdf) { + *cp &= 0x1f; + *num_left = 1; + } else if (*cp <= 0xef) { + *cp &= 0x0f; + *num_left = 2; + } else if (*cp <= 0xf7) { + *cp &= 0x07; + *num_left = 3; + } else { + return false; + } + } else { + // Last read was partial. Initialize num_read to 0 and continue reading + // the last unicode code point. + *num_read = 0; + } + while (*num_left > 0 && index < str.size()) { + arc_ui32 ch = static_cast<uint8_t>(str[index++]); + --(*num_left); + ++(*num_read); + *cp = (*cp << 6) | (ch & 0x3f); + if (ch < 0x80 || ch > 0xbf) return false; + } + return *num_left > 0 || (!IsSurrogate(*cp) && IsValidCodePoint(*cp)); +} + +// Stores the 16-bit unicode code point as its hexadecimal digits in buffer +// and returns a StringPiece that points to this buffer. The input buffer needs +// to be at least 6 bytes long. +StringPiece ToHex(uint16_t cp, char* buffer) { + buffer[5] = kHex[cp & 0x0f]; + cp >>= 4; + buffer[4] = kHex[cp & 0x0f]; + cp >>= 4; + buffer[3] = kHex[cp & 0x0f]; + cp >>= 4; + buffer[2] = kHex[cp & 0x0f]; + return StringPiece(buffer, 6); +} + +// Stores the 32-bit unicode code point as its hexadecimal digits in buffer +// and returns a StringPiece that points to this buffer. The input buffer needs +// to be at least 12 bytes long. +StringPiece ToSurrogateHex(arc_ui32 cp, char* buffer) { + uint16_t low = ToLowSurrogate(cp); + uint16_t high = ToHighSurrogate(cp); + + buffer[11] = kHex[low & 0x0f]; + low >>= 4; + buffer[10] = kHex[low & 0x0f]; + low >>= 4; + buffer[9] = kHex[low & 0x0f]; + low >>= 4; + buffer[8] = kHex[low & 0x0f]; + + buffer[5] = kHex[high & 0x0f]; + high >>= 4; + buffer[4] = kHex[high & 0x0f]; + high >>= 4; + buffer[3] = kHex[high & 0x0f]; + high >>= 4; + buffer[2] = kHex[high & 0x0f]; + + return StringPiece(buffer, 12); +} + +// If the given unicode code point needs escaping, then returns the +// escaped form. The returned StringPiece either points to statically +// pre-allocated char[] or to the given buffer. The input buffer needs +// to be at least 12 bytes long. +// +// If the given unicode code point does not need escaping, an empty +// StringPiece is returned. +StringPiece EscapeCodePoint(arc_ui32 cp, char* buffer) { + if (cp < 0xa0) return kCommonEscapes[cp]; + switch (cp) { + // These are not required by json spec + // but used to prevent security bugs in javascript. + case 0xfeff: // Zero width no-break space + case 0xfff9: // Interlinear annotation anchor + case 0xfffa: // Interlinear annotation separator + case 0xfffb: // Interlinear annotation terminator + + case 0x00ad: // Soft-hyphen + case 0x06dd: // Arabic end of ayah + case 0x070f: // Syriac abbreviation mark + case 0x17b4: // Khmer vowel inherent Aq + case 0x17b5: // Khmer vowel inherent Aa + return ToHex(cp, buffer); + + default: + if ((cp >= 0x0600 && cp <= 0x0603) || // Arabic signs + (cp >= 0x200b && cp <= 0x200f) || // Zero width etc. + (cp >= 0x2028 && cp <= 0x202e) || // Separators etc. + (cp >= 0x2060 && cp <= 0x2064) || // Invisible etc. + (cp >= 0x206a && cp <= 0x206f)) { // Shaping etc. + return ToHex(cp, buffer); + } + + if (cp == 0x000e0001 || // Language tag + (cp >= 0x0001d173 && cp <= 0x0001d17a) || // Music formatting + (cp >= 0x000e0020 && cp <= 0x000e007f)) { // TAG symbols + return ToSurrogateHex(cp, buffer); + } + } + return StringPiece(); +} + +// Tries to escape the given code point first. If the given code point +// does not need to be escaped, but force_output is true, then render +// the given multi-byte code point in UTF8 in the buffer and returns it. +StringPiece EscapeCodePoint(arc_ui32 cp, char* buffer, + bool force_output) { + StringPiece sp = EscapeCodePoint(cp, buffer); + if (force_output && sp.empty()) { + buffer[5] = (cp & 0x3f) | 0x80; + cp >>= 6; + if (cp <= 0x1f) { + buffer[4] = cp | 0xc0; + sp = StringPiece(buffer + 4, 2); + return sp; + } + buffer[4] = (cp & 0x3f) | 0x80; + cp >>= 6; + if (cp <= 0x0f) { + buffer[3] = cp | 0xe0; + sp = StringPiece(buffer + 3, 3); + return sp; + } + buffer[3] = (cp & 0x3f) | 0x80; + buffer[2] = ((cp >> 6) & 0x07) | 0xf0; + sp = StringPiece(buffer + 2, 4); + } + return sp; +} + +} // namespace + +void JsonEscaping::Escape(strings::ByteSource* input, + strings::ByteSink* output) { + char buffer[12] = "\\udead\\ubee"; + arc_ui32 cp = 0; // Current unicode code point. + int num_left = 0; // Num of chars to read to complete the code point. + while (input->Available() > 0) { + StringPiece str = input->Peek(); + StringPiece escaped; + int i = 0; + int num_read; + bool ok; + bool cp_was_split = num_left > 0; + // Loop until we encounter either + // i) a code point that needs to be escaped; or + // ii) a split code point is completely read; or + // iii) a character that is not a valid utf8; or + // iv) end of the StringPiece str is reached. + do { + ok = ReadCodePoint(str, i, &cp, &num_left, &num_read); + if (num_left > 0 || !ok) break; // case iii or iv + escaped = EscapeCodePoint(cp, buffer, cp_was_split); + if (!escaped.empty()) break; // case i or ii + i += num_read; + num_read = 0; + } while (i < str.length()); // case iv + // First copy the un-escaped prefix, if any, to the output ByteSink. + if (i > 0) input->CopyTo(output, i); + if (num_read > 0) input->Skip(num_read); + if (!ok) { + // Case iii: Report error. + // TODO(wpoon): Add error reporting. + num_left = 0; + } else if (num_left == 0 && !escaped.empty()) { + // Case i or ii: Append the escaped code point to the output ByteSink. + output->Append(escaped.data(), escaped.size()); + } + } + if (num_left > 0) { + // Treat as case iii: report error. + // TODO(wpoon): Add error reporting. + } +} + +void JsonEscaping::Escape(StringPiece input, strings::ByteSink* output) { + const size_t len = input.length(); + const char* p = input.data(); + + bool can_skip_escaping = true; + for (int i = 0; i < len; i++) { + char c = p[i]; + if (c < 0x20 || c >= 0x7F || c == '"' || c == '<' || c == '>' || + c == '\\') { + can_skip_escaping = false; + break; + } + } + + if (can_skip_escaping) { + output->Append(input.data(), input.length()); + } else { + strings::ArrayByteSource source(input); + Escape(&source, output); + } +} + +} // namespace converter +} // namespace util +} // namespace protobuf +} // namespace google diff --git a/contrib/libs/protobuf_old/src/google/protobuf/util/internal/json_escaping.h b/contrib/libs/protobuf_old/src/google/protobuf/util/internal/json_escaping.h new file mode 100644 index 0000000000..98ae79b718 --- /dev/null +++ b/contrib/libs/protobuf_old/src/google/protobuf/util/internal/json_escaping.h @@ -0,0 +1,98 @@ +// 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_UTIL_INTERNAL__JSON_ESCAPING_H__ +#define GOOGLE_PROTOBUF_UTIL_INTERNAL__JSON_ESCAPING_H__ + +#include <cstdint> + +#include <google/protobuf/stubs/common.h> +#include <google/protobuf/stubs/bytestream.h> + +namespace google { +namespace protobuf { +namespace util { +namespace converter { + +class JsonEscaping { + public: + // The minimum value of a unicode high-surrogate code unit in the utf-16 + // encoding. A high-surrogate is also known as a leading-surrogate. + // See http://www.unicode.org/glossary/#high_surrogate_code_unit + static constexpr uint16_t kMinHighSurrogate = 0xd800; + + // The maximum value of a unicide high-surrogate code unit in the utf-16 + // encoding. A high-surrogate is also known as a leading-surrogate. + // See http://www.unicode.org/glossary/#high_surrogate_code_unit + static constexpr uint16_t kMaxHighSurrogate = 0xdbff; + + // The minimum value of a unicode low-surrogate code unit in the utf-16 + // encoding. A low-surrogate is also known as a trailing-surrogate. + // See http://www.unicode.org/glossary/#low_surrogate_code_unit + static constexpr uint16_t kMinLowSurrogate = 0xdc00; + + // The maximum value of a unicode low-surrogate code unit in the utf-16 + // encoding. A low-surrogate is also known as a trailing surrogate. + // See http://www.unicode.org/glossary/#low_surrogate_code_unit + static constexpr uint16_t kMaxLowSurrogate = 0xdfff; + + // The minimum value of a unicode supplementary code point. + // See http://www.unicode.org/glossary/#supplementary_code_point + static constexpr arc_ui32 kMinSupplementaryCodePoint = 0x010000; + + // The minimum value of a unicode code point. + // See http://www.unicode.org/glossary/#code_point + static constexpr arc_ui32 kMinCodePoint = 0x000000; + + // The maximum value of a unicode code point. + // See http://www.unicode.org/glossary/#code_point + static constexpr arc_ui32 kMaxCodePoint = 0x10ffff; + + JsonEscaping() {} + virtual ~JsonEscaping() {} + + // Escape the given ByteSource to the given ByteSink. + static void Escape(strings::ByteSource* input, strings::ByteSink* output); + + // Escape the given ByteSource to the given ByteSink. + // This is optimized for the case where the string is all printable 7-bit + // ASCII and does not contain a few other characters (such as quotes). + static void Escape(StringPiece input, strings::ByteSink* output); + + private: + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(JsonEscaping); +}; + +} // namespace converter +} // namespace util +} // namespace protobuf +} // namespace google + +#endif // GOOGLE_PROTOBUF_UTIL_INTERNAL__JSON_ESCAPING_H__ diff --git a/contrib/libs/protobuf_old/src/google/protobuf/util/internal/json_objectwriter.cc b/contrib/libs/protobuf_old/src/google/protobuf/util/internal/json_objectwriter.cc new file mode 100644 index 0000000000..c40e582e32 --- /dev/null +++ b/contrib/libs/protobuf_old/src/google/protobuf/util/internal/json_objectwriter.cc @@ -0,0 +1,190 @@ +// 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 <google/protobuf/util/internal/json_objectwriter.h> + +#include <cmath> +#include <cstdint> +#include <limits> + +#include <google/protobuf/stubs/casts.h> +#include <google/protobuf/stubs/logging.h> +#include <google/protobuf/stubs/common.h> +#include <google/protobuf/util/internal/utility.h> +#include <google/protobuf/util/internal/json_escaping.h> +#include <google/protobuf/stubs/strutil.h> + +namespace google { +namespace protobuf { +namespace util { +namespace converter { + + +JsonObjectWriter::~JsonObjectWriter() { + if (element_ && !element_->is_root()) { + GOOGLE_LOG(WARNING) << "JsonObjectWriter was not fully closed."; + } +} + +JsonObjectWriter* JsonObjectWriter::StartObject(StringPiece name) { + WritePrefix(name); + WriteChar('{'); + PushObject(); + return this; +} + +JsonObjectWriter* JsonObjectWriter::EndObject() { + Pop(); + WriteChar('}'); + if (element() && element()->is_root()) NewLine(); + return this; +} + +JsonObjectWriter* JsonObjectWriter::StartList(StringPiece name) { + WritePrefix(name); + WriteChar('['); + PushArray(); + return this; +} + +JsonObjectWriter* JsonObjectWriter::EndList() { + Pop(); + WriteChar(']'); + if (element()->is_root()) NewLine(); + return this; +} + +JsonObjectWriter* JsonObjectWriter::RenderBool(StringPiece name, + bool value) { + return RenderSimple(name, value ? "true" : "false"); +} + +JsonObjectWriter* JsonObjectWriter::RenderInt32(StringPiece name, + arc_i32 value) { + return RenderSimple(name, StrCat(value)); +} + +JsonObjectWriter* JsonObjectWriter::RenderUint32(StringPiece name, + arc_ui32 value) { + return RenderSimple(name, StrCat(value)); +} + +JsonObjectWriter* JsonObjectWriter::RenderInt64(StringPiece name, + arc_i64 value) { + WritePrefix(name); + WriteChar('"'); + WriteRawString(StrCat(value)); + WriteChar('"'); + return this; +} + +JsonObjectWriter* JsonObjectWriter::RenderUint64(StringPiece name, + arc_ui64 value) { + WritePrefix(name); + WriteChar('"'); + WriteRawString(StrCat(value)); + WriteChar('"'); + return this; +} + +JsonObjectWriter* JsonObjectWriter::RenderDouble(StringPiece name, + double value) { + if (std::isfinite(value)) { + return RenderSimple(name, SimpleDtoa(value)); + } + + // Render quoted with NaN/Infinity-aware DoubleAsString. + return RenderString(name, DoubleAsString(value)); +} + +JsonObjectWriter* JsonObjectWriter::RenderFloat(StringPiece name, + float value) { + if (std::isfinite(value)) { + return RenderSimple(name, SimpleFtoa(value)); + } + + // Render quoted with NaN/Infinity-aware FloatAsString. + return RenderString(name, FloatAsString(value)); +} + +JsonObjectWriter* JsonObjectWriter::RenderString(StringPiece name, + StringPiece value) { + WritePrefix(name); + WriteChar('"'); + JsonEscaping::Escape(value, &sink_); + WriteChar('"'); + return this; +} + +JsonObjectWriter* JsonObjectWriter::RenderBytes(StringPiece name, + StringPiece value) { + WritePrefix(name); + TProtoStringType base64; + + if (use_websafe_base64_for_bytes_) + WebSafeBase64EscapeWithPadding(TProtoStringType(value), &base64); + else + Base64Escape(value, &base64); + + WriteChar('"'); + // TODO(wpoon): Consider a ByteSink solution that writes the base64 bytes + // directly to the stream, rather than first putting them + // into a string and then writing them to the stream. + stream_->WriteRaw(base64.data(), base64.size()); + WriteChar('"'); + return this; +} + +JsonObjectWriter* JsonObjectWriter::RenderNull(StringPiece name) { + return RenderSimple(name, "null"); +} + +JsonObjectWriter* JsonObjectWriter::RenderNullAsEmpty(StringPiece name) { + return RenderSimple(name, ""); +} + +void JsonObjectWriter::WritePrefix(StringPiece name) { + bool not_first = !element()->is_first(); + if (not_first) WriteChar(','); + if (not_first || !element()->is_root()) NewLine(); + if (!name.empty() || element()->is_json_object()) { + WriteChar('"'); + if (!name.empty()) { + JsonEscaping::Escape(name, &sink_); + } + WriteRawString("\":"); + if (!indent_string_.empty()) WriteChar(' '); + } +} + +} // namespace converter +} // namespace util +} // namespace protobuf +} // namespace google diff --git a/contrib/libs/protobuf_old/src/google/protobuf/util/internal/json_objectwriter.h b/contrib/libs/protobuf_old/src/google/protobuf/util/internal/json_objectwriter.h new file mode 100644 index 0000000000..b5520d300a --- /dev/null +++ b/contrib/libs/protobuf_old/src/google/protobuf/util/internal/json_objectwriter.h @@ -0,0 +1,278 @@ +// 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_UTIL_CONVERTER_JSON_OBJECTWRITER_H__ +#define GOOGLE_PROTOBUF_UTIL_CONVERTER_JSON_OBJECTWRITER_H__ + +#include <cstdint> +#include <memory> +#include <string> + +#include <google/protobuf/io/coded_stream.h> +#include <google/protobuf/util/internal/structured_objectwriter.h> +#include <google/protobuf/stubs/bytestream.h> + +// clang-format off +#include <google/protobuf/port_def.inc> +// clang-format on + +namespace google { +namespace protobuf { +namespace util { +namespace converter { + + +// An ObjectWriter implementation that outputs JSON. This ObjectWriter +// supports writing a compact form or a pretty printed form. +// +// Sample usage: +// string output; +// StringOutputStream* str_stream = new StringOutputStream(&output); +// CodedOutputStream* out_stream = new CodedOutputStream(str_stream); +// JsonObjectWriter* ow = new JsonObjectWriter(" ", out_stream); +// ow->StartObject("") +// ->RenderString("name", "value") +// ->RenderString("emptystring", string()) +// ->StartObject("nested") +// ->RenderInt64("light", 299792458); +// ->RenderDouble("pi", 3.141592653589793); +// ->EndObject() +// ->StartList("empty") +// ->EndList() +// ->EndObject(); +// +// And then the output string would become: +// { +// "name": "value", +// "emptystring": "", +// "nested": { +// "light": "299792458", +// "pi": 3.141592653589793 +// }, +// "empty": [] +// } +// +// JsonObjectWriter does not validate if calls actually result in valid JSON. +// For example, passing an empty name when one would be required won't result +// in an error, just an invalid output. +// +// Note that all int64 and uint64 are rendered as strings instead of numbers. +// This is because JavaScript parses numbers as 64-bit float thus int64 and +// uint64 would lose precision if rendered as numbers. +// +// JsonObjectWriter is thread-unsafe. +class PROTOBUF_EXPORT JsonObjectWriter : public StructuredObjectWriter { + public: + JsonObjectWriter(StringPiece indent_string, io::CodedOutputStream* out) + : element_(new Element(/*parent=*/nullptr, /*is_json_object=*/false)), + stream_(out), + sink_(out), + indent_string_(indent_string), + indent_char_('\0'), + indent_count_(0), + use_websafe_base64_for_bytes_(false) { + // See if we have a trivial sequence of indent characters. + if (!indent_string.empty()) { + indent_char_ = indent_string[0]; + indent_count_ = indent_string.length(); + for (int i = 1; i < indent_string.length(); i++) { + if (indent_char_ != indent_string_[i]) { + indent_char_ = '\0'; + indent_count_ = 0; + break; + } + } + } + } + virtual ~JsonObjectWriter(); + + // ObjectWriter methods. + JsonObjectWriter* StartObject(StringPiece name) override; + JsonObjectWriter* EndObject() override; + JsonObjectWriter* StartList(StringPiece name) override; + JsonObjectWriter* EndList() override; + JsonObjectWriter* RenderBool(StringPiece name, bool value) override; + JsonObjectWriter* RenderInt32(StringPiece name, arc_i32 value) override; + JsonObjectWriter* RenderUint32(StringPiece name, + arc_ui32 value) override; + JsonObjectWriter* RenderInt64(StringPiece name, arc_i64 value) override; + JsonObjectWriter* RenderUint64(StringPiece name, + arc_ui64 value) override; + JsonObjectWriter* RenderDouble(StringPiece name, double value) override; + JsonObjectWriter* RenderFloat(StringPiece name, float value) override; + JsonObjectWriter* RenderString(StringPiece name, + StringPiece value) override; + JsonObjectWriter* RenderBytes(StringPiece name, StringPiece value) override; + JsonObjectWriter* RenderNull(StringPiece name) override; + virtual JsonObjectWriter* RenderNullAsEmpty(StringPiece name); + + void set_use_websafe_base64_for_bytes(bool value) { + use_websafe_base64_for_bytes_ = value; + } + + protected: + class PROTOBUF_EXPORT Element : public BaseElement { + public: + Element(Element* parent, bool is_json_object) + : BaseElement(parent), + is_first_(true), + is_json_object_(is_json_object) {} + + // Called before each field of the Element is to be processed. + // Returns true if this is the first call (processing the first field). + bool is_first() { + if (is_first_) { + is_first_ = false; + return true; + } + return false; + } + + // Whether we are currently rendering inside a JSON object (i.e., between + // StartObject() and EndObject()). + bool is_json_object() const { return is_json_object_; } + + private: + bool is_first_; + bool is_json_object_; + + GOOGLE_DISALLOW_IMPLICIT_CONSTRUCTORS(Element); + }; + + Element* element() override { return element_.get(); } + + private: + class PROTOBUF_EXPORT ByteSinkWrapper : public strings::ByteSink { + public: + explicit ByteSinkWrapper(io::CodedOutputStream* stream) : stream_(stream) {} + ~ByteSinkWrapper() override {} + + // ByteSink methods. + void Append(const char* bytes, size_t n) override { + stream_->WriteRaw(bytes, n); + } + + private: + io::CodedOutputStream* stream_; + + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ByteSinkWrapper); + }; + + // Renders a simple value as a string. By default all non-string Render + // methods convert their argument to a string and call this method. This + // method can then be used to render the simple value without escaping it. + JsonObjectWriter* RenderSimple(StringPiece name, + StringPiece value) { + WritePrefix(name); + WriteRawString(value); + return this; + } + + // Pushes a new JSON array element to the stack. + void PushArray() { + element_.reset(new Element(element_.release(), /*is_json_object=*/false)); + } + + // Pushes a new JSON object element to the stack. + void PushObject() { + element_.reset(new Element(element_.release(), /*is_json_object=*/true)); + } + + // Pops an element off of the stack and deletes the popped element. + void Pop() { + bool needs_newline = !element_->is_first(); + element_.reset(element_->pop<Element>()); + if (needs_newline) NewLine(); + } + + // If pretty printing is enabled, this will write a newline to the output, + // followed by optional indentation. Otherwise this method is a noop. + void NewLine() { + if (!indent_string_.empty()) { + size_t len = sizeof('\n') + (indent_string_.size() * element()->level()); + + // Take the slow-path if we don't have sufficient characters remaining in + // our buffer or we have a non-trivial indent string which would prevent + // us from using memset. + uint8_t* out = nullptr; + if (indent_count_ > 0) { + out = stream_->GetDirectBufferForNBytesAndAdvance(len); + } + + if (out != nullptr) { + out[0] = '\n'; + memset(&out[1], indent_char_, len - 1); + } else { + // Slow path, no contiguous output buffer available. + WriteChar('\n'); + for (int i = 0; i < element()->level(); i++) { + stream_->WriteRaw(indent_string_.c_str(), indent_string_.length()); + } + } + } + } + + // Writes a prefix. This will write out any pretty printing and + // commas that are required, followed by the name and a ':' if + // the name is not null. + void WritePrefix(StringPiece name); + + // Writes an individual character to the output. + void WriteChar(const char c) { stream_->WriteRaw(&c, sizeof(c)); } + + // Writes a string to the output. + void WriteRawString(StringPiece s) { + stream_->WriteRaw(s.data(), s.length()); + } + + std::unique_ptr<Element> element_; + io::CodedOutputStream* stream_; + ByteSinkWrapper sink_; + const TProtoStringType indent_string_; + + // For the common case of indent being a single character repeated. + char indent_char_; + int indent_count_; + + // Whether to use regular or websafe base64 encoding for byte fields. Defaults + // to regular base64 encoding. + bool use_websafe_base64_for_bytes_; + + GOOGLE_DISALLOW_IMPLICIT_CONSTRUCTORS(JsonObjectWriter); +}; + +} // namespace converter +} // namespace util +} // namespace protobuf +} // namespace google + +#include <google/protobuf/port_undef.inc> + +#endif // GOOGLE_PROTOBUF_UTIL_CONVERTER_JSON_OBJECTWRITER_H__ diff --git a/contrib/libs/protobuf_old/src/google/protobuf/util/internal/json_stream_parser.cc b/contrib/libs/protobuf_old/src/google/protobuf/util/internal/json_stream_parser.cc new file mode 100644 index 0000000000..62d2a8fe9b --- /dev/null +++ b/contrib/libs/protobuf_old/src/google/protobuf/util/internal/json_stream_parser.cc @@ -0,0 +1,995 @@ +// 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 <google/protobuf/util/internal/json_stream_parser.h> + +#include <algorithm> +#include <cctype> +#include <cmath> +#include <memory> +#include <stack> +#include <string> + +#include <google/protobuf/stubs/common.h> +#include <google/protobuf/stubs/logging.h> +#include <google/protobuf/stubs/strutil.h> +#include <google/protobuf/stubs/status.h> +#include <google/protobuf/util/internal/object_writer.h> +#include <google/protobuf/util/internal/json_escaping.h> + + +namespace google { +namespace protobuf { +namespace util { + +namespace converter { + +// Number of digits in an escaped UTF-16 code unit ('\\' 'u' X X X X) +static const int kUnicodeEscapedLength = 6; + +static const int kDefaultMaxRecursionDepth = 100; + +// These cannot be constexpr for portability with VS2015. +static const StringPiece kKeywordTrue = "true"; +static const StringPiece kKeywordFalse = "false"; +static const StringPiece kKeywordNull = "null"; + +inline bool IsLetter(char c) { + return ('a' <= c && c <= 'z') || ('A' <= c && c <= 'Z') || (c == '_') || + (c == '$'); +} + +inline bool IsAlphanumeric(char c) { + return IsLetter(c) || ('0' <= c && c <= '9'); +} + +// Indicates a character may not be part of an unquoted key. +inline bool IsKeySeparator(char c) { + return (ascii_isspace(c) || c == '"' || c == '\'' || c == '{' || + c == '}' || c == '[' || c == ']' || c == ':' || c == ','); +} + +inline void ReplaceInvalidCodePoints(StringPiece str, + const TProtoStringType& replacement, + TProtoStringType* dst) { + while (!str.empty()) { + int n_valid_bytes = internal::UTF8SpnStructurallyValid(str); + StringPiece valid_part = str.substr(0, n_valid_bytes); + StrAppend(dst, valid_part); + + if (n_valid_bytes == str.size()) { + break; + } + + // Append replacement value. + StrAppend(dst, replacement); + + // Move past valid bytes + one invalid byte. + str.remove_prefix(n_valid_bytes + 1); + } +} + +static bool ConsumeKey(StringPiece* input, StringPiece* key) { + if (input->empty() || !IsLetter((*input)[0])) return false; + int len = 1; + for (; len < input->size(); ++len) { + if (!IsAlphanumeric((*input)[len])) { + break; + } + } + *key = StringPiece(input->data(), len); + *input = StringPiece(input->data() + len, input->size() - len); + return true; +} + +// Same as 'ConsumeKey', but allows a widened set of key characters. +static bool ConsumeKeyPermissive(StringPiece* input, + StringPiece* key) { + if (input->empty() || !IsLetter((*input)[0])) return false; + int len = 1; + for (; len < input->size(); ++len) { + if (IsKeySeparator((*input)[len])) { + break; + } + } + *key = StringPiece(input->data(), len); + *input = StringPiece(input->data() + len, input->size() - len); + return true; +} + +static bool MatchKey(StringPiece input) { + return !input.empty() && IsLetter(input[0]); +} + +JsonStreamParser::JsonStreamParser(ObjectWriter* ow) + : ow_(ow), + stack_(), + leftover_(), + json_(), + p_(), + key_(), + key_storage_(), + finishing_(false), + seen_non_whitespace_(false), + allow_no_root_element_(false), + parsed_(), + parsed_storage_(), + string_open_(0), + chunk_storage_(), + coerce_to_utf8_(false), + utf8_replacement_character_(" "), + allow_empty_null_(false), + allow_permissive_key_naming_(false), + loose_float_number_conversion_(false), + recursion_depth_(0), + max_recursion_depth_(kDefaultMaxRecursionDepth) { + // Initialize the stack with a single value to be parsed. + stack_.push(VALUE); +} + +JsonStreamParser::~JsonStreamParser() {} + + +util::Status JsonStreamParser::Parse(StringPiece json) { + StringPiece chunk = json; + // If we have leftovers from a previous chunk, append the new chunk to it + // and create a new StringPiece pointing at the string's data. This could + // be large but we rely on the chunks to be small, assuming they are + // fragments of a Cord. + if (!leftover_.empty()) { + // Don't point chunk to leftover_ because leftover_ will be updated in + // ParseChunk(chunk). + chunk_storage_.swap(leftover_); + StrAppend(&chunk_storage_, json); + chunk = StringPiece(chunk_storage_); + } + + // Find the structurally valid UTF8 prefix and parse only that. + int n = internal::UTF8SpnStructurallyValid(chunk); + if (n > 0) { + util::Status status = ParseChunk(chunk.substr(0, n)); + + // Any leftover characters are stashed in leftover_ for later parsing when + // there is more data available. + StrAppend(&leftover_, chunk.substr(n)); + return status; + } else { + leftover_.assign(chunk.data(), chunk.size()); + return util::Status(); + } +} + +util::Status JsonStreamParser::FinishParse() { + // If we do not expect anything and there is nothing left to parse we're all + // done. + if (stack_.empty() && leftover_.empty()) { + return util::Status(); + } + + // Lifetime needs to last until RunParser returns, so keep this variable + // outside of the coerce_to_utf8 block. + std::unique_ptr<TProtoStringType> scratch; + + bool is_valid_utf8 = internal::IsStructurallyValidUTF8(leftover_); + if (coerce_to_utf8_ && !is_valid_utf8) { + scratch.reset(new TProtoStringType); + scratch->reserve(leftover_.size() * utf8_replacement_character_.size()); + ReplaceInvalidCodePoints(leftover_, utf8_replacement_character_, + scratch.get()); + p_ = json_ = *scratch; + } else { + p_ = json_ = leftover_; + if (!is_valid_utf8) { + return ReportFailure("Encountered non UTF-8 code points.", + ParseErrorType::NON_UTF_8); + } + } + + // Parse the remainder in finishing mode, which reports errors for things like + // unterminated strings or unknown tokens that would normally be retried. + finishing_ = true; + util::Status result = RunParser(); + if (result.ok()) { + SkipWhitespace(); + if (!p_.empty()) { + result = + ReportFailure("Parsing terminated before end of input.", + ParseErrorType::PARSING_TERMINATED_BEFORE_END_OF_INPUT); + } + } + return result; +} + +util::Status JsonStreamParser::ParseChunk(StringPiece chunk) { + // Do not do any work if the chunk is empty. + if (chunk.empty()) return util::Status(); + + p_ = json_ = chunk; + + finishing_ = false; + util::Status result = RunParser(); + if (!result.ok()) return result; + + SkipWhitespace(); + if (p_.empty()) { + // If we parsed everything we had, clear the leftover. + leftover_.clear(); + } else { + // If we do not expect anything i.e. stack is empty, and we have non-empty + // string left to parse, we report an error. + if (stack_.empty()) { + return ReportFailure( + "Parsing terminated before end of input.", + ParseErrorType::PARSING_TERMINATED_BEFORE_END_OF_INPUT); + } + // If we expect future data i.e. stack is non-empty, and we have some + // unparsed data left, we save it for later parse. + leftover_ = TProtoStringType(p_); + } + return util::Status(); +} + +bool JsonStreamParser::IsInputAllWhiteSpaces(TokenType type) { + // Conclude the whole input is full of white spaces by: + // - it is at the finishing stage + // - we have run out of the input data + // - haven't seen non-whitespace char so far + if (finishing_ && p_.empty() && type == UNKNOWN && !seen_non_whitespace_) { + return true; + } + return false; +} + +util::Status JsonStreamParser::RunParser() { + while (!stack_.empty()) { + ParseType type = stack_.top(); + TokenType t = (string_open_ == 0) ? GetNextTokenType() : BEGIN_STRING; + stack_.pop(); + util::Status result; + switch (type) { + case VALUE: + if (allow_no_root_element_ && IsInputAllWhiteSpaces(t)) { + return util::Status(); + } + result = ParseValue(t); + break; + + case OBJ_MID: + result = ParseObjectMid(t); + break; + + case ENTRY: + result = ParseEntry(t); + break; + + case ENTRY_MID: + result = ParseEntryMid(t); + break; + + case ARRAY_VALUE: + result = ParseArrayValue(t); + break; + + case ARRAY_MID: + result = ParseArrayMid(t); + break; + + default: + result = + util::InternalError(StrCat("Unknown parse type: ", type)); + break; + } + if (!result.ok()) { + // If we were cancelled, save our state and try again later. + if (!finishing_ && util::IsCancelled(result)) { + stack_.push(type); + // If we have a key we still need to render, make sure to save off the + // contents in our own storage. + if (!key_.empty() && key_storage_.empty()) { + StrAppend(&key_storage_, key_); + key_ = StringPiece(key_storage_); + } + result = util::Status(); + } + return result; + } + } + return util::Status(); +} + +util::Status JsonStreamParser::ParseValue(TokenType type) { + switch (type) { + case BEGIN_OBJECT: + return HandleBeginObject(); + case BEGIN_ARRAY: + return HandleBeginArray(); + case BEGIN_STRING: + return ParseString(); + case BEGIN_NUMBER: + return ParseNumber(); + case BEGIN_TRUE: + return ParseTrue(); + case BEGIN_FALSE: + return ParseFalse(); + case BEGIN_NULL: + return ParseNull(); + case UNKNOWN: + return ReportUnknown("Expected a value.", ParseErrorType::EXPECTED_VALUE); + default: { + // Special case for having been cut off while parsing, wait for more data. + // This handles things like 'fals' being at the end of the string, we + // don't know if the next char would be e, completing it, or something + // else, making it invalid. + if (!finishing_ && p_.length() < kKeywordFalse.length()) { + return util::CancelledError(""); + } + + if (allow_empty_null_ && IsEmptyNullAllowed(type)) { + return ParseEmptyNull(); + } + return ReportFailure("Unexpected token.", + ParseErrorType::UNEXPECTED_TOKEN); + } + } +} + +util::Status JsonStreamParser::ParseString() { + util::Status result = ParseStringHelper(); + if (result.ok()) { + ow_->RenderString(key_, parsed_); + key_ = StringPiece(); + parsed_ = StringPiece(); + parsed_storage_.clear(); + } + return result; +} + +util::Status JsonStreamParser::ParseStringHelper() { + // If we haven't seen the start quote, grab it and remember it for later. + if (string_open_ == 0) { + string_open_ = *p_.data(); + GOOGLE_DCHECK(string_open_ == '\"' || string_open_ == '\''); + Advance(); + } + // Track where we last copied data from so we can minimize copying. + const char* last = p_.data(); + while (!p_.empty()) { + const char* data = p_.data(); + if (*data == '\\') { + // We're about to handle an escape, copy all bytes from last to data. + if (last < data) { + parsed_storage_.append(last, data - last); + } + // If we ran out of string after the \, cancel or report an error + // depending on if we expect more data later. + if (p_.length() == 1) { + if (!finishing_) { + return util::CancelledError(""); + } + return ReportFailure("Closing quote expected in string.", + ParseErrorType::EXPECTED_CLOSING_QUOTE); + } + // Parse a unicode escape if we found \u in the string. + if (data[1] == 'u') { + util::Status result = ParseUnicodeEscape(); + if (!result.ok()) { + return result; + } + // Move last pointer past the unicode escape and continue. + last = p_.data(); + continue; + } + // Handle the standard set of backslash-escaped characters. + switch (data[1]) { + case 'b': + parsed_storage_.push_back('\b'); + break; + case 'f': + parsed_storage_.push_back('\f'); + break; + case 'n': + parsed_storage_.push_back('\n'); + break; + case 'r': + parsed_storage_.push_back('\r'); + break; + case 't': + parsed_storage_.push_back('\t'); + break; + case 'v': + parsed_storage_.push_back('\v'); + break; + default: + parsed_storage_.push_back(data[1]); + } + // We handled two characters, so advance past them and continue. + p_.remove_prefix(2); + last = p_.data(); + continue; + } + // If we found the closing quote note it, advance past it, and return. + if (*data == string_open_) { + // If we didn't copy anything, reuse the input buffer. + if (parsed_storage_.empty()) { + parsed_ = StringPiece(last, data - last); + } else { + if (last < data) { + parsed_storage_.append(last, data - last); + } + parsed_ = StringPiece(parsed_storage_); + } + // Clear the quote char so next time we try to parse a string we'll + // start fresh. + string_open_ = 0; + Advance(); + return util::Status(); + } + // Normal character, just advance past it. + Advance(); + } + // If we ran out of characters, copy over what we have so far. + if (last < p_.data()) { + parsed_storage_.append(last, p_.data() - last); + } + // If we didn't find the closing quote but we expect more data, cancel for now + if (!finishing_) { + return util::CancelledError(""); + } + // End of string reached without a closing quote, report an error. + string_open_ = 0; + return ReportFailure("Closing quote expected in string.", + ParseErrorType::EXPECTED_CLOSING_QUOTE); +} + +// Converts a unicode escaped character to a decimal value stored in a char32 +// for use in UTF8 encoding utility. We assume that str begins with \uhhhh and +// convert that from the hex number to a decimal value. +// +// There are some security exploits with UTF-8 that we should be careful of: +// - http://www.unicode.org/reports/tr36/#UTF-8_Exploit +// - http://sites/intl-eng/design-guide/core-application +util::Status JsonStreamParser::ParseUnicodeEscape() { + if (p_.length() < kUnicodeEscapedLength) { + if (!finishing_) { + return util::CancelledError(""); + } + return ReportFailure("Illegal hex string.", + ParseErrorType::ILLEGAL_HEX_STRING); + } + GOOGLE_DCHECK_EQ('\\', p_.data()[0]); + GOOGLE_DCHECK_EQ('u', p_.data()[1]); + uint32 code = 0; + for (int i = 2; i < kUnicodeEscapedLength; ++i) { + if (!isxdigit(p_.data()[i])) { + return ReportFailure("Invalid escape sequence.", + ParseErrorType::INVALID_ESCAPE_SEQUENCE); + } + code = (code << 4) + hex_digit_to_int(p_.data()[i]); + } + if (code >= JsonEscaping::kMinHighSurrogate && + code <= JsonEscaping::kMaxHighSurrogate) { + if (p_.length() < 2 * kUnicodeEscapedLength) { + if (!finishing_) { + return util::CancelledError(""); + } + if (!coerce_to_utf8_) { + return ReportFailure("Missing low surrogate.", + ParseErrorType::MISSING_LOW_SURROGATE); + } + } else if (p_.data()[kUnicodeEscapedLength] == '\\' && + p_.data()[kUnicodeEscapedLength + 1] == 'u') { + uint32 low_code = 0; + for (int i = kUnicodeEscapedLength + 2; i < 2 * kUnicodeEscapedLength; + ++i) { + if (!isxdigit(p_.data()[i])) { + return ReportFailure("Invalid escape sequence.", + ParseErrorType::INVALID_ESCAPE_SEQUENCE); + } + low_code = (low_code << 4) + hex_digit_to_int(p_.data()[i]); + } + if (low_code >= JsonEscaping::kMinLowSurrogate && + low_code <= JsonEscaping::kMaxLowSurrogate) { + // Convert UTF-16 surrogate pair to 21-bit Unicode codepoint. + code = (((code & 0x3FF) << 10) | (low_code & 0x3FF)) + + JsonEscaping::kMinSupplementaryCodePoint; + // Advance past the first code unit escape. + p_.remove_prefix(kUnicodeEscapedLength); + } else if (!coerce_to_utf8_) { + return ReportFailure("Invalid low surrogate.", + ParseErrorType::INVALID_LOW_SURROGATE); + } + } else if (!coerce_to_utf8_) { + return ReportFailure("Missing low surrogate.", + ParseErrorType::MISSING_LOW_SURROGATE); + } + } + if (!coerce_to_utf8_ && !IsValidCodePoint(code)) { + return ReportFailure("Invalid unicode code point.", + ParseErrorType::INVALID_UNICODE); + } + char buf[UTFmax]; + int len = EncodeAsUTF8Char(code, buf); + // Advance past the [final] code unit escape. + p_.remove_prefix(kUnicodeEscapedLength); + parsed_storage_.append(buf, len); + return util::Status(); +} + +util::Status JsonStreamParser::ParseNumber() { + NumberResult number; + util::Status result = ParseNumberHelper(&number); + if (result.ok()) { + switch (number.type) { + case NumberResult::DOUBLE: + ow_->RenderDouble(key_, number.double_val); + key_ = StringPiece(); + break; + + case NumberResult::INT: + ow_->RenderInt64(key_, number.int_val); + key_ = StringPiece(); + break; + + case NumberResult::UINT: + ow_->RenderUint64(key_, number.uint_val); + key_ = StringPiece(); + break; + + default: + return ReportFailure("Unable to parse number.", + ParseErrorType::UNABLE_TO_PARSE_NUMBER); + } + } + return result; +} + +util::Status JsonStreamParser::ParseDoubleHelper(const TProtoStringType& number, + NumberResult* result) { + if (!safe_strtod(number, &result->double_val)) { + return ReportFailure("Unable to parse number.", + ParseErrorType::UNABLE_TO_PARSE_NUMBER); + } + if (!loose_float_number_conversion_ && !std::isfinite(result->double_val)) { + return ReportFailure("Number exceeds the range of double.", + ParseErrorType::NUMBER_EXCEEDS_RANGE_DOUBLE); + } + result->type = NumberResult::DOUBLE; + return util::Status(); +} + +util::Status JsonStreamParser::ParseNumberHelper(NumberResult* result) { + const char* data = p_.data(); + int length = p_.length(); + + // Look for the first non-numeric character, or the end of the string. + int index = 0; + bool floating = false; + bool negative = data[index] == '-'; + // Find the first character that cannot be part of the number. Along the way + // detect if the number needs to be parsed as a double. + // Note that this restricts numbers to the JSON specification, so for example + // we do not support hex or octal notations. + for (; index < length; ++index) { + char c = data[index]; + if (isdigit(c)) continue; + if (c == '.' || c == 'e' || c == 'E') { + floating = true; + continue; + } + if (c == '+' || c == '-' || c == 'x') continue; + // Not a valid number character, break out. + break; + } + + // If the entire input is a valid number, and we may have more content in the + // future, we abort for now and resume when we know more. + if (index == length && !finishing_) { + return util::CancelledError(""); + } + + // Create a string containing just the number, so we can use safe_strtoX + TProtoStringType number = TProtoStringType(p_.substr(0, index)); + + // Floating point number, parse as a double. + if (floating) { + util::Status status = ParseDoubleHelper(number, result); + if (status.ok()) { + p_.remove_prefix(index); + } + return status; + } + + // Positive non-floating point number, parse as a uint64. + if (!negative) { + // Octal/Hex numbers are not valid JSON values. + if (number.length() >= 2 && number[0] == '0') { + return ReportFailure( + "Octal/hex numbers are not valid JSON values.", + ParseErrorType::OCTAL_OR_HEX_ARE_NOT_VALID_JSON_VALUES); + } + if (safe_strtou64(number, &result->uint_val)) { + result->type = NumberResult::UINT; + p_.remove_prefix(index); + return util::Status(); + } else { + // If the value is too large, parse it as double. + util::Status status = ParseDoubleHelper(number, result); + if (status.ok()) { + p_.remove_prefix(index); + } + return status; + } + } + + // Octal/Hex numbers are not valid JSON values. + if (number.length() >= 3 && number[1] == '0') { + return ReportFailure( + "Octal/hex numbers are not valid JSON values.", + ParseErrorType::OCTAL_OR_HEX_ARE_NOT_VALID_JSON_VALUES); + } + // Negative non-floating point number, parse as an int64. + if (safe_strto64(number, &result->int_val)) { + result->type = NumberResult::INT; + p_.remove_prefix(index); + return util::Status(); + } else { + // If the value is too large, parse it as double. + util::Status status = ParseDoubleHelper(number, result); + if (status.ok()) { + p_.remove_prefix(index); + } + return status; + } +} + +util::Status JsonStreamParser::HandleBeginObject() { + GOOGLE_DCHECK_EQ('{', *p_.data()); + Advance(); + ow_->StartObject(key_); + auto status = IncrementRecursionDepth(key_); + if (!status.ok()) { + return status; + } + key_ = StringPiece(); + stack_.push(ENTRY); + return util::Status(); +} + +util::Status JsonStreamParser::ParseObjectMid(TokenType type) { + if (type == UNKNOWN) { + return ReportUnknown("Expected , or } after key:value pair.", + ParseErrorType::EXPECTED_COMMA_OR_BRACES); + } + + // Object is complete, advance past the comma and render the EndObject. + if (type == END_OBJECT) { + Advance(); + ow_->EndObject(); + --recursion_depth_; + return util::Status(); + } + // Found a comma, advance past it and get ready for an entry. + if (type == VALUE_SEPARATOR) { + Advance(); + stack_.push(ENTRY); + return util::Status(); + } + // Illegal token after key:value pair. + return ReportFailure("Expected , or } after key:value pair.", + ParseErrorType::EXPECTED_COMMA_OR_BRACES); +} + +util::Status JsonStreamParser::ParseEntry(TokenType type) { + if (type == UNKNOWN) { + return ReportUnknown("Expected an object key or }.", + ParseErrorType::EXPECTED_OBJECT_KEY_OR_BRACES); + } + + // Close the object and return. This allows for trailing commas. + if (type == END_OBJECT) { + ow_->EndObject(); + Advance(); + --recursion_depth_; + return util::Status(); + } + + util::Status result; + if (type == BEGIN_STRING) { + // Key is a string (standard JSON), parse it and store the string. + result = ParseStringHelper(); + if (result.ok()) { + key_storage_.clear(); + if (!parsed_storage_.empty()) { + parsed_storage_.swap(key_storage_); + key_ = StringPiece(key_storage_); + } else { + key_ = parsed_; + } + parsed_ = StringPiece(); + } + } else if (type == BEGIN_KEY) { + // Key is a bare key (back compat), create a StringPiece pointing to it. + result = ParseKey(); + } else if (type == BEGIN_NULL || type == BEGIN_TRUE || type == BEGIN_FALSE) { + // Key may be a bare key that begins with a reserved word. + result = ParseKey(); + if (result.ok() && (key_ == kKeywordNull || key_ == kKeywordTrue || + key_ == kKeywordFalse)) { + result = ReportFailure("Expected an object key or }.", + ParseErrorType::EXPECTED_OBJECT_KEY_OR_BRACES); + } + } else { + // Unknown key type, report an error. + result = ReportFailure("Expected an object key or }.", + ParseErrorType::EXPECTED_OBJECT_KEY_OR_BRACES); + } + // On success we next expect an entry mid ':' then an object mid ',' or '}' + if (result.ok()) { + stack_.push(OBJ_MID); + stack_.push(ENTRY_MID); + } + return result; +} + +util::Status JsonStreamParser::ParseEntryMid(TokenType type) { + if (type == UNKNOWN) { + return ReportUnknown("Expected : between key:value pair.", + ParseErrorType::EXPECTED_COLON); + } + if (type == ENTRY_SEPARATOR) { + Advance(); + stack_.push(VALUE); + return util::Status(); + } + return ReportFailure("Expected : between key:value pair.", + ParseErrorType::EXPECTED_COLON); +} + +util::Status JsonStreamParser::HandleBeginArray() { + GOOGLE_DCHECK_EQ('[', *p_.data()); + Advance(); + ow_->StartList(key_); + key_ = StringPiece(); + stack_.push(ARRAY_VALUE); + return util::Status(); +} + +util::Status JsonStreamParser::ParseArrayValue(TokenType type) { + if (type == UNKNOWN) { + return ReportUnknown("Expected a value or ] within an array.", + ParseErrorType::EXPECTED_VALUE_OR_BRACKET); + } + + if (type == END_ARRAY) { + ow_->EndList(); + Advance(); + return util::Status(); + } + + // The ParseValue call may push something onto the stack so we need to make + // sure an ARRAY_MID is after it, so we push it on now. Also, the parsing of + // empty-null array value is relying on this ARRAY_MID token. + stack_.push(ARRAY_MID); + util::Status result = ParseValue(type); + if (util::IsCancelled(result)) { + // If we were cancelled, pop back off the ARRAY_MID so we don't try to + // push it on again when we try over. + stack_.pop(); + } + return result; +} + +util::Status JsonStreamParser::ParseArrayMid(TokenType type) { + if (type == UNKNOWN) { + return ReportUnknown("Expected , or ] after array value.", + ParseErrorType::EXPECTED_COMMA_OR_BRACKET); + } + + if (type == END_ARRAY) { + ow_->EndList(); + Advance(); + return util::Status(); + } + + // Found a comma, advance past it and expect an array value next. + if (type == VALUE_SEPARATOR) { + Advance(); + stack_.push(ARRAY_VALUE); + return util::Status(); + } + // Illegal token after array value. + return ReportFailure("Expected , or ] after array value.", + ParseErrorType::EXPECTED_COMMA_OR_BRACKET); +} + +util::Status JsonStreamParser::ParseTrue() { + ow_->RenderBool(key_, true); + key_ = StringPiece(); + p_.remove_prefix(kKeywordTrue.length()); + return util::Status(); +} + +util::Status JsonStreamParser::ParseFalse() { + ow_->RenderBool(key_, false); + key_ = StringPiece(); + p_.remove_prefix(kKeywordFalse.length()); + return util::Status(); +} + +util::Status JsonStreamParser::ParseNull() { + ow_->RenderNull(key_); + key_ = StringPiece(); + p_.remove_prefix(kKeywordNull.length()); + return util::Status(); +} + +util::Status JsonStreamParser::ParseEmptyNull() { + ow_->RenderNull(key_); + key_ = StringPiece(); + return util::Status(); +} + +bool JsonStreamParser::IsEmptyNullAllowed(TokenType type) { + if (stack_.empty()) return false; + return (stack_.top() == ARRAY_MID && type == VALUE_SEPARATOR) || + stack_.top() == OBJ_MID; +} + +util::Status JsonStreamParser::ReportFailure(StringPiece message, + ParseErrorType parse_code) { + (void)parse_code; // Parameter is used in Google-internal code. + static const int kContextLength = 20; + const char* p_start = p_.data(); + const char* json_start = json_.data(); + const char* begin = std::max(p_start - kContextLength, json_start); + const char* end = + std::min(p_start + kContextLength, json_start + json_.size()); + StringPiece segment(begin, end - begin); + TProtoStringType location(p_start - begin, ' '); + location.push_back('^'); + auto status = util::InvalidArgumentError( + StrCat(message, "\n", segment, "\n", location)); + return status; +} + +util::Status JsonStreamParser::ReportUnknown(StringPiece message, + ParseErrorType parse_code) { + // If we aren't finishing the parse, cancel parsing and try later. + if (!finishing_) { + return util::CancelledError(""); + } + if (p_.empty()) { + return ReportFailure(StrCat("Unexpected end of string. ", message), + parse_code); + } + return ReportFailure(message, parse_code); +} + +util::Status JsonStreamParser::IncrementRecursionDepth( + StringPiece key) const { + if (++recursion_depth_ > max_recursion_depth_) { + return util::InvalidArgumentError(StrCat( + "Message too deep. Max recursion depth reached for key '", key, "'")); + } + return util::Status(); +} + +void JsonStreamParser::SkipWhitespace() { + while (!p_.empty() && ascii_isspace(*p_.data())) { + Advance(); + } + if (!p_.empty() && !ascii_isspace(*p_.data())) { + seen_non_whitespace_ = true; + } +} + +void JsonStreamParser::Advance() { + // Advance by moving one UTF8 character while making sure we don't go beyond + // the length of StringPiece. + p_.remove_prefix(std::min<int>( + p_.length(), UTF8FirstLetterNumBytes(p_.data(), p_.length()))); +} + +util::Status JsonStreamParser::ParseKey() { + StringPiece original = p_; + + if (allow_permissive_key_naming_) { + if (!ConsumeKeyPermissive(&p_, &key_)) { + return ReportFailure("Invalid key or variable name.", + ParseErrorType::INVALID_KEY_OR_VARIABLE_NAME); + } + } else { + if (!ConsumeKey(&p_, &key_)) { + return ReportFailure("Invalid key or variable name.", + ParseErrorType::INVALID_KEY_OR_VARIABLE_NAME); + } + } + + // If we consumed everything but expect more data, reset p_ and cancel since + // we can't know if the key was complete or not. + if (!finishing_ && p_.empty()) { + p_ = original; + return util::CancelledError(""); + } + // Since we aren't using the key storage, clear it out. + key_storage_.clear(); + return util::Status(); +} + +JsonStreamParser::TokenType JsonStreamParser::GetNextTokenType() { + SkipWhitespace(); + + int size = p_.size(); + if (size == 0) { + // If we ran out of data, report unknown and we'll place the previous parse + // type onto the stack and try again when we have more data. + return UNKNOWN; + } + // TODO(sven): Split this method based on context since different contexts + // support different tokens. Would slightly speed up processing? + const char* data = p_.data(); + StringPiece data_view = StringPiece(data, size); + if (*data == '\"' || *data == '\'') return BEGIN_STRING; + if (*data == '-' || ('0' <= *data && *data <= '9')) { + return BEGIN_NUMBER; + } + if (size >= kKeywordTrue.length() && + HasPrefixString(data_view, kKeywordTrue)) { + return BEGIN_TRUE; + } + if (size >= kKeywordFalse.length() && + HasPrefixString(data_view, kKeywordFalse)) { + return BEGIN_FALSE; + } + if (size >= kKeywordNull.length() && + HasPrefixString(data_view, kKeywordNull)) { + return BEGIN_NULL; + } + if (*data == '{') return BEGIN_OBJECT; + if (*data == '}') return END_OBJECT; + if (*data == '[') return BEGIN_ARRAY; + if (*data == ']') return END_ARRAY; + if (*data == ':') return ENTRY_SEPARATOR; + if (*data == ',') return VALUE_SEPARATOR; + if (MatchKey(p_)) { + return BEGIN_KEY; + } + + // We don't know that we necessarily have an invalid token here, just that we + // can't parse what we have so far. So we don't report an error and just + // return UNKNOWN so we can try again later when we have more data, or if we + // finish and we have leftovers. + return UNKNOWN; +} + +} // namespace converter +} // namespace util +} // namespace protobuf +} // namespace google diff --git a/contrib/libs/protobuf_old/src/google/protobuf/util/internal/json_stream_parser.h b/contrib/libs/protobuf_old/src/google/protobuf/util/internal/json_stream_parser.h new file mode 100644 index 0000000000..1230f6e6e8 --- /dev/null +++ b/contrib/libs/protobuf_old/src/google/protobuf/util/internal/json_stream_parser.h @@ -0,0 +1,349 @@ +// 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_UTIL_CONVERTER_JSON_STREAM_PARSER_H__ +#define GOOGLE_PROTOBUF_UTIL_CONVERTER_JSON_STREAM_PARSER_H__ + +#include <cstdint> +#include <stack> +#include <string> + +#include <google/protobuf/stubs/common.h> +#include <google/protobuf/stubs/status.h> +#include <google/protobuf/stubs/strutil.h> +#include <google/protobuf/stubs/status.h> + +#include <google/protobuf/port_def.inc> + +namespace google { +namespace protobuf { +namespace util { +namespace converter { + + +class ObjectWriter; + +// A JSON parser that can parse a stream of JSON chunks rather than needing the +// entire JSON string up front. It is a modified version of the parser in +// //net/proto/json/json-parser.h that has been changed in the following ways: +// - Changed from recursion to an explicit stack to allow resumption +// - Added support for int64 and uint64 numbers +// - Removed support for octal and decimal escapes +// - Removed support for numeric keys +// - Removed support for functions (javascript) +// - Removed some lax-comma support (but kept trailing comma support) +// - Writes directly to an ObjectWriter rather than using subclassing +// +// Here is an example usage: +// JsonStreamParser parser(ow_.get()); +// util::Status result = parser.Parse(chunk1); +// result.Update(parser.Parse(chunk2)); +// result.Update(parser.FinishParse()); +// GOOGLE_DCHECK(result.ok()) << "Failed to parse JSON"; +// +// This parser is thread-compatible as long as only one thread is calling a +// Parse() method at a time. +class PROTOBUF_EXPORT JsonStreamParser { + public: + // Creates a JsonStreamParser that will write to the given ObjectWriter. + explicit JsonStreamParser(ObjectWriter* ow); + virtual ~JsonStreamParser(); + + // Parses a UTF-8 encoded JSON string from a StringPiece. If the returned + // status is non-ok, the status might contain a payload ParseErrorType with + // type_url kParseErrorTypeUrl and a payload containing string snippet of the + // error with type_url kParseErrorSnippetUrl. + util::Status Parse(StringPiece json); + + + // Finish parsing the JSON string. If the returned status is non-ok, the + // status might contain a payload ParseErrorType with type_url + // kParseErrorTypeUrl and a payload containing string snippet of the error + // with type_url kParseErrorSnippetUrl. + util::Status FinishParse(); + + + // Sets the max recursion depth of JSON message to be deserialized. JSON + // messages over this depth will fail to be deserialized. + // Default value is 100. + void set_max_recursion_depth(int max_depth) { + max_recursion_depth_ = max_depth; + } + + // Denotes the cause of error. + enum ParseErrorType { + UNKNOWN_PARSE_ERROR, + OCTAL_OR_HEX_ARE_NOT_VALID_JSON_VALUES, + EXPECTED_COLON, + EXPECTED_COMMA_OR_BRACKET, + EXPECTED_VALUE, + EXPECTED_COMMA_OR_BRACES, + EXPECTED_OBJECT_KEY_OR_BRACES, + EXPECTED_VALUE_OR_BRACKET, + INVALID_KEY_OR_VARIABLE_NAME, + NON_UTF_8, + PARSING_TERMINATED_BEFORE_END_OF_INPUT, + UNEXPECTED_TOKEN, + EXPECTED_CLOSING_QUOTE, + ILLEGAL_HEX_STRING, + INVALID_ESCAPE_SEQUENCE, + MISSING_LOW_SURROGATE, + INVALID_LOW_SURROGATE, + INVALID_UNICODE, + UNABLE_TO_PARSE_NUMBER, + NUMBER_EXCEEDS_RANGE_DOUBLE + }; + + private: + friend class JsonStreamParserTest; + // Return the current recursion depth. + int recursion_depth() { return recursion_depth_; } + + enum TokenType { + BEGIN_STRING, // " or ' + BEGIN_NUMBER, // - or digit + BEGIN_TRUE, // true + BEGIN_FALSE, // false + BEGIN_NULL, // null + BEGIN_OBJECT, // { + END_OBJECT, // } + BEGIN_ARRAY, // [ + END_ARRAY, // ] + ENTRY_SEPARATOR, // : + VALUE_SEPARATOR, // , + BEGIN_KEY, // letter, _, $ or digit. Must begin with non-digit + UNKNOWN // Unknown token or we ran out of the stream. + }; + + enum ParseType { + VALUE, // Expects a {, [, true, false, null, string or number + OBJ_MID, // Expects a ',' or } + ENTRY, // Expects a key or } + ENTRY_MID, // Expects a : + ARRAY_VALUE, // Expects a value or ] + ARRAY_MID // Expects a ',' or ] + }; + + // Holds the result of parsing a number + struct NumberResult { + enum Type { DOUBLE, INT, UINT }; + Type type; + union { + double double_val; + arc_i64 int_val; + arc_ui64 uint_val; + }; + }; + + // Parses a single chunk of JSON, returning an error if the JSON was invalid. + util::Status ParseChunk(StringPiece chunk); + + // Runs the parser based on stack_ and p_, until the stack is empty or p_ runs + // out of data. If we unexpectedly run out of p_ we push the latest back onto + // the stack and return. + util::Status RunParser(); + + // Parses a value from p_ and writes it to ow_. + // A value may be an object, array, true, false, null, string or number. + util::Status ParseValue(TokenType type); + + // Parses a string and writes it out to the ow_. + util::Status ParseString(); + + // Parses a string, storing the result in parsed_. + util::Status ParseStringHelper(); + + // This function parses unicode escape sequences in strings. It returns an + // error when there's a parsing error, either the size is not the expected + // size or a character is not a hex digit. When it returns str will contain + // what has been successfully parsed so far. + util::Status ParseUnicodeEscape(); + + // Expects p_ to point to a JSON number, writes the number to the writer using + // the appropriate Render method based on the type of number. + util::Status ParseNumber(); + + // Parse a number into a NumberResult, reporting an error if no number could + // be parsed. This method will try to parse into a uint64, int64, or double + // based on whether the number was positive or negative or had a decimal + // component. + util::Status ParseNumberHelper(NumberResult* result); + + // Parse a number as double into a NumberResult. + util::Status ParseDoubleHelper(const TProtoStringType& number, + NumberResult* result); + + // Handles a { during parsing of a value. + util::Status HandleBeginObject(); + + // Parses from the ENTRY state. + util::Status ParseEntry(TokenType type); + + // Parses from the ENTRY_MID state. + util::Status ParseEntryMid(TokenType type); + + // Parses from the OBJ_MID state. + util::Status ParseObjectMid(TokenType type); + + // Handles a [ during parsing of a value. + util::Status HandleBeginArray(); + + // Parses from the ARRAY_VALUE state. + util::Status ParseArrayValue(TokenType type); + + // Parses from the ARRAY_MID state. + util::Status ParseArrayMid(TokenType type); + + // Expects p_ to point to an unquoted literal + util::Status ParseTrue(); + util::Status ParseFalse(); + util::Status ParseNull(); + util::Status ParseEmptyNull(); + + // Whether an empty-null is allowed in the current state. + bool IsEmptyNullAllowed(TokenType type); + + // Whether the whole input is all whitespaces. + bool IsInputAllWhiteSpaces(TokenType type); + + // Report a failure as a util::Status. + util::Status ReportFailure(StringPiece message, + ParseErrorType parse_code); + + // Report a failure due to an UNKNOWN token type. We check if we hit the + // end of the stream and if we're finishing or not to detect what type of + // status to return in this case. + util::Status ReportUnknown(StringPiece message, + ParseErrorType parse_code); + + // Helper function to check recursion depth and increment it. It will return + // OkStatus() if the current depth is allowed. Otherwise an error is returned. + // key is used for error reporting. + util::Status IncrementRecursionDepth(StringPiece key) const; + + // Advance p_ past all whitespace or until the end of the string. + void SkipWhitespace(); + + // Advance p_ one UTF-8 character + void Advance(); + + // Expects p_ to point to the beginning of a key. + util::Status ParseKey(); + + // Return the type of the next token at p_. + TokenType GetNextTokenType(); + + // The object writer to write parse events to. + ObjectWriter* ow_; + + // The stack of parsing we still need to do. When the stack runs empty we will + // have parsed a single value from the root (e.g. an object or list). + std::stack<ParseType> stack_; + + // Contains any leftover text from a previous chunk that we weren't able to + // fully parse, for example the start of a key or number. + TProtoStringType leftover_; + + // The current chunk of JSON being parsed. Primarily used for providing + // context during error reporting. + StringPiece json_; + + // A pointer within the current JSON being parsed, used to track location. + StringPiece p_; + + // Stores the last key read, as we separate parsing of keys and values. + StringPiece key_; + + // Storage for key_ if we need to keep ownership, for example between chunks + // or if the key was unescaped from a JSON string. + TProtoStringType key_storage_; + + // True during the FinishParse() call, so we know that any errors are fatal. + // For example an unterminated string will normally result in cancelling and + // trying during the next chunk, but during FinishParse() it is an error. + bool finishing_; + + // Whether non whitespace tokens have been seen during parsing. + // It is used to handle the case of a pure whitespace stream input. + bool seen_non_whitespace_; + + // The JsonStreamParser requires a root element by default and it will raise + // error if the root element is missing. If `allow_no_root_element_` is true, + // the JsonStreamParser can also handle this case. + bool allow_no_root_element_; + + // String we parsed during a call to ParseStringHelper(). + StringPiece parsed_; + + // Storage for the string we parsed. This may be empty if the string was able + // to be parsed directly from the input. + TProtoStringType parsed_storage_; + + // The character that opened the string, either ' or ". + // A value of 0 indicates that string parsing is not in process. + char string_open_; + + // Storage for the chunk that are being parsed in ParseChunk(). + TProtoStringType chunk_storage_; + + // Whether to allow non UTF-8 encoded input and replace invalid code points. + bool coerce_to_utf8_; + + // Replacement character for invalid UTF-8 code points. + TProtoStringType utf8_replacement_character_; + + // Whether allows empty string represented null array value or object entry + // value. + bool allow_empty_null_; + + // Whether unquoted object keys can contain embedded non-alphanumeric + // characters when this is unambiguous for parsing. + bool allow_permissive_key_naming_; + + // Whether allows out-of-range floating point numbers or reject them. + bool loose_float_number_conversion_; + + // Tracks current recursion depth. + mutable int recursion_depth_; + + // Maximum allowed recursion depth. + int max_recursion_depth_; + + GOOGLE_DISALLOW_IMPLICIT_CONSTRUCTORS(JsonStreamParser); +}; + +} // namespace converter +} // namespace util +} // namespace protobuf +} // namespace google + +#include <google/protobuf/port_undef.inc> + +#endif // GOOGLE_PROTOBUF_UTIL_CONVERTER_JSON_STREAM_PARSER_H__ diff --git a/contrib/libs/protobuf_old/src/google/protobuf/util/internal/location_tracker.h b/contrib/libs/protobuf_old/src/google/protobuf/util/internal/location_tracker.h new file mode 100644 index 0000000000..9ffe163609 --- /dev/null +++ b/contrib/libs/protobuf_old/src/google/protobuf/util/internal/location_tracker.h @@ -0,0 +1,69 @@ +// 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_UTIL_CONVERTER_LOCATION_TRACKER_H__ +#define GOOGLE_PROTOBUF_UTIL_CONVERTER_LOCATION_TRACKER_H__ + +#include <string> + +#include <google/protobuf/stubs/common.h> + +#include <google/protobuf/port_def.inc> + +namespace google { +namespace protobuf { +namespace util { +namespace converter { + +// LocationTrackerInterface is an interface for classes that track +// the location information for the purpose of error reporting. +class PROTOBUF_EXPORT LocationTrackerInterface { + public: + virtual ~LocationTrackerInterface() {} + + // Returns the object location as human readable string. + virtual TProtoStringType ToString() const = 0; + + protected: + LocationTrackerInterface() {} + + private: + // Please do not add any data members to this class. + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(LocationTrackerInterface); +}; + +} // namespace converter +} // namespace util +} // namespace protobuf +} // namespace google + +#include <google/protobuf/port_undef.inc> + +#endif // GOOGLE_PROTOBUF_UTIL_CONVERTER_LOCATION_TRACKER_H__ diff --git a/contrib/libs/protobuf_old/src/google/protobuf/util/internal/object_location_tracker.h b/contrib/libs/protobuf_old/src/google/protobuf/util/internal/object_location_tracker.h new file mode 100644 index 0000000000..0cd65c87b5 --- /dev/null +++ b/contrib/libs/protobuf_old/src/google/protobuf/util/internal/object_location_tracker.h @@ -0,0 +1,64 @@ +// 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_UTIL_CONVERTER_OBJECT_LOCATION_TRACKER_H__ +#define GOOGLE_PROTOBUF_UTIL_CONVERTER_OBJECT_LOCATION_TRACKER_H__ + +#include <string> + +#include <google/protobuf/stubs/common.h> +#include <google/protobuf/util/internal/location_tracker.h> + +namespace google { +namespace protobuf { +namespace util { +namespace converter { + +// An empty concrete implementation of LocationTrackerInterface. +class ObjectLocationTracker : public LocationTrackerInterface { + public: + // Creates an empty location tracker. + ObjectLocationTracker() {} + + ~ObjectLocationTracker() override {} + + // Returns empty because nothing is tracked. + TProtoStringType ToString() const override { return ""; } + + private: + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ObjectLocationTracker); +}; + +} // namespace converter +} // namespace util +} // namespace protobuf +} // namespace google + +#endif // GOOGLE_PROTOBUF_UTIL_CONVERTER_OBJECT_LOCATION_TRACKER_H__ diff --git a/contrib/libs/protobuf_old/src/google/protobuf/util/internal/object_source.h b/contrib/libs/protobuf_old/src/google/protobuf/util/internal/object_source.h new file mode 100644 index 0000000000..de548c1d0a --- /dev/null +++ b/contrib/libs/protobuf_old/src/google/protobuf/util/internal/object_source.h @@ -0,0 +1,85 @@ +// 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_UTIL_CONVERTER_OBJECT_SOURCE_H__ +#define GOOGLE_PROTOBUF_UTIL_CONVERTER_OBJECT_SOURCE_H__ + +#include <google/protobuf/stubs/common.h> +#include <google/protobuf/stubs/status.h> +#include <google/protobuf/stubs/strutil.h> +#include <google/protobuf/stubs/status.h> + +// Must be included last. +#include <google/protobuf/port_def.inc> + +namespace google { +namespace protobuf { +namespace util { +namespace converter { + +class ObjectWriter; + +// An ObjectSource is anything that can write to an ObjectWriter. +// Implementation of this interface typically provide constructors or +// factory methods to create an instance based on some source data, for +// example, a character stream, or protobuf. +// +// Derived classes could be thread-unsafe. +class PROTOBUF_EXPORT ObjectSource { + public: + virtual ~ObjectSource() {} + + // Writes to the ObjectWriter + virtual util::Status WriteTo(ObjectWriter* ow) const { + return NamedWriteTo("", ow); + } + + // Writes to the ObjectWriter with a custom name for the message. + // This is useful when you chain ObjectSource together by embedding one + // within another. + virtual util::Status NamedWriteTo(StringPiece name, + ObjectWriter* ow) const = 0; + + protected: + ObjectSource() {} + + private: + // Do not add any data members to this class. + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ObjectSource); +}; + +} // namespace converter +} // namespace util +} // namespace protobuf +} // namespace google + +#include <google/protobuf/port_undef.inc> + +#endif // GOOGLE_PROTOBUF_UTIL_CONVERTER_OBJECT_SOURCE_H__ diff --git a/contrib/libs/protobuf_old/src/google/protobuf/util/internal/object_writer.cc b/contrib/libs/protobuf_old/src/google/protobuf/util/internal/object_writer.cc new file mode 100644 index 0000000000..4dabd378e4 --- /dev/null +++ b/contrib/libs/protobuf_old/src/google/protobuf/util/internal/object_writer.cc @@ -0,0 +1,93 @@ +// 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 <google/protobuf/util/internal/object_writer.h> + +#include <google/protobuf/util/internal/datapiece.h> + +namespace google { +namespace protobuf { +namespace util { +namespace converter { + +// static +void ObjectWriter::RenderDataPieceTo(const DataPiece& data, + StringPiece name, ObjectWriter* ow) { + switch (data.type()) { + case DataPiece::TYPE_INT32: { + ow->RenderInt32(name, data.ToInt32().value()); + break; + } + case DataPiece::TYPE_INT64: { + ow->RenderInt64(name, data.ToInt64().value()); + break; + } + case DataPiece::TYPE_UINT32: { + ow->RenderUint32(name, data.ToUint32().value()); + break; + } + case DataPiece::TYPE_UINT64: { + ow->RenderUint64(name, data.ToUint64().value()); + break; + } + case DataPiece::TYPE_DOUBLE: { + ow->RenderDouble(name, data.ToDouble().value()); + break; + } + case DataPiece::TYPE_FLOAT: { + ow->RenderFloat(name, data.ToFloat().value()); + break; + } + case DataPiece::TYPE_BOOL: { + ow->RenderBool(name, data.ToBool().value()); + break; + } + case DataPiece::TYPE_STRING: { + ow->RenderString(name, data.ToString().value()); + break; + } + case DataPiece::TYPE_BYTES: { + ow->RenderBytes(name, data.ToBytes().value()); + break; + } + case DataPiece::TYPE_NULL: { + ow->RenderNull(name); + break; + } + default: + break; + } +} + + +} // namespace converter +} // namespace util +} // namespace protobuf +} // namespace google diff --git a/contrib/libs/protobuf_old/src/google/protobuf/util/internal/object_writer.h b/contrib/libs/protobuf_old/src/google/protobuf/util/internal/object_writer.h new file mode 100644 index 0000000000..69b692979c --- /dev/null +++ b/contrib/libs/protobuf_old/src/google/protobuf/util/internal/object_writer.h @@ -0,0 +1,151 @@ +// 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_UTIL_CONVERTER_OBJECT_WRITER_H__ +#define GOOGLE_PROTOBUF_UTIL_CONVERTER_OBJECT_WRITER_H__ + +#include <cstdint> + +#include <google/protobuf/stubs/common.h> +#include <google/protobuf/stubs/strutil.h> + +// Must be included last. +#include <google/protobuf/port_def.inc> + +namespace google { +namespace protobuf { +namespace util { +namespace converter { + + +class DataPiece; + +// An ObjectWriter is an interface for writing a stream of events +// representing objects and collections. Implementation of this +// interface can be used to write an object stream to an in-memory +// structure, protobufs, JSON, XML, or any other output format +// desired. The ObjectSource interface is typically used as the +// source of an object stream. +// +// See JsonObjectWriter for a sample implementation of ObjectWriter +// and its use. +// +// Derived classes could be thread-unsafe. +// +// TODO(xinb): seems like a prime candidate to apply the RAII paradigm +// and get rid the need to call EndXXX(). +class PROTOBUF_EXPORT ObjectWriter { + public: + virtual ~ObjectWriter() {} + + // Starts an object. If the name is empty, the object will not be named. + virtual ObjectWriter* StartObject(StringPiece name) = 0; + + // Ends an object. + virtual ObjectWriter* EndObject() = 0; + + // Starts a list. If the name is empty, the list will not be named. + virtual ObjectWriter* StartList(StringPiece name) = 0; + + // Ends a list. + virtual ObjectWriter* EndList() = 0; + + // Renders a boolean value. + virtual ObjectWriter* RenderBool(StringPiece name, bool value) = 0; + + // Renders an 32-bit integer value. + virtual ObjectWriter* RenderInt32(StringPiece name, arc_i32 value) = 0; + + // Renders an 32-bit unsigned integer value. + virtual ObjectWriter* RenderUint32(StringPiece name, + arc_ui32 value) = 0; + + // Renders a 64-bit integer value. + virtual ObjectWriter* RenderInt64(StringPiece name, arc_i64 value) = 0; + + // Renders an 64-bit unsigned integer value. + virtual ObjectWriter* RenderUint64(StringPiece name, + arc_ui64 value) = 0; + + + // Renders a double value. + virtual ObjectWriter* RenderDouble(StringPiece name, double value) = 0; + // Renders a float value. + virtual ObjectWriter* RenderFloat(StringPiece name, float value) = 0; + + // Renders a StringPiece value. This is for rendering strings. + virtual ObjectWriter* RenderString(StringPiece name, + StringPiece value) = 0; + + // Renders a bytes value. + virtual ObjectWriter* RenderBytes(StringPiece name, StringPiece value) = 0; + + // Renders a Null value. + virtual ObjectWriter* RenderNull(StringPiece name) = 0; + + + // Renders a DataPiece object to a ObjectWriter. + static void RenderDataPieceTo(const DataPiece& data, StringPiece name, + ObjectWriter* ow); + + + // Indicates whether this ObjectWriter has completed writing the root message, + // usually this means writing of one complete object. Subclasses must override + // this behavior appropriately. + virtual bool done() { return false; } + + void set_use_strict_base64_decoding(bool value) { + use_strict_base64_decoding_ = value; + } + + bool use_strict_base64_decoding() const { + return use_strict_base64_decoding_; + } + + protected: + ObjectWriter() : use_strict_base64_decoding_(true) {} + + private: + // If set to true, we use the stricter version of base64 decoding for byte + // fields by making sure decoded version encodes back to the original string. + bool use_strict_base64_decoding_; + + // Do not add any data members to this class. + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ObjectWriter); +}; + +} // namespace converter +} // namespace util +} // namespace protobuf +} // namespace google + +#include <google/protobuf/port_undef.inc> + +#endif // GOOGLE_PROTOBUF_UTIL_CONVERTER_OBJECT_WRITER_H__ diff --git a/contrib/libs/protobuf_old/src/google/protobuf/util/internal/proto_writer.cc b/contrib/libs/protobuf_old/src/google/protobuf/util/internal/proto_writer.cc new file mode 100644 index 0000000000..c39ff9f0e2 --- /dev/null +++ b/contrib/libs/protobuf_old/src/google/protobuf/util/internal/proto_writer.cc @@ -0,0 +1,825 @@ +// 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 <google/protobuf/util/internal/proto_writer.h> + +#include <cstdint> +#include <functional> +#include <stack> + +#include <google/protobuf/stubs/once.h> +#include <google/protobuf/wire_format_lite.h> +#include <google/protobuf/util/internal/field_mask_utility.h> +#include <google/protobuf/util/internal/object_location_tracker.h> +#include <google/protobuf/util/internal/constants.h> +#include <google/protobuf/util/internal/utility.h> +#include <google/protobuf/stubs/strutil.h> +#include <google/protobuf/stubs/statusor.h> +#include <google/protobuf/stubs/time.h> +#include <google/protobuf/stubs/map_util.h> + + +#include <google/protobuf/port_def.inc> + +namespace google { +namespace protobuf { +namespace util { +namespace converter { + +using io::CodedOutputStream; +using ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite; + +ProtoWriter::ProtoWriter(TypeResolver* type_resolver, + const google::protobuf::Type& type, + strings::ByteSink* output, ErrorListener* listener) + : master_type_(type), + typeinfo_(TypeInfo::NewTypeInfo(type_resolver)), + own_typeinfo_(true), + done_(false), + ignore_unknown_fields_(false), + ignore_unknown_enum_values_(false), + use_lower_camel_for_enums_(false), + case_insensitive_enum_parsing_(true), + use_json_name_in_missing_fields_(false), + element_(nullptr), + size_insert_(), + output_(output), + buffer_(), + adapter_(&buffer_), + stream_(new CodedOutputStream(&adapter_)), + listener_(listener), + invalid_depth_(0), + tracker_(new ObjectLocationTracker()) {} + +ProtoWriter::ProtoWriter(const TypeInfo* typeinfo, + const google::protobuf::Type& type, + strings::ByteSink* output, ErrorListener* listener) + : master_type_(type), + typeinfo_(typeinfo), + own_typeinfo_(false), + done_(false), + ignore_unknown_fields_(false), + ignore_unknown_enum_values_(false), + use_lower_camel_for_enums_(false), + case_insensitive_enum_parsing_(true), + use_json_name_in_missing_fields_(false), + element_(nullptr), + size_insert_(), + output_(output), + buffer_(), + adapter_(&buffer_), + stream_(new CodedOutputStream(&adapter_)), + listener_(listener), + invalid_depth_(0), + tracker_(new ObjectLocationTracker()) {} + +ProtoWriter::~ProtoWriter() { + if (own_typeinfo_) { + delete typeinfo_; + } + if (element_ == nullptr) return; + // Cleanup explicitly in order to avoid destructor stack overflow when input + // is deeply nested. + // Cast to BaseElement to avoid doing additional checks (like missing fields) + // during pop(). + std::unique_ptr<BaseElement> element( + static_cast<BaseElement*>(element_.get())->pop<BaseElement>()); + while (element != nullptr) { + element.reset(element->pop<BaseElement>()); + } +} + +namespace { + +// Writes an INT32 field, including tag to the stream. +inline util::Status WriteInt32(int field_number, const DataPiece& data, + CodedOutputStream* stream) { + util::StatusOr<arc_i32> i32 = data.ToInt32(); + if (i32.ok()) { + WireFormatLite::WriteInt32(field_number, i32.value(), stream); + } + return i32.status(); +} + +// writes an SFIXED32 field, including tag, to the stream. +inline util::Status WriteSFixed32(int field_number, const DataPiece& data, + CodedOutputStream* stream) { + util::StatusOr<arc_i32> i32 = data.ToInt32(); + if (i32.ok()) { + WireFormatLite::WriteSFixed32(field_number, i32.value(), stream); + } + return i32.status(); +} + +// Writes an SINT32 field, including tag, to the stream. +inline util::Status WriteSInt32(int field_number, const DataPiece& data, + CodedOutputStream* stream) { + util::StatusOr<arc_i32> i32 = data.ToInt32(); + if (i32.ok()) { + WireFormatLite::WriteSInt32(field_number, i32.value(), stream); + } + return i32.status(); +} + +// Writes a FIXED32 field, including tag, to the stream. +inline util::Status WriteFixed32(int field_number, const DataPiece& data, + CodedOutputStream* stream) { + util::StatusOr<arc_ui32> u32 = data.ToUint32(); + if (u32.ok()) { + WireFormatLite::WriteFixed32(field_number, u32.value(), stream); + } + return u32.status(); +} + +// Writes a UINT32 field, including tag, to the stream. +inline util::Status WriteUInt32(int field_number, const DataPiece& data, + CodedOutputStream* stream) { + util::StatusOr<arc_ui32> u32 = data.ToUint32(); + if (u32.ok()) { + WireFormatLite::WriteUInt32(field_number, u32.value(), stream); + } + return u32.status(); +} + +// Writes an INT64 field, including tag, to the stream. +inline util::Status WriteInt64(int field_number, const DataPiece& data, + CodedOutputStream* stream) { + util::StatusOr<arc_i64> i64 = data.ToInt64(); + if (i64.ok()) { + WireFormatLite::WriteInt64(field_number, i64.value(), stream); + } + return i64.status(); +} + +// Writes an SFIXED64 field, including tag, to the stream. +inline util::Status WriteSFixed64(int field_number, const DataPiece& data, + CodedOutputStream* stream) { + util::StatusOr<arc_i64> i64 = data.ToInt64(); + if (i64.ok()) { + WireFormatLite::WriteSFixed64(field_number, i64.value(), stream); + } + return i64.status(); +} + +// Writes an SINT64 field, including tag, to the stream. +inline util::Status WriteSInt64(int field_number, const DataPiece& data, + CodedOutputStream* stream) { + util::StatusOr<arc_i64> i64 = data.ToInt64(); + if (i64.ok()) { + WireFormatLite::WriteSInt64(field_number, i64.value(), stream); + } + return i64.status(); +} + +// Writes a FIXED64 field, including tag, to the stream. +inline util::Status WriteFixed64(int field_number, const DataPiece& data, + CodedOutputStream* stream) { + util::StatusOr<arc_ui64> u64 = data.ToUint64(); + if (u64.ok()) { + WireFormatLite::WriteFixed64(field_number, u64.value(), stream); + } + return u64.status(); +} + +// Writes a UINT64 field, including tag, to the stream. +inline util::Status WriteUInt64(int field_number, const DataPiece& data, + CodedOutputStream* stream) { + util::StatusOr<arc_ui64> u64 = data.ToUint64(); + if (u64.ok()) { + WireFormatLite::WriteUInt64(field_number, u64.value(), stream); + } + return u64.status(); +} + +// Writes a DOUBLE field, including tag, to the stream. +inline util::Status WriteDouble(int field_number, const DataPiece& data, + CodedOutputStream* stream) { + util::StatusOr<double> d = data.ToDouble(); + if (d.ok()) { + WireFormatLite::WriteDouble(field_number, d.value(), stream); + } + return d.status(); +} + +// Writes a FLOAT field, including tag, to the stream. +inline util::Status WriteFloat(int field_number, const DataPiece& data, + CodedOutputStream* stream) { + util::StatusOr<float> f = data.ToFloat(); + if (f.ok()) { + WireFormatLite::WriteFloat(field_number, f.value(), stream); + } + return f.status(); +} + +// Writes a BOOL field, including tag, to the stream. +inline util::Status WriteBool(int field_number, const DataPiece& data, + CodedOutputStream* stream) { + util::StatusOr<bool> b = data.ToBool(); + if (b.ok()) { + WireFormatLite::WriteBool(field_number, b.value(), stream); + } + return b.status(); +} + +// Writes a BYTES field, including tag, to the stream. +inline util::Status WriteBytes(int field_number, const DataPiece& data, + CodedOutputStream* stream) { + util::StatusOr<TProtoStringType> c = data.ToBytes(); + if (c.ok()) { + WireFormatLite::WriteBytes(field_number, c.value(), stream); + } + return c.status(); +} + +// Writes a STRING field, including tag, to the stream. +inline util::Status WriteString(int field_number, const DataPiece& data, + CodedOutputStream* stream) { + util::StatusOr<TProtoStringType> s = data.ToString(); + if (s.ok()) { + WireFormatLite::WriteString(field_number, s.value(), stream); + } + return s.status(); +} + +// Given a google::protobuf::Type, returns the set of all required fields. +std::set<const google::protobuf::Field*> GetRequiredFields( + const google::protobuf::Type& type) { + std::set<const google::protobuf::Field*> required; + for (int i = 0; i < type.fields_size(); i++) { + const google::protobuf::Field& field = type.fields(i); + if (field.cardinality() == google::protobuf::Field::CARDINALITY_REQUIRED) { + required.insert(&field); + } + } + return required; +} + +} // namespace + +ProtoWriter::ProtoElement::ProtoElement(const TypeInfo* typeinfo, + const google::protobuf::Type& type, + ProtoWriter* enclosing) + : BaseElement(nullptr), + ow_(enclosing), + parent_field_(nullptr), + typeinfo_(typeinfo), + proto3_(type.syntax() == google::protobuf::SYNTAX_PROTO3), + type_(type), + size_index_(-1), + array_index_(-1), + // oneof_indices_ values are 1-indexed (0 means not present). + oneof_indices_(type.oneofs_size() + 1) { + if (!proto3_) { + required_fields_ = GetRequiredFields(type_); + } +} + +ProtoWriter::ProtoElement::ProtoElement(ProtoWriter::ProtoElement* parent, + const google::protobuf::Field* field, + const google::protobuf::Type& type, + bool is_list) + : BaseElement(parent), + ow_(this->parent()->ow_), + parent_field_(field), + typeinfo_(this->parent()->typeinfo_), + proto3_(type.syntax() == google::protobuf::SYNTAX_PROTO3), + type_(type), + size_index_(!is_list && + field->kind() == google::protobuf::Field::TYPE_MESSAGE + ? ow_->size_insert_.size() + : -1), + array_index_(is_list ? 0 : -1), + // oneof_indices_ values are 1-indexed (0 means not present). + oneof_indices_(type_.oneofs_size() + 1) { + if (!is_list) { + if (ow_->IsRepeated(*field)) { + // Update array_index_ if it is an explicit list. + if (this->parent()->array_index_ >= 0) this->parent()->array_index_++; + } else if (!proto3_) { + // For required fields tracking. + this->parent()->RegisterField(field); + } + + if (field->kind() == google::protobuf::Field::TYPE_MESSAGE) { + if (!proto3_) { + required_fields_ = GetRequiredFields(type_); + } + int start_pos = ow_->stream_->ByteCount(); + // length of serialized message is the final buffer position minus + // starting buffer position, plus length adjustments for size fields + // of any nested messages. We start with -start_pos here, so we only + // need to add the final buffer position to it at the end. + SizeInfo info = {start_pos, -start_pos}; + ow_->size_insert_.push_back(info); + } + } +} + +ProtoWriter::ProtoElement* ProtoWriter::ProtoElement::pop() { + if (!proto3_) { + // Calls the registered error listener for any required field(s) not yet + // seen. + for (std::set<const google::protobuf::Field*>::iterator it = + required_fields_.begin(); + it != required_fields_.end(); ++it) { + ow_->MissingField(ow_->use_json_name_in_missing_fields_ + ? (*it)->json_name() + : (*it)->name()); + } + } + // Computes the total number of proto bytes used by a message, also adjusts + // the size of all parent messages by the length of this size field. + // If size_index_ < 0, this is not a message, so no size field is added. + if (size_index_ >= 0) { + // Add the final buffer position to compute the total length of this + // serialized message. The stored value (before this addition) already + // contains the total length of the size fields of all nested messages + // minus the initial buffer position. + ow_->size_insert_[size_index_].size += ow_->stream_->ByteCount(); + // Calculate the length required to serialize the size field of the + // message, and propagate this additional size information upward to + // all enclosing messages. + int size = ow_->size_insert_[size_index_].size; + int length = CodedOutputStream::VarintSize32(size); + for (ProtoElement* e = parent(); e != nullptr; e = e->parent()) { + // Only nested messages have size field, lists do not have size field. + if (e->size_index_ >= 0) { + ow_->size_insert_[e->size_index_].size += length; + } + } + } + return BaseElement::pop<ProtoElement>(); +} + +void ProtoWriter::ProtoElement::RegisterField( + const google::protobuf::Field* field) { + if (!required_fields_.empty() && + field->cardinality() == google::protobuf::Field::CARDINALITY_REQUIRED) { + required_fields_.erase(field); + } +} + +TProtoStringType ProtoWriter::ProtoElement::ToString() const { + TProtoStringType loc = ""; + + // first populate a stack with the nodes since we need to process them + // from root to leaf when generating the string location + const ProtoWriter::ProtoElement* now = this; + std::stack<const ProtoWriter::ProtoElement*> element_stack; + while (now->parent() != nullptr) { + element_stack.push(now); + now = now->parent(); + } + + // now pop each node from the stack and append to the location string + while (!element_stack.empty()) { + now = element_stack.top(); + element_stack.pop(); + + if (!ow_->IsRepeated(*(now->parent_field_)) || + now->parent()->parent_field_ != now->parent_field_) { + TProtoStringType name = now->parent_field_->name(); + int i = 0; + while (i < name.size() && + (ascii_isalnum(name[i]) || name[i] == '_')) + ++i; + if (i > 0 && i == name.size()) { // safe field name + if (loc.empty()) { + loc = name; + } else { + StrAppend(&loc, ".", name); + } + } else { + StrAppend(&loc, "[\"", CEscape(name), "\"]"); + } + } + + int array_index_now = now->array_index_; + if (ow_->IsRepeated(*(now->parent_field_)) && array_index_now > 0) { + StrAppend(&loc, "[", array_index_now - 1, "]"); + } + } + + return loc; +} + +bool ProtoWriter::ProtoElement::IsOneofIndexTaken(arc_i32 index) { + return oneof_indices_[index]; +} + +void ProtoWriter::ProtoElement::TakeOneofIndex(arc_i32 index) { + oneof_indices_[index] = true; +} + +void ProtoWriter::InvalidName(StringPiece unknown_name, + StringPiece message) { + listener_->InvalidName(location(), unknown_name, message); +} + +void ProtoWriter::InvalidValue(StringPiece type_name, + StringPiece value) { + listener_->InvalidValue(location(), type_name, value); +} + +void ProtoWriter::MissingField(StringPiece missing_name) { + listener_->MissingField(location(), missing_name); +} + +ProtoWriter* ProtoWriter::StartObject( + StringPiece name) { + // Starting the root message. Create the root ProtoElement and return. + if (element_ == nullptr) { + if (!name.empty()) { + InvalidName(name, "Root element should not be named."); + } + element_.reset(new ProtoElement(typeinfo_, master_type_, this)); + return this; + } + + const google::protobuf::Field* field = BeginNamed(name, false); + + if (field == nullptr) return this; + + // Check to see if this field is a oneof and that no oneof in that group has + // already been set. + if (!ValidOneof(*field, name)) { + ++invalid_depth_; + return this; + } + + const google::protobuf::Type* type = LookupType(field); + if (type == nullptr) { + ++invalid_depth_; + InvalidName(name, StrCat("Missing descriptor for field: ", + field->type_url())); + return this; + } + + return StartObjectField(*field, *type); +} + + +ProtoWriter* ProtoWriter::EndObject() { + if (invalid_depth_ > 0) { + --invalid_depth_; + return this; + } + + if (element_ != nullptr) { + element_.reset(element_->pop()); + } + + + // If ending the root element, + // then serialize the full message with calculated sizes. + if (element_ == nullptr) { + WriteRootMessage(); + } + return this; +} + +ProtoWriter* ProtoWriter::StartList( + StringPiece name) { + + const google::protobuf::Field* field = BeginNamed(name, true); + + if (field == nullptr) return this; + + if (!ValidOneof(*field, name)) { + ++invalid_depth_; + return this; + } + + const google::protobuf::Type* type = LookupType(field); + if (type == nullptr) { + ++invalid_depth_; + InvalidName(name, StrCat("Missing descriptor for field: ", + field->type_url())); + return this; + } + + return StartListField(*field, *type); +} + + +ProtoWriter* ProtoWriter::EndList() { + if (invalid_depth_ > 0) { + --invalid_depth_; + } else if (element_ != nullptr) { + element_.reset(element_->pop()); + } + return this; +} + +ProtoWriter* ProtoWriter::RenderDataPiece( + StringPiece name, const DataPiece& data) { + util::Status status; + if (invalid_depth_ > 0) return this; + + const google::protobuf::Field* field = Lookup(name); + + if (field == nullptr) return this; + + if (!ValidOneof(*field, name)) return this; + + const google::protobuf::Type* type = LookupType(field); + if (type == nullptr) { + InvalidName(name, StrCat("Missing descriptor for field: ", + field->type_url())); + return this; + } + + return RenderPrimitiveField(*field, *type, data); +} + +bool ProtoWriter::ValidOneof(const google::protobuf::Field& field, + StringPiece unnormalized_name) { + if (element_ == nullptr) return true; + + if (field.oneof_index() > 0) { + if (element_->IsOneofIndexTaken(field.oneof_index())) { + InvalidValue( + "oneof", + StrCat( + "oneof field '", element_->type().oneofs(field.oneof_index() - 1), + "' is already set. Cannot set '", unnormalized_name, "'")); + return false; + } + element_->TakeOneofIndex(field.oneof_index()); + } + return true; +} + +bool ProtoWriter::IsRepeated(const google::protobuf::Field& field) { + return field.cardinality() == google::protobuf::Field::CARDINALITY_REPEATED; +} + +ProtoWriter* ProtoWriter::StartObjectField(const google::protobuf::Field& field, + const google::protobuf::Type& type) { + WriteTag(field); + element_.reset(new ProtoElement(element_.release(), &field, type, false)); + return this; +} + +ProtoWriter* ProtoWriter::StartListField(const google::protobuf::Field& field, + const google::protobuf::Type& type) { + element_.reset(new ProtoElement(element_.release(), &field, type, true)); + return this; +} + +util::Status ProtoWriter::WriteEnum(int field_number, const DataPiece& data, + const google::protobuf::Enum* enum_type, + CodedOutputStream* stream, + bool use_lower_camel_for_enums, + bool case_insensitive_enum_parsing, + bool ignore_unknown_values) { + bool is_unknown_enum_value = false; + util::StatusOr<int> e = data.ToEnum( + enum_type, use_lower_camel_for_enums, case_insensitive_enum_parsing, + ignore_unknown_values, &is_unknown_enum_value); + if (e.ok() && !is_unknown_enum_value) { + WireFormatLite::WriteEnum(field_number, e.value(), stream); + } + return e.status(); +} + +ProtoWriter* ProtoWriter::RenderPrimitiveField( + const google::protobuf::Field& field, const google::protobuf::Type& type, + const DataPiece& data) { + util::Status status; + + // Pushing a ProtoElement and then pop it off at the end for 2 purposes: + // error location reporting and required field accounting. + // + // For proto3, since there is no required field tracking, we only need to + // push ProtoElement for error cases. + if (!element_->proto3()) { + element_.reset(new ProtoElement(element_.release(), &field, type, false)); + } + + switch (field.kind()) { + case google::protobuf::Field::TYPE_INT32: { + status = WriteInt32(field.number(), data, stream_.get()); + break; + } + case google::protobuf::Field::TYPE_SFIXED32: { + status = WriteSFixed32(field.number(), data, stream_.get()); + break; + } + case google::protobuf::Field::TYPE_SINT32: { + status = WriteSInt32(field.number(), data, stream_.get()); + break; + } + case google::protobuf::Field::TYPE_FIXED32: { + status = WriteFixed32(field.number(), data, stream_.get()); + break; + } + case google::protobuf::Field::TYPE_UINT32: { + status = WriteUInt32(field.number(), data, stream_.get()); + break; + } + case google::protobuf::Field::TYPE_INT64: { + status = WriteInt64(field.number(), data, stream_.get()); + break; + } + case google::protobuf::Field::TYPE_SFIXED64: { + status = WriteSFixed64(field.number(), data, stream_.get()); + break; + } + case google::protobuf::Field::TYPE_SINT64: { + status = WriteSInt64(field.number(), data, stream_.get()); + break; + } + case google::protobuf::Field::TYPE_FIXED64: { + status = WriteFixed64(field.number(), data, stream_.get()); + break; + } + case google::protobuf::Field::TYPE_UINT64: { + status = WriteUInt64(field.number(), data, stream_.get()); + break; + } + case google::protobuf::Field::TYPE_DOUBLE: { + status = WriteDouble(field.number(), data, stream_.get()); + break; + } + case google::protobuf::Field::TYPE_FLOAT: { + status = WriteFloat(field.number(), data, stream_.get()); + break; + } + case google::protobuf::Field::TYPE_BOOL: { + status = WriteBool(field.number(), data, stream_.get()); + break; + } + case google::protobuf::Field::TYPE_BYTES: { + status = WriteBytes(field.number(), data, stream_.get()); + break; + } + case google::protobuf::Field::TYPE_STRING: { + status = WriteString(field.number(), data, stream_.get()); + break; + } + case google::protobuf::Field::TYPE_ENUM: { + status = WriteEnum( + field.number(), data, typeinfo_->GetEnumByTypeUrl(field.type_url()), + stream_.get(), use_lower_camel_for_enums_, + case_insensitive_enum_parsing_, ignore_unknown_enum_values_); + break; + } + default: // TYPE_GROUP, TYPE_MESSAGE, TYPE_UNKNOWN. + status = util::InvalidArgumentError(data.ValueAsStringOrDefault("")); + } + + if (!status.ok()) { + // Push a ProtoElement for location reporting purposes. + if (element_->proto3()) { + element_.reset(new ProtoElement(element_.release(), &field, type, false)); + } + InvalidValue(field.type_url().empty() + ? google::protobuf::Field_Kind_Name(field.kind()) + : field.type_url(), + status.message()); + element_.reset(element()->pop()); + return this; + } + + if (!element_->proto3()) element_.reset(element()->pop()); + + return this; +} + +const google::protobuf::Field* ProtoWriter::BeginNamed(StringPiece name, + bool is_list) { + if (invalid_depth_ > 0) { + ++invalid_depth_; + return nullptr; + } + const google::protobuf::Field* field = Lookup(name); + if (field == nullptr) { + ++invalid_depth_; + // InvalidName() already called in Lookup(). + return nullptr; + } + if (is_list && !IsRepeated(*field)) { + ++invalid_depth_; + InvalidName(name, "Proto field is not repeating, cannot start list."); + return nullptr; + } + return field; +} + +const google::protobuf::Field* ProtoWriter::Lookup( + StringPiece unnormalized_name) { + ProtoElement* e = element(); + if (e == nullptr) { + InvalidName(unnormalized_name, "Root element must be a message."); + return nullptr; + } + if (unnormalized_name.empty()) { + // Objects in repeated field inherit the same field descriptor. + if (e->parent_field() == nullptr) { + InvalidName(unnormalized_name, "Proto fields must have a name."); + } else if (!IsRepeated(*e->parent_field())) { + InvalidName(unnormalized_name, "Proto fields must have a name."); + return nullptr; + } + return e->parent_field(); + } + const google::protobuf::Field* field = + typeinfo_->FindField(&e->type(), unnormalized_name); + if (field == nullptr && !ignore_unknown_fields_) { + InvalidName(unnormalized_name, "Cannot find field."); + } + return field; +} + +const google::protobuf::Type* ProtoWriter::LookupType( + const google::protobuf::Field* field) { + return ((field->kind() == google::protobuf::Field::TYPE_MESSAGE || + field->kind() == google::protobuf::Field::TYPE_GROUP) + ? typeinfo_->GetTypeByTypeUrl(field->type_url()) + : &element_->type()); +} + +void ProtoWriter::WriteRootMessage() { + GOOGLE_DCHECK(!done_); + int curr_pos = 0; + // Calls the destructor of CodedOutputStream to remove any uninitialized + // memory from the Cord before we read it. + stream_.reset(nullptr); + const void* data; + int length; + io::ArrayInputStream input_stream(buffer_.data(), buffer_.size()); + while (input_stream.Next(&data, &length)) { + if (length == 0) continue; + int num_bytes = length; + // Write up to where we need to insert the size field. + // The number of bytes we may write is the smaller of: + // - the current fragment size + // - the distance to the next position where a size field needs to be + // inserted. + if (!size_insert_.empty() && + size_insert_.front().pos - curr_pos < num_bytes) { + num_bytes = size_insert_.front().pos - curr_pos; + } + output_->Append(static_cast<const char*>(data), num_bytes); + if (num_bytes < length) { + input_stream.BackUp(length - num_bytes); + } + curr_pos += num_bytes; + // Insert the size field. + // size_insert_.front(): the next <index, size> pair to be written. + // size_insert_.front().pos: position of the size field. + // size_insert_.front().size: the size (integer) to be inserted. + if (!size_insert_.empty() && curr_pos == size_insert_.front().pos) { + // Varint32 occupies at most 10 bytes. + uint8_t insert_buffer[10]; + uint8_t* insert_buffer_pos = CodedOutputStream::WriteVarint32ToArray( + size_insert_.front().size, insert_buffer); + output_->Append(reinterpret_cast<const char*>(insert_buffer), + insert_buffer_pos - insert_buffer); + size_insert_.pop_front(); + } + } + output_->Flush(); + stream_.reset(new CodedOutputStream(&adapter_)); + done_ = true; +} + +void ProtoWriter::WriteTag(const google::protobuf::Field& field) { + WireFormatLite::WireType wire_type = WireFormatLite::WireTypeForFieldType( + static_cast<WireFormatLite::FieldType>(field.kind())); + stream_->WriteTag(WireFormatLite::MakeTag(field.number(), wire_type)); +} + + +} // namespace converter +} // namespace util +} // namespace protobuf +} // namespace google diff --git a/contrib/libs/protobuf_old/src/google/protobuf/util/internal/proto_writer.h b/contrib/libs/protobuf_old/src/google/protobuf/util/internal/proto_writer.h new file mode 100644 index 0000000000..6ecabb428b --- /dev/null +++ b/contrib/libs/protobuf_old/src/google/protobuf/util/internal/proto_writer.h @@ -0,0 +1,388 @@ +// 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_UTIL_CONVERTER_PROTO_WRITER_H__ +#define GOOGLE_PROTOBUF_UTIL_CONVERTER_PROTO_WRITER_H__ + +#include <cstdint> +#include <deque> +#include <string> +#include <vector> + +#include <google/protobuf/stubs/common.h> +#include <google/protobuf/type.pb.h> +#include <google/protobuf/io/coded_stream.h> +#include <google/protobuf/io/zero_copy_stream_impl.h> +#include <google/protobuf/descriptor.h> +#include <google/protobuf/util/internal/type_info.h> +#include <google/protobuf/util/internal/datapiece.h> +#include <google/protobuf/util/internal/error_listener.h> +#include <google/protobuf/util/internal/structured_objectwriter.h> +#include <google/protobuf/util/type_resolver.h> +#include <google/protobuf/stubs/bytestream.h> +#include <google/protobuf/stubs/status.h> +#include <google/protobuf/stubs/hash.h> +#include <google/protobuf/stubs/status.h> + +// Must be included last. +#include <google/protobuf/port_def.inc> + +namespace google { +namespace protobuf { +namespace util { +namespace converter { + + +class ObjectLocationTracker; + +// An ObjectWriter that can write protobuf bytes directly from writer events. +// This class does not support special types like Struct or Map. However, since +// this class supports raw protobuf, it can be used to provide support for +// special types by inheriting from it or by wrapping it. +// +// It also supports streaming. +class PROTOBUF_EXPORT ProtoWriter : public StructuredObjectWriter { + public: +// Constructor. Does not take ownership of any parameter passed in. + ProtoWriter(TypeResolver* type_resolver, const google::protobuf::Type& type, + strings::ByteSink* output, ErrorListener* listener); + ~ProtoWriter() override; + + // ObjectWriter methods. + ProtoWriter* StartObject(StringPiece name) override; + ProtoWriter* EndObject() override; + ProtoWriter* StartList(StringPiece name) override; + ProtoWriter* EndList() override; + ProtoWriter* RenderBool(StringPiece name, bool value) override { + return RenderDataPiece(name, DataPiece(value)); + } + ProtoWriter* RenderInt32(StringPiece name, arc_i32 value) override { + return RenderDataPiece(name, DataPiece(value)); + } + ProtoWriter* RenderUint32(StringPiece name, arc_ui32 value) override { + return RenderDataPiece(name, DataPiece(value)); + } + ProtoWriter* RenderInt64(StringPiece name, arc_i64 value) override { + return RenderDataPiece(name, DataPiece(value)); + } + ProtoWriter* RenderUint64(StringPiece name, arc_ui64 value) override { + return RenderDataPiece(name, DataPiece(value)); + } + ProtoWriter* RenderDouble(StringPiece name, double value) override { + return RenderDataPiece(name, DataPiece(value)); + } + ProtoWriter* RenderFloat(StringPiece name, float value) override { + return RenderDataPiece(name, DataPiece(value)); + } + ProtoWriter* RenderString(StringPiece name, + StringPiece value) override { + return RenderDataPiece(name, + DataPiece(value, use_strict_base64_decoding())); + } + + ProtoWriter* RenderBytes(StringPiece name, StringPiece value) override { + return RenderDataPiece( + name, DataPiece(value, false, use_strict_base64_decoding())); + } + + ProtoWriter* RenderNull(StringPiece name) override { + return RenderDataPiece(name, DataPiece::NullData()); + } + + + // Renders a DataPiece 'value' into a field whose wire type is determined + // from the given field 'name'. + virtual ProtoWriter* RenderDataPiece(StringPiece name, + const DataPiece& data); + + + // Returns the location tracker to use for tracking locations for errors. + const LocationTrackerInterface& location() { + return element_ != nullptr ? *element_ : *tracker_; + } + + // When true, we finished writing to output a complete message. + bool done() override { return done_; } + + // Returns the proto stream object. + io::CodedOutputStream* stream() { return stream_.get(); } + + // Getters and mutators of invalid_depth_. + void IncrementInvalidDepth() { ++invalid_depth_; } + void DecrementInvalidDepth() { --invalid_depth_; } + int invalid_depth() { return invalid_depth_; } + + ErrorListener* listener() { return listener_; } + + const TypeInfo* typeinfo() { return typeinfo_; } + + void set_ignore_unknown_fields(bool ignore_unknown_fields) { + ignore_unknown_fields_ = ignore_unknown_fields; + } + + bool ignore_unknown_fields() { return ignore_unknown_fields_; } + + void set_ignore_unknown_enum_values(bool ignore_unknown_enum_values) { + ignore_unknown_enum_values_ = ignore_unknown_enum_values; + } + + void set_use_lower_camel_for_enums(bool use_lower_camel_for_enums) { + use_lower_camel_for_enums_ = use_lower_camel_for_enums; + } + + void set_case_insensitive_enum_parsing(bool case_insensitive_enum_parsing) { + case_insensitive_enum_parsing_ = case_insensitive_enum_parsing; + } + + void set_use_json_name_in_missing_fields( + bool use_json_name_in_missing_fields) { + use_json_name_in_missing_fields_ = use_json_name_in_missing_fields; + } + + protected: + class PROTOBUF_EXPORT ProtoElement : public BaseElement, + public LocationTrackerInterface { + public: + // Constructor for the root element. No parent nor field. + ProtoElement(const TypeInfo* typeinfo, const google::protobuf::Type& type, + ProtoWriter* enclosing); + + // Constructor for a field of an element. + ProtoElement(ProtoElement* parent, const google::protobuf::Field* field, + const google::protobuf::Type& type, bool is_list); + + ~ProtoElement() override {} + + // Called just before the destructor for clean up: + // - reports any missing required fields + // - computes the space needed by the size field, and augment the + // length of all parent messages by this additional space. + // - releases and returns the parent pointer. + ProtoElement* pop(); + + // Accessors + // parent_field() may be nullptr if we are at root. + const google::protobuf::Field* parent_field() const { + return parent_field_; + } + const google::protobuf::Type& type() const { return type_; } + + // Registers field for accounting required fields. + void RegisterField(const google::protobuf::Field* field); + + // To report location on error messages. + TProtoStringType ToString() const override; + + ProtoElement* parent() const override { + return static_cast<ProtoElement*>(BaseElement::parent()); + } + + // Returns true if the index is already taken by a preceding oneof input. + bool IsOneofIndexTaken(arc_i32 index); + + // Marks the oneof 'index' as taken. Future inputs to this oneof will + // generate an error. + void TakeOneofIndex(arc_i32 index); + + bool proto3() { return proto3_; } + + private: + // Used for access to variables of the enclosing instance of + // ProtoWriter. + ProtoWriter* ow_; + + // Describes the element as a field in the parent message. + // parent_field_ is nullptr if and only if this element is the root element. + const google::protobuf::Field* parent_field_; + + // TypeInfo to lookup types. + const TypeInfo* typeinfo_; + + // Whether the type_ is proto3 or not. + bool proto3_; + + // Additional variables if this element is a message: + // (Root element is always a message). + // type_ : the type of this element. + // required_fields_ : set of required fields. + // size_index_ : index into ProtoWriter::size_insert_ + // for later insertion of serialized message length. + const google::protobuf::Type& type_; + std::set<const google::protobuf::Field*> required_fields_; + const int size_index_; + + // Tracks position in repeated fields, needed for LocationTrackerInterface. + int array_index_; + + // Set of oneof indices already seen for the type_. Used to validate + // incoming messages so no more than one oneof is set. + std::vector<bool> oneof_indices_; + + GOOGLE_DISALLOW_IMPLICIT_CONSTRUCTORS(ProtoElement); + }; + + // Container for inserting 'size' information at the 'pos' position. + struct SizeInfo { + const int pos; + int size; + }; + + ProtoWriter(const TypeInfo* typeinfo, const google::protobuf::Type& type, + strings::ByteSink* output, ErrorListener* listener); + + ProtoElement* element() override { return element_.get(); } + + // Helper methods for calling ErrorListener. See error_listener.h. + void InvalidName(StringPiece unknown_name, StringPiece message); + void InvalidValue(StringPiece type_name, StringPiece value); + void MissingField(StringPiece missing_name); + + // Common code for BeginObject() and BeginList() that does invalid_depth_ + // bookkeeping associated with name lookup. + const google::protobuf::Field* BeginNamed(StringPiece name, + bool is_list); + + // Lookup the field in the current element. Looks in the base descriptor + // and in any extension. This will report an error if the field cannot be + // found when ignore_unknown_names_ is false or if multiple matching + // extensions are found. + const google::protobuf::Field* Lookup(StringPiece name); + + // Lookup the field type in the type descriptor. Returns nullptr if the type + // is not known. + const google::protobuf::Type* LookupType( + const google::protobuf::Field* field); + + // Write serialized output to the final output ByteSink, inserting all + // the size information for nested messages that are missing from the + // intermediate Cord buffer. + void WriteRootMessage(); + + // Helper method to write proto tags based on the given field. + void WriteTag(const google::protobuf::Field& field); + + + // Returns true if the field for type_ can be set as a oneof. If field is not + // a oneof type, this function does nothing and returns true. + // If another field for this oneof is already set, this function returns + // false. It also calls the appropriate error callback. + // unnormalized_name is used for error string. + bool ValidOneof(const google::protobuf::Field& field, + StringPiece unnormalized_name); + + // Returns true if the field is repeated. + bool IsRepeated(const google::protobuf::Field& field); + + // Starts an object given the field and the enclosing type. + ProtoWriter* StartObjectField(const google::protobuf::Field& field, + const google::protobuf::Type& type); + + // Starts a list given the field and the enclosing type. + ProtoWriter* StartListField(const google::protobuf::Field& field, + const google::protobuf::Type& type); + + // Renders a primitive field given the field and the enclosing type. + ProtoWriter* RenderPrimitiveField(const google::protobuf::Field& field, + const google::protobuf::Type& type, + const DataPiece& data); + + private: + // Writes an ENUM field, including tag, to the stream. + static util::Status WriteEnum(int field_number, const DataPiece& data, + const google::protobuf::Enum* enum_type, + io::CodedOutputStream* stream, + bool use_lower_camel_for_enums, + bool case_insensitive_enum_parsing, + bool ignore_unknown_values); + + // Variables for describing the structure of the input tree: + // master_type_: descriptor for the whole protobuf message. + // typeinfo_ : the TypeInfo object to lookup types. + const google::protobuf::Type& master_type_; + const TypeInfo* typeinfo_; + // Whether we own the typeinfo_ object. + bool own_typeinfo_; + + // Indicates whether we finished writing root message completely. + bool done_; + + // If true, don't report unknown field names to the listener. + bool ignore_unknown_fields_; + + // If true, don't report unknown enum values to the listener. + bool ignore_unknown_enum_values_; + + // If true, check if enum name in camel case or without underscore matches the + // field name. + bool use_lower_camel_for_enums_; + + // If true, check if enum name in UPPER_CASE matches the field name. + bool case_insensitive_enum_parsing_; + + // If true, use the json name in missing fields errors. + bool use_json_name_in_missing_fields_; + + // Variable for internal state processing: + // element_ : the current element. + // size_insert_: sizes of nested messages. + // pos - position to insert the size field. + // size - size value to be inserted. + std::unique_ptr<ProtoElement> element_; + std::deque<SizeInfo> size_insert_; + + // Variables for output generation: + // output_ : pointer to an external ByteSink for final user-visible output. + // buffer_ : buffer holding partial message before being ready for output_. + // adapter_ : internal adapter between CodedOutputStream and buffer_. + // stream_ : wrapper for writing tags and other encodings in wire format. + strings::ByteSink* output_; + TProtoStringType buffer_; + io::StringOutputStream adapter_; + std::unique_ptr<io::CodedOutputStream> stream_; + + // Variables for error tracking and reporting: + // listener_ : a place to report any errors found. + // invalid_depth_: number of enclosing invalid nested messages. + // tracker_ : the root location tracker interface. + ErrorListener* listener_; + int invalid_depth_; + std::unique_ptr<LocationTrackerInterface> tracker_; + + GOOGLE_DISALLOW_IMPLICIT_CONSTRUCTORS(ProtoWriter); +}; + +} // namespace converter +} // namespace util +} // namespace protobuf +} // namespace google + +#include <google/protobuf/port_undef.inc> + +#endif // GOOGLE_PROTOBUF_UTIL_CONVERTER_PROTO_WRITER_H__ diff --git a/contrib/libs/protobuf_old/src/google/protobuf/util/internal/protostream_objectsource.cc b/contrib/libs/protobuf_old/src/google/protobuf/util/internal/protostream_objectsource.cc new file mode 100644 index 0000000000..8a04f7927f --- /dev/null +++ b/contrib/libs/protobuf_old/src/google/protobuf/util/internal/protostream_objectsource.cc @@ -0,0 +1,1112 @@ +// 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 <google/protobuf/util/internal/protostream_objectsource.h> + +#include <cstdint> +#include <unordered_map> +#include <utility> + +#include <google/protobuf/stubs/logging.h> +#include <google/protobuf/stubs/common.h> +#include <google/protobuf/stubs/stringprintf.h> +#include <google/protobuf/io/coded_stream.h> +#include <google/protobuf/io/zero_copy_stream_impl.h> +#include <google/protobuf/descriptor.h> +#include <google/protobuf/stubs/once.h> +#include <google/protobuf/unknown_field_set.h> +#include <google/protobuf/wire_format.h> +#include <google/protobuf/wire_format_lite.h> +#include <google/protobuf/util/internal/field_mask_utility.h> +#include <google/protobuf/util/internal/constants.h> +#include <google/protobuf/util/internal/utility.h> +#include <google/protobuf/stubs/strutil.h> +#include <google/protobuf/stubs/casts.h> +#include <google/protobuf/stubs/status.h> +#include <google/protobuf/stubs/time.h> +#include <google/protobuf/stubs/map_util.h> +#include <google/protobuf/stubs/status_macros.h> + + +#include <google/protobuf/port_def.inc> + +namespace google { +namespace protobuf { +namespace util { +namespace converter { + +using ::PROTOBUF_NAMESPACE_ID::internal::WireFormat; +using ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite; + +namespace { + +static int kDefaultMaxRecursionDepth = 64; + +// Finds a field with the given number. nullptr if none found. +const google::protobuf::Field* FindFieldByNumber( + const google::protobuf::Type& type, int number); + +// Returns true if the field is packable. +bool IsPackable(const google::protobuf::Field& field); + +// Finds an enum value with the given number. nullptr if none found. +const google::protobuf::EnumValue* FindEnumValueByNumber( + const google::protobuf::Enum& tech_enum, int number); + +// Utility function to format nanos. +const TProtoStringType FormatNanos(arc_ui32 nanos, bool with_trailing_zeros); + +util::StatusOr<TProtoStringType> MapKeyDefaultValueAsString( + const google::protobuf::Field& field) { + switch (field.kind()) { + case google::protobuf::Field::TYPE_BOOL: + return TProtoStringType("false"); + case google::protobuf::Field::TYPE_INT32: + case google::protobuf::Field::TYPE_INT64: + case google::protobuf::Field::TYPE_UINT32: + case google::protobuf::Field::TYPE_UINT64: + case google::protobuf::Field::TYPE_SINT32: + case google::protobuf::Field::TYPE_SINT64: + case google::protobuf::Field::TYPE_SFIXED32: + case google::protobuf::Field::TYPE_SFIXED64: + case google::protobuf::Field::TYPE_FIXED32: + case google::protobuf::Field::TYPE_FIXED64: + return TProtoStringType("0"); + case google::protobuf::Field::TYPE_STRING: + return TProtoStringType(); + default: + return util::InternalError("Invalid map key type."); + } +} +} // namespace + + +ProtoStreamObjectSource::ProtoStreamObjectSource( + io::CodedInputStream* stream, TypeResolver* type_resolver, + const google::protobuf::Type& type, const RenderOptions& render_options) + : stream_(stream), + typeinfo_(TypeInfo::NewTypeInfo(type_resolver)), + own_typeinfo_(true), + type_(type), + render_options_(render_options), + recursion_depth_(0), + max_recursion_depth_(kDefaultMaxRecursionDepth) { + GOOGLE_LOG_IF(DFATAL, stream == nullptr) << "Input stream is nullptr."; +} + +ProtoStreamObjectSource::ProtoStreamObjectSource( + io::CodedInputStream* stream, const TypeInfo* typeinfo, + const google::protobuf::Type& type, const RenderOptions& render_options) + : stream_(stream), + typeinfo_(typeinfo), + own_typeinfo_(false), + type_(type), + render_options_(render_options), + recursion_depth_(0), + max_recursion_depth_(kDefaultMaxRecursionDepth) { + GOOGLE_LOG_IF(DFATAL, stream == nullptr) << "Input stream is nullptr."; +} + +ProtoStreamObjectSource::~ProtoStreamObjectSource() { + if (own_typeinfo_) { + delete typeinfo_; + } +} + +util::Status ProtoStreamObjectSource::NamedWriteTo(StringPiece name, + ObjectWriter* ow) const { + return WriteMessage(type_, name, 0, true, ow); +} + +const google::protobuf::Field* ProtoStreamObjectSource::FindAndVerifyField( + const google::protobuf::Type& type, arc_ui32 tag) const { + // Lookup the new field in the type by tag number. + const google::protobuf::Field* field = FindFieldByNumber(type, tag >> 3); + // Verify if the field corresponds to the wire type in tag. + // If there is any discrepancy, mark the field as not found. + if (field != nullptr) { + WireFormatLite::WireType expected_type = + WireFormatLite::WireTypeForFieldType( + static_cast<WireFormatLite::FieldType>(field->kind())); + WireFormatLite::WireType actual_type = WireFormatLite::GetTagWireType(tag); + if (actual_type != expected_type && + (!IsPackable(*field) || + actual_type != WireFormatLite::WIRETYPE_LENGTH_DELIMITED)) { + field = nullptr; + } + } + return field; +} + +util::Status ProtoStreamObjectSource::WriteMessage( + const google::protobuf::Type& type, StringPiece name, + const arc_ui32 end_tag, bool include_start_and_end, + ObjectWriter* ow) const { + + const TypeRenderer* type_renderer = FindTypeRenderer(type.name()); + if (type_renderer != nullptr) { + return (*type_renderer)(this, type, name, ow); + } + + const google::protobuf::Field* field = nullptr; + TProtoStringType field_name; + // last_tag set to dummy value that is different from tag. + arc_ui32 tag = stream_->ReadTag(), last_tag = tag + 1; + UnknownFieldSet unknown_fields; + + + if (include_start_and_end) { + ow->StartObject(name); + } + while (tag != end_tag && tag != 0) { + if (tag != last_tag) { // Update field only if tag is changed. + last_tag = tag; + field = FindAndVerifyField(type, tag); + if (field != nullptr) { + if (render_options_.preserve_proto_field_names) { + field_name = field->name(); + } else { + field_name = field->json_name(); + } + } + } + if (field == nullptr) { + // If we didn't find a field, skip this unknown tag. + // TODO(wpoon): Check return boolean value. + WireFormat::SkipField( + stream_, tag, + nullptr); + tag = stream_->ReadTag(); + continue; + } + + if (field->cardinality() == google::protobuf::Field::CARDINALITY_REPEATED) { + if (IsMap(*field)) { + ow->StartObject(field_name); + ASSIGN_OR_RETURN(tag, RenderMap(field, field_name, tag, ow)); + ow->EndObject(); + } else { + ASSIGN_OR_RETURN(tag, RenderList(field, field_name, tag, ow)); + } + } else { + // Render the field. + RETURN_IF_ERROR(RenderField(field, field_name, ow)); + tag = stream_->ReadTag(); + } + } + + + if (include_start_and_end) { + ow->EndObject(); + } + return util::Status(); +} + +util::StatusOr<arc_ui32> ProtoStreamObjectSource::RenderList( + const google::protobuf::Field* field, StringPiece name, + arc_ui32 list_tag, ObjectWriter* ow) const { + arc_ui32 tag_to_return = 0; + ow->StartList(name); + if (IsPackable(*field) && + list_tag == + WireFormatLite::MakeTag(field->number(), + WireFormatLite::WIRETYPE_LENGTH_DELIMITED)) { + RETURN_IF_ERROR(RenderPacked(field, ow)); + // Since packed fields have a single tag, read another tag from stream to + // return. + tag_to_return = stream_->ReadTag(); + } else { + do { + RETURN_IF_ERROR(RenderField(field, "", ow)); + } while ((tag_to_return = stream_->ReadTag()) == list_tag); + } + ow->EndList(); + return tag_to_return; +} + +util::StatusOr<arc_ui32> ProtoStreamObjectSource::RenderMap( + const google::protobuf::Field* field, StringPiece /* name */, + arc_ui32 list_tag, ObjectWriter* ow) const { + const google::protobuf::Type* field_type = + typeinfo_->GetTypeByTypeUrl(field->type_url()); + arc_ui32 tag_to_return = 0; + do { + // Render map entry message type. + arc_ui32 buffer32; + stream_->ReadVarint32(&buffer32); // message length + int old_limit = stream_->PushLimit(buffer32); + TProtoStringType map_key; + for (arc_ui32 tag = stream_->ReadTag(); tag != 0; + tag = stream_->ReadTag()) { + const google::protobuf::Field* map_entry_field = + FindAndVerifyField(*field_type, tag); + if (map_entry_field == nullptr) { + WireFormat::SkipField(stream_, tag, nullptr); + continue; + } + // Map field numbers are key = 1 and value = 2 + if (map_entry_field->number() == 1) { + map_key = ReadFieldValueAsString(*map_entry_field); + } else if (map_entry_field->number() == 2) { + if (map_key.empty()) { + // An absent map key is treated as the default. + const google::protobuf::Field* key_field = + FindFieldByNumber(*field_type, 1); + if (key_field == nullptr) { + // The Type info for this map entry is incorrect. It should always + // have a field named "key" and with field number 1. + return util::InternalError("Invalid map entry."); + } + ASSIGN_OR_RETURN(map_key, MapKeyDefaultValueAsString(*key_field)); + } + RETURN_IF_ERROR(RenderField(map_entry_field, map_key, ow)); + } else { + // The Type info for this map entry is incorrect. It should contain + // exactly two fields with field number 1 and 2. + return util::InternalError("Invalid map entry."); + } + } + stream_->PopLimit(old_limit); + } while ((tag_to_return = stream_->ReadTag()) == list_tag); + return tag_to_return; +} + +util::Status ProtoStreamObjectSource::RenderPacked( + const google::protobuf::Field* field, ObjectWriter* ow) const { + arc_ui32 length; + stream_->ReadVarint32(&length); + int old_limit = stream_->PushLimit(length); + while (stream_->BytesUntilLimit() > 0) { + RETURN_IF_ERROR(RenderField(field, StringPiece(), ow)); + } + stream_->PopLimit(old_limit); + return util::Status(); +} + +util::Status ProtoStreamObjectSource::RenderTimestamp( + const ProtoStreamObjectSource* os, const google::protobuf::Type& type, + StringPiece field_name, ObjectWriter* ow) { + std::pair<arc_i64, arc_i32> p = os->ReadSecondsAndNanos(type); + arc_i64 seconds = p.first; + arc_i32 nanos = p.second; + if (seconds > kTimestampMaxSeconds || seconds < kTimestampMinSeconds) { + return util::InternalError(StrCat( + "Timestamp seconds exceeds limit for field: ", field_name)); + } + + if (nanos < 0 || nanos >= kNanosPerSecond) { + return util::InternalError( + StrCat("Timestamp nanos exceeds limit for field: ", field_name)); + } + + ow->RenderString(field_name, + ::google::protobuf::internal::FormatTime(seconds, nanos)); + + return util::Status(); +} + +util::Status ProtoStreamObjectSource::RenderDuration( + const ProtoStreamObjectSource* os, const google::protobuf::Type& type, + StringPiece field_name, ObjectWriter* ow) { + std::pair<arc_i64, arc_i32> p = os->ReadSecondsAndNanos(type); + arc_i64 seconds = p.first; + arc_i32 nanos = p.second; + if (seconds > kDurationMaxSeconds || seconds < kDurationMinSeconds) { + return util::InternalError( + StrCat("Duration seconds exceeds limit for field: ", field_name)); + } + + if (nanos <= -kNanosPerSecond || nanos >= kNanosPerSecond) { + return util::InternalError( + StrCat("Duration nanos exceeds limit for field: ", field_name)); + } + + TProtoStringType sign = ""; + if (seconds < 0) { + if (nanos > 0) { + return util::InternalError( + StrCat("Duration nanos is non-negative, but seconds is " + "negative for field: ", + field_name)); + } + sign = "-"; + seconds = -seconds; + nanos = -nanos; + } else if (seconds == 0 && nanos < 0) { + sign = "-"; + nanos = -nanos; + } + TProtoStringType formatted_duration = StringPrintf( + "%s%lld%ss", sign.c_str(), static_cast<long long>(seconds), // NOLINT + FormatNanos( + nanos, + false + ) + .c_str()); + ow->RenderString(field_name, formatted_duration); + return util::Status(); +} + +util::Status ProtoStreamObjectSource::RenderDouble( + const ProtoStreamObjectSource* os, const google::protobuf::Type& /*type*/, + StringPiece field_name, ObjectWriter* ow) { + arc_ui32 tag = os->stream_->ReadTag(); + arc_ui64 buffer64 = 0; // default value of Double wrapper value + if (tag != 0) { + os->stream_->ReadLittleEndian64(&buffer64); + os->stream_->ReadTag(); + } + ow->RenderDouble(field_name, bit_cast<double>(buffer64)); + return util::Status(); +} + +util::Status ProtoStreamObjectSource::RenderFloat( + const ProtoStreamObjectSource* os, const google::protobuf::Type& /*type*/, + StringPiece field_name, ObjectWriter* ow) { + arc_ui32 tag = os->stream_->ReadTag(); + arc_ui32 buffer32 = 0; // default value of Float wrapper value + if (tag != 0) { + os->stream_->ReadLittleEndian32(&buffer32); + os->stream_->ReadTag(); + } + ow->RenderFloat(field_name, bit_cast<float>(buffer32)); + return util::Status(); +} + +util::Status ProtoStreamObjectSource::RenderInt64( + const ProtoStreamObjectSource* os, const google::protobuf::Type& /*type*/, + StringPiece field_name, ObjectWriter* ow) { + arc_ui32 tag = os->stream_->ReadTag(); + arc_ui64 buffer64 = 0; // default value of Int64 wrapper value + if (tag != 0) { + os->stream_->ReadVarint64(&buffer64); + os->stream_->ReadTag(); + } + ow->RenderInt64(field_name, bit_cast<arc_i64>(buffer64)); + return util::Status(); +} + +util::Status ProtoStreamObjectSource::RenderUInt64( + const ProtoStreamObjectSource* os, const google::protobuf::Type& /*type*/, + StringPiece field_name, ObjectWriter* ow) { + arc_ui32 tag = os->stream_->ReadTag(); + arc_ui64 buffer64 = 0; // default value of UInt64 wrapper value + if (tag != 0) { + os->stream_->ReadVarint64(&buffer64); + os->stream_->ReadTag(); + } + ow->RenderUint64(field_name, bit_cast<arc_ui64>(buffer64)); + return util::Status(); +} + +util::Status ProtoStreamObjectSource::RenderInt32( + const ProtoStreamObjectSource* os, const google::protobuf::Type& /*type*/, + StringPiece field_name, ObjectWriter* ow) { + arc_ui32 tag = os->stream_->ReadTag(); + arc_ui32 buffer32 = 0; // default value of Int32 wrapper value + if (tag != 0) { + os->stream_->ReadVarint32(&buffer32); + os->stream_->ReadTag(); + } + ow->RenderInt32(field_name, bit_cast<arc_i32>(buffer32)); + return util::Status(); +} + +util::Status ProtoStreamObjectSource::RenderUInt32( + const ProtoStreamObjectSource* os, const google::protobuf::Type& /*type*/, + StringPiece field_name, ObjectWriter* ow) { + arc_ui32 tag = os->stream_->ReadTag(); + arc_ui32 buffer32 = 0; // default value of UInt32 wrapper value + if (tag != 0) { + os->stream_->ReadVarint32(&buffer32); + os->stream_->ReadTag(); + } + ow->RenderUint32(field_name, bit_cast<arc_ui32>(buffer32)); + return util::Status(); +} + +util::Status ProtoStreamObjectSource::RenderBool( + const ProtoStreamObjectSource* os, const google::protobuf::Type& /*type*/, + StringPiece field_name, ObjectWriter* ow) { + arc_ui32 tag = os->stream_->ReadTag(); + arc_ui64 buffer64 = 0; // results in 'false' value as default, which is the + // default value of Bool wrapper + if (tag != 0) { + os->stream_->ReadVarint64(&buffer64); + os->stream_->ReadTag(); + } + ow->RenderBool(field_name, buffer64 != 0); + return util::Status(); +} + +util::Status ProtoStreamObjectSource::RenderString( + const ProtoStreamObjectSource* os, const google::protobuf::Type& /*type*/, + StringPiece field_name, ObjectWriter* ow) { + arc_ui32 tag = os->stream_->ReadTag(); + arc_ui32 buffer32; + TProtoStringType str; // default value of empty for String wrapper + if (tag != 0) { + os->stream_->ReadVarint32(&buffer32); // string size. + os->stream_->ReadString(&str, buffer32); + os->stream_->ReadTag(); + } + ow->RenderString(field_name, str); + return util::Status(); +} + +util::Status ProtoStreamObjectSource::RenderBytes( + const ProtoStreamObjectSource* os, const google::protobuf::Type& /*type*/, + StringPiece field_name, ObjectWriter* ow) { + arc_ui32 tag = os->stream_->ReadTag(); + arc_ui32 buffer32; + TProtoStringType str; + if (tag != 0) { + os->stream_->ReadVarint32(&buffer32); + os->stream_->ReadString(&str, buffer32); + os->stream_->ReadTag(); + } + ow->RenderBytes(field_name, str); + return util::Status(); +} + +util::Status ProtoStreamObjectSource::RenderStruct( + const ProtoStreamObjectSource* os, const google::protobuf::Type& type, + StringPiece field_name, ObjectWriter* ow) { + const google::protobuf::Field* field = nullptr; + arc_ui32 tag = os->stream_->ReadTag(); + ow->StartObject(field_name); + while (tag != 0) { + field = os->FindAndVerifyField(type, tag); + if (field == nullptr) { + WireFormat::SkipField(os->stream_, tag, nullptr); + tag = os->stream_->ReadTag(); + continue; + } + // google.protobuf.Struct has only one field that is a map. Hence we use + // RenderMap to render that field. + if (os->IsMap(*field)) { + ASSIGN_OR_RETURN(tag, os->RenderMap(field, field_name, tag, ow)); + } + } + ow->EndObject(); + return util::Status(); +} + +util::Status ProtoStreamObjectSource::RenderStructValue( + const ProtoStreamObjectSource* os, const google::protobuf::Type& type, + StringPiece field_name, ObjectWriter* ow) { + const google::protobuf::Field* field = nullptr; + for (arc_ui32 tag = os->stream_->ReadTag(); tag != 0; + tag = os->stream_->ReadTag()) { + field = os->FindAndVerifyField(type, tag); + if (field == nullptr) { + WireFormat::SkipField(os->stream_, tag, nullptr); + continue; + } + RETURN_IF_ERROR(os->RenderField(field, field_name, ow)); + } + return util::Status(); +} + +// TODO(skarvaje): Avoid code duplication of for loops and SkipField logic. +util::Status ProtoStreamObjectSource::RenderStructListValue( + const ProtoStreamObjectSource* os, const google::protobuf::Type& type, + StringPiece field_name, ObjectWriter* ow) { + arc_ui32 tag = os->stream_->ReadTag(); + + // Render empty list when we find empty ListValue message. + if (tag == 0) { + ow->StartList(field_name); + ow->EndList(); + return util::Status(); + } + + while (tag != 0) { + const google::protobuf::Field* field = os->FindAndVerifyField(type, tag); + if (field == nullptr) { + WireFormat::SkipField(os->stream_, tag, nullptr); + tag = os->stream_->ReadTag(); + continue; + } + ASSIGN_OR_RETURN(tag, os->RenderList(field, field_name, tag, ow)); + } + return util::Status(); +} + +util::Status ProtoStreamObjectSource::RenderAny( + const ProtoStreamObjectSource* os, const google::protobuf::Type& type, + StringPiece field_name, ObjectWriter* ow) { + // An Any is of the form { string type_url = 1; bytes value = 2; } + arc_ui32 tag; + TProtoStringType type_url; + TProtoStringType value; + + // First read out the type_url and value from the proto stream + for (tag = os->stream_->ReadTag(); tag != 0; tag = os->stream_->ReadTag()) { + const google::protobuf::Field* field = os->FindAndVerifyField(type, tag); + if (field == nullptr) { + WireFormat::SkipField(os->stream_, tag, nullptr); + continue; + } + // 'type_url' has field number of 1 and 'value' has field number 2 + // //google/protobuf/any.proto + if (field->number() == 1) { + // read type_url + arc_ui32 type_url_size; + os->stream_->ReadVarint32(&type_url_size); + os->stream_->ReadString(&type_url, type_url_size); + } else if (field->number() == 2) { + // read value + arc_ui32 value_size; + os->stream_->ReadVarint32(&value_size); + os->stream_->ReadString(&value, value_size); + } + } + + // If there is no value, we don't lookup the type, we just output it (if + // present). If both type and value are empty we output an empty object. + if (value.empty()) { + ow->StartObject(field_name); + if (!type_url.empty()) { + ow->RenderString("@type", type_url); + } + ow->EndObject(); + return util::Status(); + } + + // If there is a value but no type, we cannot render it, so report an error. + if (type_url.empty()) { + // TODO(sven): Add an external message once those are ready. + return util::InternalError("Invalid Any, the type_url is missing."); + } + + util::StatusOr<const google::protobuf::Type*> resolved_type = + os->typeinfo_->ResolveTypeUrl(type_url); + + if (!resolved_type.ok()) { + // Convert into an internal error, since this means the backend gave us + // an invalid response (missing or invalid type information). + return util::InternalError(resolved_type.status().message()); + } + // nested_type cannot be null at this time. + const google::protobuf::Type* nested_type = resolved_type.value(); + + io::ArrayInputStream zero_copy_stream(value.data(), value.size()); + io::CodedInputStream in_stream(&zero_copy_stream); + // We know the type so we can render it. Recursively parse the nested stream + // using a nested ProtoStreamObjectSource using our nested type information. + ProtoStreamObjectSource nested_os(&in_stream, os->typeinfo_, *nested_type, + os->render_options_); + + // We manually call start and end object here so we can inject the @type. + ow->StartObject(field_name); + ow->RenderString("@type", type_url); + util::Status result = + nested_os.WriteMessage(nested_os.type_, "value", 0, false, ow); + ow->EndObject(); + return result; +} + +util::Status ProtoStreamObjectSource::RenderFieldMask( + const ProtoStreamObjectSource* os, const google::protobuf::Type& type, + StringPiece field_name, ObjectWriter* ow) { + TProtoStringType combined; + arc_ui32 buffer32; + arc_ui32 paths_field_tag = 0; + for (arc_ui32 tag = os->stream_->ReadTag(); tag != 0; + tag = os->stream_->ReadTag()) { + if (paths_field_tag == 0) { + const google::protobuf::Field* field = os->FindAndVerifyField(type, tag); + if (field != nullptr && field->number() == 1 && + field->name() == "paths") { + paths_field_tag = tag; + } + } + if (paths_field_tag != tag) { + return util::InternalError("Invalid FieldMask, unexpected field."); + } + TProtoStringType str; + os->stream_->ReadVarint32(&buffer32); // string size. + os->stream_->ReadString(&str, buffer32); + if (!combined.empty()) { + combined.append(","); + } + combined.append(ConvertFieldMaskPath(str, &ToCamelCase)); + } + ow->RenderString(field_name, combined); + return util::Status(); +} + + +std::unordered_map<TProtoStringType, ProtoStreamObjectSource::TypeRenderer>* + ProtoStreamObjectSource::renderers_ = nullptr; +PROTOBUF_NAMESPACE_ID::internal::once_flag source_renderers_init_; + + +void ProtoStreamObjectSource::InitRendererMap() { + renderers_ = new std::unordered_map<TProtoStringType, + ProtoStreamObjectSource::TypeRenderer>(); + (*renderers_)["google.protobuf.Timestamp"] = + &ProtoStreamObjectSource::RenderTimestamp; + (*renderers_)["google.protobuf.Duration"] = + &ProtoStreamObjectSource::RenderDuration; + (*renderers_)["google.protobuf.DoubleValue"] = + &ProtoStreamObjectSource::RenderDouble; + (*renderers_)["google.protobuf.FloatValue"] = + &ProtoStreamObjectSource::RenderFloat; + (*renderers_)["google.protobuf.Int64Value"] = + &ProtoStreamObjectSource::RenderInt64; + (*renderers_)["google.protobuf.UInt64Value"] = + &ProtoStreamObjectSource::RenderUInt64; + (*renderers_)["google.protobuf.Int32Value"] = + &ProtoStreamObjectSource::RenderInt32; + (*renderers_)["google.protobuf.UInt32Value"] = + &ProtoStreamObjectSource::RenderUInt32; + (*renderers_)["google.protobuf.BoolValue"] = + &ProtoStreamObjectSource::RenderBool; + (*renderers_)["google.protobuf.StringValue"] = + &ProtoStreamObjectSource::RenderString; + (*renderers_)["google.protobuf.BytesValue"] = + &ProtoStreamObjectSource::RenderBytes; + (*renderers_)["google.protobuf.Any"] = &ProtoStreamObjectSource::RenderAny; + (*renderers_)["google.protobuf.Struct"] = + &ProtoStreamObjectSource::RenderStruct; + (*renderers_)["google.protobuf.Value"] = + &ProtoStreamObjectSource::RenderStructValue; + (*renderers_)["google.protobuf.ListValue"] = + &ProtoStreamObjectSource::RenderStructListValue; + (*renderers_)["google.protobuf.FieldMask"] = + &ProtoStreamObjectSource::RenderFieldMask; + ::google::protobuf::internal::OnShutdown(&DeleteRendererMap); +} + +void ProtoStreamObjectSource::DeleteRendererMap() { + delete ProtoStreamObjectSource::renderers_; + renderers_ = nullptr; +} + +// static +ProtoStreamObjectSource::TypeRenderer* +ProtoStreamObjectSource::FindTypeRenderer(const TProtoStringType& type_url) { + PROTOBUF_NAMESPACE_ID::internal::call_once(source_renderers_init_, + InitRendererMap); + return FindOrNull(*renderers_, type_url); +} + +util::Status ProtoStreamObjectSource::RenderField( + const google::protobuf::Field* field, StringPiece field_name, + ObjectWriter* ow) const { + // Short-circuit message types as it tends to call WriteMessage recursively + // and ends up using a lot of stack space. Keep the stack usage of this + // message small in order to preserve stack space and not crash. + if (field->kind() == google::protobuf::Field::TYPE_MESSAGE) { + arc_ui32 buffer32; + stream_->ReadVarint32(&buffer32); // message length + int old_limit = stream_->PushLimit(buffer32); + // Get the nested message type for this field. + const google::protobuf::Type* type = + typeinfo_->GetTypeByTypeUrl(field->type_url()); + if (type == nullptr) { + return util::InternalError( + StrCat("Invalid configuration. Could not find the type: ", + field->type_url())); + } + + // Short-circuit any special type rendering to save call-stack space. + const TypeRenderer* type_renderer = FindTypeRenderer(type->name()); + + RETURN_IF_ERROR(IncrementRecursionDepth(type->name(), field_name)); + if (type_renderer != nullptr) { + RETURN_IF_ERROR((*type_renderer)(this, *type, field_name, ow)); + } else { + RETURN_IF_ERROR(WriteMessage(*type, field_name, 0, true, ow)); + } + --recursion_depth_; + + if (!stream_->ConsumedEntireMessage()) { + return util::InvalidArgumentError( + "Nested protocol message not parsed in its entirety."); + } + stream_->PopLimit(old_limit); + } else { + // Render all other non-message types. + return RenderNonMessageField(field, field_name, ow); + } + return util::Status(); +} + +util::Status ProtoStreamObjectSource::RenderNonMessageField( + const google::protobuf::Field* field, StringPiece field_name, + ObjectWriter* ow) const { + // Temporary buffers of different types. + arc_ui32 buffer32 = 0; + arc_ui64 buffer64 = 0; + TProtoStringType strbuffer; + switch (field->kind()) { + case google::protobuf::Field::TYPE_BOOL: { + stream_->ReadVarint64(&buffer64); + ow->RenderBool(field_name, buffer64 != 0); + break; + } + case google::protobuf::Field::TYPE_INT32: { + stream_->ReadVarint32(&buffer32); + ow->RenderInt32(field_name, bit_cast<arc_i32>(buffer32)); + break; + } + case google::protobuf::Field::TYPE_INT64: { + stream_->ReadVarint64(&buffer64); + ow->RenderInt64(field_name, bit_cast<int64>(buffer64)); + break; + } + case google::protobuf::Field::TYPE_UINT32: { + stream_->ReadVarint32(&buffer32); + ow->RenderUint32(field_name, bit_cast<arc_ui32>(buffer32)); + break; + } + case google::protobuf::Field::TYPE_UINT64: { + stream_->ReadVarint64(&buffer64); + ow->RenderUint64(field_name, bit_cast<uint64>(buffer64)); + break; + } + case google::protobuf::Field::TYPE_SINT32: { + stream_->ReadVarint32(&buffer32); + ow->RenderInt32(field_name, WireFormatLite::ZigZagDecode32(buffer32)); + break; + } + case google::protobuf::Field::TYPE_SINT64: { + stream_->ReadVarint64(&buffer64); + ow->RenderInt64(field_name, WireFormatLite::ZigZagDecode64(buffer64)); + break; + } + case google::protobuf::Field::TYPE_SFIXED32: { + stream_->ReadLittleEndian32(&buffer32); + ow->RenderInt32(field_name, bit_cast<arc_i32>(buffer32)); + break; + } + case google::protobuf::Field::TYPE_SFIXED64: { + stream_->ReadLittleEndian64(&buffer64); + ow->RenderInt64(field_name, bit_cast<int64>(buffer64)); + break; + } + case google::protobuf::Field::TYPE_FIXED32: { + stream_->ReadLittleEndian32(&buffer32); + ow->RenderUint32(field_name, bit_cast<arc_ui32>(buffer32)); + break; + } + case google::protobuf::Field::TYPE_FIXED64: { + stream_->ReadLittleEndian64(&buffer64); + ow->RenderUint64(field_name, bit_cast<uint64>(buffer64)); + break; + } + case google::protobuf::Field::TYPE_FLOAT: { + stream_->ReadLittleEndian32(&buffer32); + ow->RenderFloat(field_name, bit_cast<float>(buffer32)); + break; + } + case google::protobuf::Field::TYPE_DOUBLE: { + stream_->ReadLittleEndian64(&buffer64); + ow->RenderDouble(field_name, bit_cast<double>(buffer64)); + break; + } + case google::protobuf::Field::TYPE_ENUM: { + stream_->ReadVarint32(&buffer32); + + // If the field represents an explicit NULL value, render null. + if (field->type_url() == kStructNullValueTypeUrl) { + ow->RenderNull(field_name); + break; + } + + // Get the nested enum type for this field. + // TODO(skarvaje): Avoid string manipulation. Find ways to speed this + // up. + const google::protobuf::Enum* en = + typeinfo_->GetEnumByTypeUrl(field->type_url()); + // Lookup the name of the enum, and render that. Unknown enum values + // are printed as integers. + if (en != nullptr) { + const google::protobuf::EnumValue* enum_value = + FindEnumValueByNumber(*en, buffer32); + if (enum_value != nullptr) { + if (render_options_.use_ints_for_enums) { + ow->RenderInt32(field_name, buffer32); + } else if (render_options_.use_lower_camel_for_enums) { + ow->RenderString(field_name, + EnumValueNameToLowerCamelCase(enum_value->name())); + } else { + ow->RenderString(field_name, enum_value->name()); + } + } else { + ow->RenderInt32(field_name, buffer32); + } + } else { + ow->RenderInt32(field_name, buffer32); + } + break; + } + case google::protobuf::Field::TYPE_STRING: { + stream_->ReadVarint32(&buffer32); // string size. + stream_->ReadString(&strbuffer, buffer32); + ow->RenderString(field_name, strbuffer); + break; + } + case google::protobuf::Field::TYPE_BYTES: { + stream_->ReadVarint32(&buffer32); // bytes size. + stream_->ReadString(&strbuffer, buffer32); + ow->RenderBytes(field_name, strbuffer); + break; + } + default: + break; + } + return util::Status(); +} + +// TODO(skarvaje): Fix this to avoid code duplication. +const TProtoStringType ProtoStreamObjectSource::ReadFieldValueAsString( + const google::protobuf::Field& field) const { + TProtoStringType result; + switch (field.kind()) { + case google::protobuf::Field::TYPE_BOOL: { + arc_ui64 buffer64; + stream_->ReadVarint64(&buffer64); + result = buffer64 != 0 ? "true" : "false"; + break; + } + case google::protobuf::Field::TYPE_INT32: { + arc_ui32 buffer32; + stream_->ReadVarint32(&buffer32); + result = StrCat(bit_cast<arc_i32>(buffer32)); + break; + } + case google::protobuf::Field::TYPE_INT64: { + arc_ui64 buffer64; + stream_->ReadVarint64(&buffer64); + result = StrCat(bit_cast<arc_i64>(buffer64)); + break; + } + case google::protobuf::Field::TYPE_UINT32: { + arc_ui32 buffer32; + stream_->ReadVarint32(&buffer32); + result = StrCat(bit_cast<arc_ui32>(buffer32)); + break; + } + case google::protobuf::Field::TYPE_UINT64: { + arc_ui64 buffer64; + stream_->ReadVarint64(&buffer64); + result = StrCat(bit_cast<arc_ui64>(buffer64)); + break; + } + case google::protobuf::Field::TYPE_SINT32: { + arc_ui32 buffer32; + stream_->ReadVarint32(&buffer32); + result = StrCat(WireFormatLite::ZigZagDecode32(buffer32)); + break; + } + case google::protobuf::Field::TYPE_SINT64: { + arc_ui64 buffer64; + stream_->ReadVarint64(&buffer64); + result = StrCat(WireFormatLite::ZigZagDecode64(buffer64)); + break; + } + case google::protobuf::Field::TYPE_SFIXED32: { + arc_ui32 buffer32; + stream_->ReadLittleEndian32(&buffer32); + result = StrCat(bit_cast<arc_i32>(buffer32)); + break; + } + case google::protobuf::Field::TYPE_SFIXED64: { + arc_ui64 buffer64; + stream_->ReadLittleEndian64(&buffer64); + result = StrCat(bit_cast<arc_i64>(buffer64)); + break; + } + case google::protobuf::Field::TYPE_FIXED32: { + arc_ui32 buffer32; + stream_->ReadLittleEndian32(&buffer32); + result = StrCat(bit_cast<arc_ui32>(buffer32)); + break; + } + case google::protobuf::Field::TYPE_FIXED64: { + arc_ui64 buffer64; + stream_->ReadLittleEndian64(&buffer64); + result = StrCat(bit_cast<arc_ui64>(buffer64)); + break; + } + case google::protobuf::Field::TYPE_FLOAT: { + arc_ui32 buffer32; + stream_->ReadLittleEndian32(&buffer32); + result = SimpleFtoa(bit_cast<float>(buffer32)); + break; + } + case google::protobuf::Field::TYPE_DOUBLE: { + arc_ui64 buffer64; + stream_->ReadLittleEndian64(&buffer64); + result = SimpleDtoa(bit_cast<double>(buffer64)); + break; + } + case google::protobuf::Field::TYPE_ENUM: { + arc_ui32 buffer32; + stream_->ReadVarint32(&buffer32); + // Get the nested enum type for this field. + // TODO(skarvaje): Avoid string manipulation. Find ways to speed this + // up. + const google::protobuf::Enum* en = + typeinfo_->GetEnumByTypeUrl(field.type_url()); + // Lookup the name of the enum, and render that. Skips unknown enums. + if (en != nullptr) { + const google::protobuf::EnumValue* enum_value = + FindEnumValueByNumber(*en, buffer32); + if (enum_value != nullptr) { + result = enum_value->name(); + } + } + break; + } + case google::protobuf::Field::TYPE_STRING: { + arc_ui32 buffer32; + stream_->ReadVarint32(&buffer32); // string size. + stream_->ReadString(&result, buffer32); + break; + } + case google::protobuf::Field::TYPE_BYTES: { + arc_ui32 buffer32; + stream_->ReadVarint32(&buffer32); // bytes size. + stream_->ReadString(&result, buffer32); + break; + } + default: + break; + } + return result; +} + +// Field is a map if it is a repeated message and it has an option "map_type". +// TODO(skarvaje): Consider pre-computing the IsMap() into Field directly. +bool ProtoStreamObjectSource::IsMap( + const google::protobuf::Field& field) const { + const google::protobuf::Type* field_type = + typeinfo_->GetTypeByTypeUrl(field.type_url()); + return field.kind() == google::protobuf::Field::TYPE_MESSAGE && + util::converter::IsMap(field, *field_type); +} + +std::pair<arc_i64, arc_i32> ProtoStreamObjectSource::ReadSecondsAndNanos( + const google::protobuf::Type& type) const { + arc_ui64 seconds = 0; + arc_ui32 nanos = 0; + arc_ui32 tag = 0; + arc_i64 signed_seconds = 0; + arc_i32 signed_nanos = 0; + + for (tag = stream_->ReadTag(); tag != 0; tag = stream_->ReadTag()) { + const google::protobuf::Field* field = FindAndVerifyField(type, tag); + if (field == nullptr) { + WireFormat::SkipField(stream_, tag, nullptr); + continue; + } + // 'seconds' has field number of 1 and 'nanos' has field number 2 + // //google/protobuf/timestamp.proto & duration.proto + if (field->number() == 1) { + // read seconds + stream_->ReadVarint64(&seconds); + signed_seconds = bit_cast<arc_i64>(seconds); + } else if (field->number() == 2) { + // read nanos + stream_->ReadVarint32(&nanos); + signed_nanos = bit_cast<arc_i32>(nanos); + } + } + return std::pair<arc_i64, arc_i32>(signed_seconds, signed_nanos); +} + +util::Status ProtoStreamObjectSource::IncrementRecursionDepth( + StringPiece type_name, StringPiece field_name) const { + if (++recursion_depth_ > max_recursion_depth_) { + return util::InvalidArgumentError( + StrCat("Message too deep. Max recursion depth reached for type '", + type_name, "', field '", field_name, "'")); + } + return util::Status(); +} + +namespace { +// TODO(skarvaje): Speed this up by not doing a linear scan. +const google::protobuf::Field* FindFieldByNumber( + const google::protobuf::Type& type, int number) { + for (int i = 0; i < type.fields_size(); ++i) { + if (type.fields(i).number() == number) { + return &type.fields(i); + } + } + return nullptr; +} + +// TODO(skarvaje): Replace FieldDescriptor by implementing IsTypePackable() +// using tech Field. +bool IsPackable(const google::protobuf::Field& field) { + return field.cardinality() == google::protobuf::Field::CARDINALITY_REPEATED && + FieldDescriptor::IsTypePackable( + static_cast<FieldDescriptor::Type>(field.kind())); +} + +// TODO(skarvaje): Speed this up by not doing a linear scan. +const google::protobuf::EnumValue* FindEnumValueByNumber( + const google::protobuf::Enum& tech_enum, int number) { + for (int i = 0; i < tech_enum.enumvalue_size(); ++i) { + const google::protobuf::EnumValue& ev = tech_enum.enumvalue(i); + if (ev.number() == number) { + return &ev; + } + } + return nullptr; +} + +// TODO(skarvaje): Look into optimizing this by not doing computation on +// double. +const TProtoStringType FormatNanos(arc_ui32 nanos, bool with_trailing_zeros) { + if (nanos == 0) { + return with_trailing_zeros ? ".000" : ""; + } + + const char* format = (nanos % 1000 != 0) ? "%.9f" + : (nanos % 1000000 != 0) ? "%.6f" + : "%.3f"; + TProtoStringType formatted = + StringPrintf(format, static_cast<double>(nanos) / kNanosPerSecond); + // remove the leading 0 before decimal. + return formatted.substr(1); +} +} // namespace + +} // namespace converter +} // namespace util +} // namespace protobuf +} // namespace google diff --git a/contrib/libs/protobuf_old/src/google/protobuf/util/internal/protostream_objectsource.h b/contrib/libs/protobuf_old/src/google/protobuf/util/internal/protostream_objectsource.h new file mode 100644 index 0000000000..0a853cdc0e --- /dev/null +++ b/contrib/libs/protobuf_old/src/google/protobuf/util/internal/protostream_objectsource.h @@ -0,0 +1,328 @@ +// 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_UTIL_CONVERTER_PROTOSTREAM_OBJECTSOURCE_H__ +#define GOOGLE_PROTOBUF_UTIL_CONVERTER_PROTOSTREAM_OBJECTSOURCE_H__ + +#include <cstdint> +#include <functional> +#include <string> +#include <unordered_map> + +#include <google/protobuf/stubs/status.h> + +#include <google/protobuf/stubs/common.h> +#include <google/protobuf/type.pb.h> +#include <google/protobuf/util/internal/type_info.h> +#include <google/protobuf/util/internal/object_source.h> +#include <google/protobuf/util/internal/object_writer.h> +#include <google/protobuf/util/type_resolver.h> +#include <google/protobuf/stubs/statusor.h> +#include <google/protobuf/stubs/strutil.h> +#include <google/protobuf/stubs/hash.h> +#include <google/protobuf/stubs/status.h> + + +#include <google/protobuf/port_def.inc> + +namespace google { +namespace protobuf { +namespace util { +namespace converter { + +class TypeInfo; + +// An ObjectSource that can parse a stream of bytes as a protocol buffer. +// Its WriteTo() method can be given an ObjectWriter. +// This implementation uses a google.protobuf.Type for tag and name lookup. +// The field names are converted into lower camel-case when writing to the +// ObjectWriter. +// +// Sample usage: (suppose input is: string proto) +// ArrayInputStream arr_stream(proto.data(), proto.size()); +// CodedInputStream in_stream(&arr_stream); +// ProtoStreamObjectSource os(&in_stream, /*ServiceTypeInfo*/ typeinfo, +// <your message google::protobuf::Type>); +// +// Status status = os.WriteTo(<some ObjectWriter>); +class PROTOBUF_EXPORT ProtoStreamObjectSource : public ObjectSource { + public: + + struct RenderOptions { + RenderOptions() = default; + RenderOptions(const RenderOptions&) = default; + + // Sets whether or not to use lowerCamelCase casing for enum values. If set + // to false, enum values are output without any case conversions. + // + // For example, if we have an enum: + // enum Type { + // ACTION_AND_ADVENTURE = 1; + // } + // Type type = 20; + // + // And this option is set to true. Then the rendered "type" field will have + // the string "actionAndAdventure". + // { + // ... + // "type": "actionAndAdventure", + // ... + // } + // + // If set to false, the rendered "type" field will have the string + // "ACTION_AND_ADVENTURE". + // { + // ... + // "type": "ACTION_AND_ADVENTURE", + // ... + // } + bool use_lower_camel_for_enums = false; + + // Sets whether to always output enums as ints, by default this is off, and + // enums are rendered as strings. + bool use_ints_for_enums = false; + + // Whether to preserve proto field names + bool preserve_proto_field_names = false; + + }; + + ProtoStreamObjectSource(io::CodedInputStream* stream, + TypeResolver* type_resolver, + const google::protobuf::Type& type) + : ProtoStreamObjectSource(stream, type_resolver, type, RenderOptions()) {} + ProtoStreamObjectSource(io::CodedInputStream* stream, + TypeResolver* type_resolver, + const google::protobuf::Type& type, + const RenderOptions& render_options); + + ~ProtoStreamObjectSource() override; + + util::Status NamedWriteTo(StringPiece name, + ObjectWriter* ow) const override; + + // Sets the max recursion depth of proto message to be deserialized. Proto + // messages over this depth will fail to be deserialized. + // Default value is 64. + void set_max_recursion_depth(int max_depth) { + max_recursion_depth_ = max_depth; + } + + protected: + // Writes a proto2 Message to the ObjectWriter. When the given end_tag is + // found this method will complete, allowing it to be used for parsing both + // nested messages (end with 0) and nested groups (end with group end tag). + // The include_start_and_end parameter allows this method to be called when + // already inside of an object, and skip calling StartObject and EndObject. + virtual util::Status WriteMessage(const google::protobuf::Type& type, + StringPiece name, + const arc_ui32 end_tag, + bool include_start_and_end, + ObjectWriter* ow) const; + + // Renders a repeating field (packed or unpacked). Returns the next tag after + // reading all sequential repeating elements. The caller should use this tag + // before reading more tags from the stream. + virtual util::StatusOr<arc_ui32> RenderList( + const google::protobuf::Field* field, StringPiece name, + arc_ui32 list_tag, ObjectWriter* ow) const; + + // Looks up a field and verify its consistency with wire type in tag. + const google::protobuf::Field* FindAndVerifyField( + const google::protobuf::Type& type, arc_ui32 tag) const; + + // Renders a field value to the ObjectWriter. + virtual util::Status RenderField(const google::protobuf::Field* field, + StringPiece field_name, + ObjectWriter* ow) const; + + // Reads field value according to Field spec in 'field' and returns the read + // value as string. This only works for primitive datatypes (no message + // types). + const TProtoStringType ReadFieldValueAsString( + const google::protobuf::Field& field) const; + + + // Returns the input stream. + io::CodedInputStream* stream() const { return stream_; } + + private: + ProtoStreamObjectSource(io::CodedInputStream* stream, + const TypeInfo* typeinfo, + const google::protobuf::Type& type, + const RenderOptions& render_options); + // Function that renders a well known type with a modified behavior. + typedef util::Status (*TypeRenderer)(const ProtoStreamObjectSource*, + const google::protobuf::Type&, + StringPiece, ObjectWriter*); + + // TODO(skarvaje): Mark these methods as non-const as they modify internal + // state (stream_). + // + // Renders a NWP map. + // Returns the next tag after reading all map entries. The caller should use + // this tag before reading more tags from the stream. + util::StatusOr<arc_ui32> RenderMap(const google::protobuf::Field* field, + StringPiece name, arc_ui32 list_tag, + ObjectWriter* ow) const; + + // Renders a packed repeating field. A packed field is stored as: + // {tag length item1 item2 item3} instead of the less efficient + // {tag item1 tag item2 tag item3}. + util::Status RenderPacked(const google::protobuf::Field* field, + ObjectWriter* ow) const; + + // Renders a google.protobuf.Timestamp value to ObjectWriter + static util::Status RenderTimestamp(const ProtoStreamObjectSource* os, + const google::protobuf::Type& type, + StringPiece name, ObjectWriter* ow); + + // Renders a google.protobuf.Duration value to ObjectWriter + static util::Status RenderDuration(const ProtoStreamObjectSource* os, + const google::protobuf::Type& type, + StringPiece name, ObjectWriter* ow); + + // Following RenderTYPE functions render well known types in + // google/protobuf/wrappers.proto corresponding to TYPE. + static util::Status RenderDouble(const ProtoStreamObjectSource* os, + const google::protobuf::Type& type, + StringPiece name, ObjectWriter* ow); + static util::Status RenderFloat(const ProtoStreamObjectSource* os, + const google::protobuf::Type& type, + StringPiece name, ObjectWriter* ow); + static util::Status RenderInt64(const ProtoStreamObjectSource* os, + const google::protobuf::Type& type, + StringPiece name, ObjectWriter* ow); + static util::Status RenderUInt64(const ProtoStreamObjectSource* os, + const google::protobuf::Type& type, + StringPiece name, ObjectWriter* ow); + static util::Status RenderInt32(const ProtoStreamObjectSource* os, + const google::protobuf::Type& type, + StringPiece name, ObjectWriter* ow); + static util::Status RenderUInt32(const ProtoStreamObjectSource* os, + const google::protobuf::Type& type, + StringPiece name, ObjectWriter* ow); + static util::Status RenderBool(const ProtoStreamObjectSource* os, + const google::protobuf::Type& type, + StringPiece name, ObjectWriter* ow); + static util::Status RenderString(const ProtoStreamObjectSource* os, + const google::protobuf::Type& type, + StringPiece name, ObjectWriter* ow); + static util::Status RenderBytes(const ProtoStreamObjectSource* os, + const google::protobuf::Type& type, + StringPiece name, ObjectWriter* ow); + + // Renders a google.protobuf.Struct to ObjectWriter. + static util::Status RenderStruct(const ProtoStreamObjectSource* os, + const google::protobuf::Type& type, + StringPiece name, ObjectWriter* ow); + + // Helper to render google.protobuf.Struct's Value fields to ObjectWriter. + static util::Status RenderStructValue(const ProtoStreamObjectSource* os, + const google::protobuf::Type& type, + StringPiece name, + ObjectWriter* ow); + + // Helper to render google.protobuf.Struct's ListValue fields to ObjectWriter. + static util::Status RenderStructListValue(const ProtoStreamObjectSource* os, + const google::protobuf::Type& type, + StringPiece name, + ObjectWriter* ow); + + // Render the "Any" type. + static util::Status RenderAny(const ProtoStreamObjectSource* os, + const google::protobuf::Type& type, + StringPiece name, ObjectWriter* ow); + + // Render the "FieldMask" type. + static util::Status RenderFieldMask(const ProtoStreamObjectSource* os, + const google::protobuf::Type& type, + StringPiece name, ObjectWriter* ow); + + static std::unordered_map<TProtoStringType, TypeRenderer>* renderers_; + static void InitRendererMap(); + static void DeleteRendererMap(); + static TypeRenderer* FindTypeRenderer(const TProtoStringType& type_url); + + // Same as above but renders all non-message field types. Callers don't call + // this function directly. They just use RenderField. + util::Status RenderNonMessageField(const google::protobuf::Field* field, + StringPiece field_name, + ObjectWriter* ow) const; + + + // Utility function to detect proto maps. The 'field' MUST be repeated. + bool IsMap(const google::protobuf::Field& field) const; + + // Utility to read int64 and int32 values from a message type in stream_. + // Used for reading google.protobuf.Timestamp and Duration messages. + std::pair<arc_i64, arc_i32> ReadSecondsAndNanos( + const google::protobuf::Type& type) const; + + // Helper function to check recursion depth and increment it. It will return + // OkStatus() if the current depth is allowed. Otherwise an error is returned. + // type_name and field_name are used for error reporting. + util::Status IncrementRecursionDepth(StringPiece type_name, + StringPiece field_name) const; + + // Input stream to read from. Ownership rests with the caller. + mutable io::CodedInputStream* stream_; + + // Type information for all the types used in the descriptor. Used to find + // google::protobuf::Type of nested messages/enums. + const TypeInfo* typeinfo_; + + // Whether this class owns the typeinfo_ object. If true the typeinfo_ object + // should be deleted in the destructor. + bool own_typeinfo_; + + // google::protobuf::Type of the message source. + const google::protobuf::Type& type_; + + + const RenderOptions render_options_; + + // Tracks current recursion depth. + mutable int recursion_depth_; + + // Maximum allowed recursion depth. + int max_recursion_depth_; + + GOOGLE_DISALLOW_IMPLICIT_CONSTRUCTORS(ProtoStreamObjectSource); +}; + +} // namespace converter +} // namespace util +} // namespace protobuf +} // namespace google + +#include <google/protobuf/port_undef.inc> + +#endif // GOOGLE_PROTOBUF_UTIL_CONVERTER_PROTOSTREAM_OBJECTSOURCE_H__ diff --git a/contrib/libs/protobuf_old/src/google/protobuf/util/internal/protostream_objectwriter.cc b/contrib/libs/protobuf_old/src/google/protobuf/util/internal/protostream_objectwriter.cc new file mode 100644 index 0000000000..6e96598d0d --- /dev/null +++ b/contrib/libs/protobuf_old/src/google/protobuf/util/internal/protostream_objectwriter.cc @@ -0,0 +1,1400 @@ +// 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 <google/protobuf/util/internal/protostream_objectwriter.h> + +#include <cstdint> +#include <functional> +#include <stack> +#include <unordered_map> +#include <unordered_set> + +#include <google/protobuf/stubs/once.h> +#include <google/protobuf/wire_format_lite.h> +#include <google/protobuf/util/internal/field_mask_utility.h> +#include <google/protobuf/util/internal/object_location_tracker.h> +#include <google/protobuf/util/internal/constants.h> +#include <google/protobuf/util/internal/utility.h> +#include <google/protobuf/stubs/strutil.h> +#include <google/protobuf/stubs/status.h> +#include <google/protobuf/stubs/statusor.h> +#include <google/protobuf/stubs/time.h> +#include <google/protobuf/stubs/map_util.h> + + +#include <google/protobuf/port_def.inc> + +namespace google { +namespace protobuf { +namespace util { +namespace converter { + +using ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite; +using std::placeholders::_1; +using util::Status; + + +ProtoStreamObjectWriter::ProtoStreamObjectWriter( + TypeResolver* type_resolver, const google::protobuf::Type& type, + strings::ByteSink* output, ErrorListener* listener, + const ProtoStreamObjectWriter::Options& options) + : ProtoWriter(type_resolver, type, output, listener), + master_type_(type), + current_(nullptr), + options_(options) { + set_ignore_unknown_fields(options_.ignore_unknown_fields); + set_ignore_unknown_enum_values(options_.ignore_unknown_enum_values); + set_use_lower_camel_for_enums(options_.use_lower_camel_for_enums); + set_case_insensitive_enum_parsing(options_.case_insensitive_enum_parsing); + set_use_json_name_in_missing_fields(options.use_json_name_in_missing_fields); +} + +ProtoStreamObjectWriter::ProtoStreamObjectWriter( + const TypeInfo* typeinfo, const google::protobuf::Type& type, + strings::ByteSink* output, ErrorListener* listener, + const ProtoStreamObjectWriter::Options& options) + : ProtoWriter(typeinfo, type, output, listener), + master_type_(type), + current_(nullptr), + options_(options) { + set_ignore_unknown_fields(options_.ignore_unknown_fields); + set_use_lower_camel_for_enums(options.use_lower_camel_for_enums); + set_case_insensitive_enum_parsing(options_.case_insensitive_enum_parsing); + set_use_json_name_in_missing_fields(options.use_json_name_in_missing_fields); +} + +ProtoStreamObjectWriter::ProtoStreamObjectWriter( + const TypeInfo* typeinfo, const google::protobuf::Type& type, + strings::ByteSink* output, ErrorListener* listener) + : ProtoWriter(typeinfo, type, output, listener), + master_type_(type), + current_(nullptr), + options_(ProtoStreamObjectWriter::Options::Defaults()) {} + +ProtoStreamObjectWriter::~ProtoStreamObjectWriter() { + if (current_ == nullptr) return; + // Cleanup explicitly in order to avoid destructor stack overflow when input + // is deeply nested. + // Cast to BaseElement to avoid doing additional checks (like missing fields) + // during pop(). + std::unique_ptr<BaseElement> element( + static_cast<BaseElement*>(current_.get())->pop<BaseElement>()); + while (element != nullptr) { + element.reset(element->pop<BaseElement>()); + } +} + +namespace { +// Utility method to split a string representation of Timestamp or Duration and +// return the parts. +void SplitSecondsAndNanos(StringPiece input, StringPiece* seconds, + StringPiece* nanos) { + size_t idx = input.rfind('.'); + if (idx != TProtoStringType::npos) { + *seconds = input.substr(0, idx); + *nanos = input.substr(idx + 1); + } else { + *seconds = input; + *nanos = StringPiece(); + } +} + +Status GetNanosFromStringPiece(StringPiece s_nanos, + const char* parse_failure_message, + const char* exceeded_limit_message, + arc_i32* nanos) { + *nanos = 0; + + // Count the number of leading 0s and consume them. + int num_leading_zeros = 0; + while (s_nanos.Consume("0")) { + num_leading_zeros++; + } + arc_i32 i_nanos = 0; + // 's_nanos' contains fractional seconds -- i.e. 'nanos' is equal to + // "0." + s_nanos.ToString() seconds. An int32 is used for the + // conversion to 'nanos', rather than a double, so that there is no + // loss of precision. + if (!s_nanos.empty() && !safe_strto32(s_nanos, &i_nanos)) { + return util::InvalidArgumentError(parse_failure_message); + } + if (i_nanos > kNanosPerSecond || i_nanos < 0) { + return util::InvalidArgumentError(exceeded_limit_message); + } + // s_nanos should only have digits. No whitespace. + if (s_nanos.find_first_not_of("0123456789") != StringPiece::npos) { + return util::InvalidArgumentError(parse_failure_message); + } + + if (i_nanos > 0) { + // 'scale' is the number of digits to the right of the decimal + // point in "0." + s_nanos.ToString() + arc_i32 scale = num_leading_zeros + s_nanos.size(); + // 'conversion' converts i_nanos into nanoseconds. + // conversion = kNanosPerSecond / static_cast<int32>(std::pow(10, scale)) + // For efficiency, we precompute the conversion factor. + arc_i32 conversion = 0; + switch (scale) { + case 1: + conversion = 100000000; + break; + case 2: + conversion = 10000000; + break; + case 3: + conversion = 1000000; + break; + case 4: + conversion = 100000; + break; + case 5: + conversion = 10000; + break; + case 6: + conversion = 1000; + break; + case 7: + conversion = 100; + break; + case 8: + conversion = 10; + break; + case 9: + conversion = 1; + break; + default: + return util::InvalidArgumentError(exceeded_limit_message); + } + *nanos = i_nanos * conversion; + } + + return Status(); +} + +} // namespace + +ProtoStreamObjectWriter::AnyWriter::AnyWriter(ProtoStreamObjectWriter* parent) + : parent_(parent), + ow_(), + invalid_(false), + data_(), + output_(&data_), + depth_(0), + is_well_known_type_(false), + well_known_type_render_(nullptr) {} + +ProtoStreamObjectWriter::AnyWriter::~AnyWriter() {} + +void ProtoStreamObjectWriter::AnyWriter::StartObject(StringPiece name) { + ++depth_; + // If an object writer is absent, that means we have not called StartAny() + // before reaching here, which happens when we have data before the "@type" + // field. + if (ow_ == nullptr) { + // Save data before the "@type" field for later replay. + uninterpreted_events_.push_back(Event(Event::START_OBJECT, name)); + } else if (is_well_known_type_ && depth_ == 1) { + // For well-known types, the only other field besides "@type" should be a + // "value" field. + if (name != "value" && !invalid_) { + parent_->InvalidValue("Any", + "Expect a \"value\" field for well-known types."); + invalid_ = true; + } + ow_->StartObject(""); + } else { + // Forward the call to the child writer if: + // 1. the type is not a well-known type. + // 2. or, we are in a nested Any, Struct, or Value object. + ow_->StartObject(name); + } +} + +bool ProtoStreamObjectWriter::AnyWriter::EndObject() { + --depth_; + if (ow_ == nullptr) { + if (depth_ >= 0) { + // Save data before the "@type" field for later replay. + uninterpreted_events_.push_back(Event(Event::END_OBJECT)); + } + } else if (depth_ >= 0 || !is_well_known_type_) { + // As long as depth_ >= 0, we know we haven't reached the end of Any. + // Propagate these EndObject() calls to the contained ow_. For regular + // message types, we propagate the end of Any as well. + ow_->EndObject(); + } + // A negative depth_ implies that we have reached the end of Any + // object. Now we write out its contents. + if (depth_ < 0) { + WriteAny(); + return false; + } + return true; +} + +void ProtoStreamObjectWriter::AnyWriter::StartList(StringPiece name) { + ++depth_; + if (ow_ == nullptr) { + // Save data before the "@type" field for later replay. + uninterpreted_events_.push_back(Event(Event::START_LIST, name)); + } else if (is_well_known_type_ && depth_ == 1) { + if (name != "value" && !invalid_) { + parent_->InvalidValue("Any", + "Expect a \"value\" field for well-known types."); + invalid_ = true; + } + ow_->StartList(""); + } else { + ow_->StartList(name); + } +} + +void ProtoStreamObjectWriter::AnyWriter::EndList() { + --depth_; + if (depth_ < 0) { + GOOGLE_LOG(DFATAL) << "Mismatched EndList found, should not be possible"; + depth_ = 0; + } + if (ow_ == nullptr) { + // Save data before the "@type" field for later replay. + uninterpreted_events_.push_back(Event(Event::END_LIST)); + } else { + ow_->EndList(); + } +} + +void ProtoStreamObjectWriter::AnyWriter::RenderDataPiece( + StringPiece name, const DataPiece& value) { + // Start an Any only at depth_ 0. Other RenderDataPiece calls with "@type" + // should go to the contained ow_ as they indicate nested Anys. + if (depth_ == 0 && ow_ == nullptr && name == "@type") { + StartAny(value); + } else if (ow_ == nullptr) { + // Save data before the "@type" field. + uninterpreted_events_.push_back(Event(name, value)); + } else if (depth_ == 0 && is_well_known_type_) { + if (name != "value" && !invalid_) { + parent_->InvalidValue("Any", + "Expect a \"value\" field for well-known types."); + invalid_ = true; + } + if (well_known_type_render_ == nullptr) { + // Only Any and Struct don't have a special type render but both of + // them expect a JSON object (i.e., a StartObject() call). + if (value.type() != DataPiece::TYPE_NULL && !invalid_) { + parent_->InvalidValue("Any", "Expect a JSON object."); + invalid_ = true; + } + } else { + ow_->ProtoWriter::StartObject(""); + Status status = (*well_known_type_render_)(ow_.get(), value); + if (!status.ok()) ow_->InvalidValue("Any", status.message()); + ow_->ProtoWriter::EndObject(); + } + } else { + ow_->RenderDataPiece(name, value); + } +} + +void ProtoStreamObjectWriter::AnyWriter::StartAny(const DataPiece& value) { + // Figure out the type url. This is a copy-paste from WriteString but we also + // need the value, so we can't just call through to that. + if (value.type() == DataPiece::TYPE_STRING) { + type_url_ = TProtoStringType(value.str()); + } else { + util::StatusOr<TProtoStringType> s = value.ToString(); + if (!s.ok()) { + parent_->InvalidValue("String", s.status().message()); + invalid_ = true; + return; + } + type_url_ = s.value(); + } + // Resolve the type url, and report an error if we failed to resolve it. + util::StatusOr<const google::protobuf::Type*> resolved_type = + parent_->typeinfo()->ResolveTypeUrl(type_url_); + if (!resolved_type.ok()) { + parent_->InvalidValue("Any", resolved_type.status().message()); + invalid_ = true; + return; + } + // At this point, type is never null. + const google::protobuf::Type* type = resolved_type.value(); + + well_known_type_render_ = FindTypeRenderer(type_url_); + if (well_known_type_render_ != nullptr || + // Explicitly list Any and Struct here because they don't have a + // custom renderer. + type->name() == kAnyType || type->name() == kStructType) { + is_well_known_type_ = true; + } + + // Create our object writer and initialize it with the first StartObject + // call. + ow_.reset(new ProtoStreamObjectWriter(parent_->typeinfo(), *type, &output_, + parent_->listener(), + parent_->options_)); + + // Don't call StartObject() for well-known types yet. Depending on the + // type of actual data, we may not need to call StartObject(). For + // example: + // { + // "@type": "type.googleapis.com/google.protobuf.Value", + // "value": [1, 2, 3], + // } + // With the above JSON representation, we will only call StartList() on the + // contained ow_. + if (!is_well_known_type_) { + ow_->StartObject(""); + } + + // Now we know the proto type and can interpret all data fields we gathered + // before the "@type" field. + for (int i = 0; i < uninterpreted_events_.size(); ++i) { + uninterpreted_events_[i].Replay(this); + } +} + +void ProtoStreamObjectWriter::AnyWriter::WriteAny() { + if (ow_ == nullptr) { + if (uninterpreted_events_.empty()) { + // We never got any content, so just return immediately, which is + // equivalent to writing an empty Any. + return; + } else { + // There are uninterpreted data, but we never got a "@type" field. + if (!invalid_) { + parent_->InvalidValue("Any", + StrCat("Missing @type for any field in ", + parent_->master_type_.name())); + invalid_ = true; + } + return; + } + } + // Render the type_url and value fields directly to the stream. + // type_url has tag 1 and value has tag 2. + WireFormatLite::WriteString(1, type_url_, parent_->stream()); + if (!data_.empty()) { + WireFormatLite::WriteBytes(2, data_, parent_->stream()); + } +} + +void ProtoStreamObjectWriter::AnyWriter::Event::Replay( + AnyWriter* writer) const { + switch (type_) { + case START_OBJECT: + writer->StartObject(name_); + break; + case END_OBJECT: + writer->EndObject(); + break; + case START_LIST: + writer->StartList(name_); + break; + case END_LIST: + writer->EndList(); + break; + case RENDER_DATA_PIECE: + writer->RenderDataPiece(name_, value_); + break; + } +} + +void ProtoStreamObjectWriter::AnyWriter::Event::DeepCopy() { + // DataPiece only contains a string reference. To make sure the referenced + // string value stays valid, we make a copy of the string value and update + // DataPiece to reference our own copy. + if (value_.type() == DataPiece::TYPE_STRING) { + StrAppend(&value_storage_, value_.str()); + value_ = DataPiece(value_storage_, value_.use_strict_base64_decoding()); + } else if (value_.type() == DataPiece::TYPE_BYTES) { + value_storage_ = value_.ToBytes().value(); + value_ = + DataPiece(value_storage_, true, value_.use_strict_base64_decoding()); + } +} + +ProtoStreamObjectWriter::Item::Item(ProtoStreamObjectWriter* enclosing, + ItemType item_type, bool is_placeholder, + bool is_list) + : BaseElement(nullptr), + ow_(enclosing), + any_(), + item_type_(item_type), + is_placeholder_(is_placeholder), + is_list_(is_list) { + if (item_type_ == ANY) { + any_.reset(new AnyWriter(ow_)); + } + if (item_type == MAP) { + map_keys_.reset(new std::unordered_set<TProtoStringType>); + } +} + +ProtoStreamObjectWriter::Item::Item(ProtoStreamObjectWriter::Item* parent, + ItemType item_type, bool is_placeholder, + bool is_list) + : BaseElement(parent), + ow_(this->parent()->ow_), + any_(), + item_type_(item_type), + is_placeholder_(is_placeholder), + is_list_(is_list) { + if (item_type == ANY) { + any_.reset(new AnyWriter(ow_)); + } + if (item_type == MAP) { + map_keys_.reset(new std::unordered_set<TProtoStringType>); + } +} + +bool ProtoStreamObjectWriter::Item::InsertMapKeyIfNotPresent( + StringPiece map_key) { + return InsertIfNotPresent(map_keys_.get(), TProtoStringType(map_key)); +} + + +ProtoStreamObjectWriter* ProtoStreamObjectWriter::StartObject( + StringPiece name) { + if (invalid_depth() > 0) { + IncrementInvalidDepth(); + return this; + } + + // Starting the root message. Create the root Item and return. + // ANY message type does not need special handling, just set the ItemType + // to ANY. + if (current_ == nullptr) { + ProtoWriter::StartObject(name); + current_.reset(new Item( + this, master_type_.name() == kAnyType ? Item::ANY : Item::MESSAGE, + false, false)); + + // If master type is a special type that needs extra values to be written to + // stream, we write those values. + if (master_type_.name() == kStructType) { + // Struct has a map<string, Value> field called "fields". + // https://github.com/protocolbuffers/protobuf/blob/master/src/google/protobuf/struct.proto + // "fields": [ + Push("fields", Item::MAP, true, true); + return this; + } + + if (master_type_.name() == kStructValueType) { + // We got a StartObject call with google.protobuf.Value field. The only + // object within that type is a struct type. So start a struct. + // + // The struct field in Value type is named "struct_value" + // https://github.com/protocolbuffers/protobuf/blob/master/src/google/protobuf/struct.proto + // Also start the map field "fields" within the struct. + // "struct_value": { + // "fields": [ + Push("struct_value", Item::MESSAGE, true, false); + Push("fields", Item::MAP, true, true); + return this; + } + + if (master_type_.name() == kStructListValueType) { + InvalidValue(kStructListValueType, + "Cannot start root message with ListValue."); + } + + return this; + } + + // Send all ANY events to AnyWriter. + if (current_->IsAny()) { + current_->any()->StartObject(name); + return this; + } + + // If we are within a map, we render name as keys and send StartObject to the + // value field. + if (current_->IsMap()) { + if (!ValidMapKey(name)) { + IncrementInvalidDepth(); + return this; + } + + // Map is a repeated field of message type with a "key" and a "value" field. + // https://developers.google.com/protocol-buffers/docs/proto3?hl=en#maps + // message MapFieldEntry { + // key_type key = 1; + // value_type value = 2; + // } + // + // repeated MapFieldEntry map_field = N; + // + // That means, we render the following element within a list (hence no + // name): + // { "key": "<name>", "value": { + Push("", Item::MESSAGE, false, false); + ProtoWriter::RenderDataPiece("key", + DataPiece(name, use_strict_base64_decoding())); + Push("value", IsAny(*Lookup("value")) ? Item::ANY : Item::MESSAGE, true, + false); + + // Make sure we are valid so far after starting map fields. + if (invalid_depth() > 0) return this; + + // If top of stack is g.p.Struct type, start the struct the map field within + // it. + if (element() != nullptr && IsStruct(*element()->parent_field())) { + // Render "fields": [ + Push("fields", Item::MAP, true, true); + return this; + } + + // If top of stack is g.p.Value type, start the Struct within it. + if (element() != nullptr && IsStructValue(*element()->parent_field())) { + // Render + // "struct_value": { + // "fields": [ + Push("struct_value", Item::MESSAGE, true, false); + Push("fields", Item::MAP, true, true); + } + return this; + } + + const google::protobuf::Field* field = BeginNamed(name, false); + + if (field == nullptr) return this; + + // Legacy JSON map is a list of key value pairs. Starts a map entry object. + if (options_.use_legacy_json_map_format && name.empty()) { + Push(name, IsAny(*field) ? Item::ANY : Item::MESSAGE, false, false); + return this; + } + + if (IsMap(*field)) { + // Begin a map. A map is triggered by a StartObject() call if the current + // field has a map type. + // A map type is always repeated, hence set is_list to true. + // Render + // "<name>": [ + Push(name, Item::MAP, false, true); + return this; + } + + if (options_.disable_implicit_message_list) { + // If the incoming object is repeated, the top-level object on stack should + // be list. Report an error otherwise. + if (IsRepeated(*field) && !current_->is_list()) { + IncrementInvalidDepth(); + + if (!options_.suppress_implicit_message_list_error) { + InvalidValue( + field->name(), + "Starting an object in a repeated field but the parent object " + "is not a list"); + } + return this; + } + } + + if (IsStruct(*field)) { + // Start a struct object. + // Render + // "<name>": { + // "fields": { + Push(name, Item::MESSAGE, false, false); + Push("fields", Item::MAP, true, true); + return this; + } + + if (IsStructValue(*field)) { + // We got a StartObject call with google.protobuf.Value field. The only + // object within that type is a struct type. So start a struct. + // Render + // "<name>": { + // "struct_value": { + // "fields": { + Push(name, Item::MESSAGE, false, false); + Push("struct_value", Item::MESSAGE, true, false); + Push("fields", Item::MAP, true, true); + return this; + } + + if (field->kind() != google::protobuf::Field::TYPE_GROUP && + field->kind() != google::protobuf::Field::TYPE_MESSAGE) { + IncrementInvalidDepth(); + if (!options_.suppress_object_to_scalar_error) { + InvalidValue(field->name(), "Starting an object on a scalar field"); + } + + return this; + } + + // A regular message type. Pass it directly to ProtoWriter. + // Render + // "<name>": { + Push(name, IsAny(*field) ? Item::ANY : Item::MESSAGE, false, false); + return this; +} + +ProtoStreamObjectWriter* ProtoStreamObjectWriter::EndObject() { + if (invalid_depth() > 0) { + DecrementInvalidDepth(); + return this; + } + + if (current_ == nullptr) return this; + + if (current_->IsAny()) { + if (current_->any()->EndObject()) return this; + } + + Pop(); + + return this; +} + + +ProtoStreamObjectWriter* ProtoStreamObjectWriter::StartList( + StringPiece name) { + if (invalid_depth() > 0) { + IncrementInvalidDepth(); + return this; + } + + // Since we cannot have a top-level repeated item in protobuf, the only way + // this is valid is if we start a special type google.protobuf.ListValue or + // google.protobuf.Value. + if (current_ == nullptr) { + if (!name.empty()) { + InvalidName(name, "Root element should not be named."); + IncrementInvalidDepth(); + return this; + } + + // If master type is a special type that needs extra values to be written to + // stream, we write those values. + if (master_type_.name() == kStructValueType) { + // We got a StartList with google.protobuf.Value master type. This means + // we have to start the "list_value" within google.protobuf.Value. + // + // See + // https://github.com/protocolbuffers/protobuf/blob/master/src/google/protobuf/struct.proto + // + // Render + // "<name>": { + // "list_value": { + // "values": [ // Start this list. + ProtoWriter::StartObject(name); + current_.reset(new Item(this, Item::MESSAGE, false, false)); + Push("list_value", Item::MESSAGE, true, false); + Push("values", Item::MESSAGE, true, true); + return this; + } + + if (master_type_.name() == kStructListValueType) { + // We got a StartList with google.protobuf.ListValue master type. This + // means we have to start the "values" within google.protobuf.ListValue. + // + // Render + // "<name>": { + // "values": [ // Start this list. + ProtoWriter::StartObject(name); + current_.reset(new Item(this, Item::MESSAGE, false, false)); + Push("values", Item::MESSAGE, true, true); + return this; + } + + // Send the event to ProtoWriter so proper errors can be reported. + // + // Render a regular list: + // "<name>": [ + ProtoWriter::StartList(name); + current_.reset(new Item(this, Item::MESSAGE, false, true)); + return this; + } + + if (current_->IsAny()) { + current_->any()->StartList(name); + return this; + } + + // If the top of stack is a map, we are starting a list value within a map. + // Since map does not allow repeated values, this can only happen when the map + // value is of a special type that renders a list in JSON. These can be one + // of 3 cases: + // i. We are rendering a list value within google.protobuf.Struct + // ii. We are rendering a list value within google.protobuf.Value + // iii. We are rendering a list value with type google.protobuf.ListValue. + if (current_->IsMap()) { + if (!ValidMapKey(name)) { + IncrementInvalidDepth(); + return this; + } + + // Start the repeated map entry object. + // Render + // { "key": "<name>", "value": { + Push("", Item::MESSAGE, false, false); + ProtoWriter::RenderDataPiece("key", + DataPiece(name, use_strict_base64_decoding())); + Push("value", Item::MESSAGE, true, false); + + // Make sure we are valid after pushing all above items. + if (invalid_depth() > 0) return this; + + // case i and ii above. Start "list_value" field within g.p.Value + if (element() != nullptr && element()->parent_field() != nullptr) { + // Render + // "list_value": { + // "values": [ // Start this list + if (IsStructValue(*element()->parent_field())) { + Push("list_value", Item::MESSAGE, true, false); + Push("values", Item::MESSAGE, true, true); + return this; + } + + // Render + // "values": [ + if (IsStructListValue(*element()->parent_field())) { + // case iii above. Bind directly to g.p.ListValue + Push("values", Item::MESSAGE, true, true); + return this; + } + } + + // Report an error. + InvalidValue("Map", StrCat("Cannot have repeated items ('", name, + "') within a map.")); + return this; + } + + // When name is empty and stack is not empty, we are rendering an item within + // a list. + if (name.empty()) { + if (element() != nullptr && element()->parent_field() != nullptr) { + if (IsStructValue(*element()->parent_field())) { + // Since it is g.p.Value, we bind directly to the list_value. + // Render + // { // g.p.Value item within the list + // "list_value": { + // "values": [ + Push("", Item::MESSAGE, false, false); + Push("list_value", Item::MESSAGE, true, false); + Push("values", Item::MESSAGE, true, true); + return this; + } + + if (IsStructListValue(*element()->parent_field())) { + // Since it is g.p.ListValue, we bind to it directly. + // Render + // { // g.p.ListValue item within the list + // "values": [ + Push("", Item::MESSAGE, false, false); + Push("values", Item::MESSAGE, true, true); + return this; + } + } + + // Pass the event to underlying ProtoWriter. + Push(name, Item::MESSAGE, false, true); + return this; + } + + // name is not empty + const google::protobuf::Field* field = Lookup(name); + + if (field == nullptr) { + IncrementInvalidDepth(); + return this; + } + + if (IsStructValue(*field)) { + // If g.p.Value is repeated, start that list. Otherwise, start the + // "list_value" within it. + if (IsRepeated(*field)) { + // Render it just like a regular repeated field. + // "<name>": [ + Push(name, Item::MESSAGE, false, true); + return this; + } + + // Start the "list_value" field. + // Render + // "<name>": { + // "list_value": { + // "values": [ + Push(name, Item::MESSAGE, false, false); + Push("list_value", Item::MESSAGE, true, false); + Push("values", Item::MESSAGE, true, true); + return this; + } + + if (IsStructListValue(*field)) { + // If g.p.ListValue is repeated, start that list. Otherwise, start the + // "values" within it. + if (IsRepeated(*field)) { + // Render it just like a regular repeated field. + // "<name>": [ + Push(name, Item::MESSAGE, false, true); + return this; + } + + // Start the "values" field within g.p.ListValue. + // Render + // "<name>": { + // "values": [ + Push(name, Item::MESSAGE, false, false); + Push("values", Item::MESSAGE, true, true); + return this; + } + + // If we are here, the field should be repeated. Report an error otherwise. + if (!IsRepeated(*field)) { + IncrementInvalidDepth(); + InvalidName(name, "Proto field is not repeating, cannot start list."); + return this; + } + + if (IsMap(*field)) { + if (options_.use_legacy_json_map_format) { + Push(name, Item::MESSAGE, false, true); + return this; + } + InvalidValue("Map", StrCat("Cannot bind a list to map for field '", + name, "'.")); + IncrementInvalidDepth(); + return this; + } + + // Pass the event to ProtoWriter. + // Render + // "<name>": [ + Push(name, Item::MESSAGE, false, true); + return this; +} + +ProtoStreamObjectWriter* ProtoStreamObjectWriter::EndList() { + if (invalid_depth() > 0) { + DecrementInvalidDepth(); + return this; + } + + if (current_ == nullptr) return this; + + if (current_->IsAny()) { + current_->any()->EndList(); + return this; + } + + Pop(); + return this; +} + +Status ProtoStreamObjectWriter::RenderStructValue(ProtoStreamObjectWriter* ow, + const DataPiece& data) { + TProtoStringType struct_field_name; + switch (data.type()) { + case DataPiece::TYPE_INT32: { + if (ow->options_.struct_integers_as_strings) { + util::StatusOr<arc_i32> int_value = data.ToInt32(); + if (int_value.ok()) { + ow->ProtoWriter::RenderDataPiece( + "string_value", + DataPiece(SimpleDtoa(int_value.value()), true)); + return Status(); + } + } + struct_field_name = "number_value"; + break; + } + case DataPiece::TYPE_UINT32: { + if (ow->options_.struct_integers_as_strings) { + util::StatusOr<arc_ui32> int_value = data.ToUint32(); + if (int_value.ok()) { + ow->ProtoWriter::RenderDataPiece( + "string_value", + DataPiece(SimpleDtoa(int_value.value()), true)); + return Status(); + } + } + struct_field_name = "number_value"; + break; + } + case DataPiece::TYPE_INT64: { + // If the option to treat integers as strings is set, then render them as + // strings. Otherwise, fallback to rendering them as double. + if (ow->options_.struct_integers_as_strings) { + util::StatusOr<arc_i64> int_value = data.ToInt64(); + if (int_value.ok()) { + ow->ProtoWriter::RenderDataPiece( + "string_value", DataPiece(StrCat(int_value.value()), true)); + return Status(); + } + } + struct_field_name = "number_value"; + break; + } + case DataPiece::TYPE_UINT64: { + // If the option to treat integers as strings is set, then render them as + // strings. Otherwise, fallback to rendering them as double. + if (ow->options_.struct_integers_as_strings) { + util::StatusOr<arc_ui64> int_value = data.ToUint64(); + if (int_value.ok()) { + ow->ProtoWriter::RenderDataPiece( + "string_value", DataPiece(StrCat(int_value.value()), true)); + return Status(); + } + } + struct_field_name = "number_value"; + break; + } + case DataPiece::TYPE_FLOAT: { + if (ow->options_.struct_integers_as_strings) { + util::StatusOr<float> float_value = data.ToFloat(); + if (float_value.ok()) { + ow->ProtoWriter::RenderDataPiece( + "string_value", + DataPiece(SimpleDtoa(float_value.value()), true)); + return Status(); + } + } + struct_field_name = "number_value"; + break; + } + case DataPiece::TYPE_DOUBLE: { + if (ow->options_.struct_integers_as_strings) { + util::StatusOr<double> double_value = data.ToDouble(); + if (double_value.ok()) { + ow->ProtoWriter::RenderDataPiece( + "string_value", + DataPiece(SimpleDtoa(double_value.value()), true)); + return Status(); + } + } + struct_field_name = "number_value"; + break; + } + case DataPiece::TYPE_STRING: { + struct_field_name = "string_value"; + break; + } + case DataPiece::TYPE_BOOL: { + struct_field_name = "bool_value"; + break; + } + case DataPiece::TYPE_NULL: { + struct_field_name = "null_value"; + break; + } + default: { + return util::InvalidArgumentError( + "Invalid struct data type. Only number, string, boolean or null " + "values are supported."); + } + } + ow->ProtoWriter::RenderDataPiece(struct_field_name, data); + return Status(); +} + +Status ProtoStreamObjectWriter::RenderTimestamp(ProtoStreamObjectWriter* ow, + const DataPiece& data) { + if (data.type() == DataPiece::TYPE_NULL) return Status(); + if (data.type() != DataPiece::TYPE_STRING) { + return util::InvalidArgumentError( + StrCat("Invalid data type for timestamp, value is ", + data.ValueAsStringOrDefault(""))); + } + + StringPiece value(data.str()); + + int64 seconds; + int32 nanos; + if (!::google::protobuf::internal::ParseTime(value.ToString(), &seconds, + &nanos)) { + return util::InvalidArgumentError(StrCat("Invalid time format: ", value)); + } + + + ow->ProtoWriter::RenderDataPiece("seconds", DataPiece(seconds)); + ow->ProtoWriter::RenderDataPiece("nanos", DataPiece(nanos)); + return Status(); +} + +static inline util::Status RenderOneFieldPath(ProtoStreamObjectWriter* ow, + StringPiece path) { + ow->ProtoWriter::RenderDataPiece( + "paths", DataPiece(ConvertFieldMaskPath(path, &ToSnakeCase), true)); + return Status(); +} + +Status ProtoStreamObjectWriter::RenderFieldMask(ProtoStreamObjectWriter* ow, + const DataPiece& data) { + if (data.type() == DataPiece::TYPE_NULL) return Status(); + if (data.type() != DataPiece::TYPE_STRING) { + return util::InvalidArgumentError( + StrCat("Invalid data type for field mask, value is ", + data.ValueAsStringOrDefault(""))); + } + + // TODO(tsun): figure out how to do proto descriptor based snake case + // conversions as much as possible. Because ToSnakeCase sometimes returns the + // wrong value. + return DecodeCompactFieldMaskPaths(data.str(), + std::bind(&RenderOneFieldPath, ow, _1)); +} + +Status ProtoStreamObjectWriter::RenderDuration(ProtoStreamObjectWriter* ow, + const DataPiece& data) { + if (data.type() == DataPiece::TYPE_NULL) return Status(); + if (data.type() != DataPiece::TYPE_STRING) { + return util::InvalidArgumentError( + StrCat("Invalid data type for duration, value is ", + data.ValueAsStringOrDefault(""))); + } + + StringPiece value(data.str()); + + if (!HasSuffixString(value, "s")) { + return util::InvalidArgumentError( + "Illegal duration format; duration must end with 's'"); + } + value = value.substr(0, value.size() - 1); + int sign = 1; + if (HasPrefixString(value, "-")) { + sign = -1; + value = value.substr(1); + } + + StringPiece s_secs, s_nanos; + SplitSecondsAndNanos(value, &s_secs, &s_nanos); + arc_ui64 unsigned_seconds; + if (!safe_strtou64(s_secs, &unsigned_seconds)) { + return util::InvalidArgumentError( + "Invalid duration format, failed to parse seconds"); + } + + arc_i32 nanos = 0; + Status nanos_status = GetNanosFromStringPiece( + s_nanos, "Invalid duration format, failed to parse nano seconds", + "Duration value exceeds limits", &nanos); + if (!nanos_status.ok()) { + return nanos_status; + } + nanos = sign * nanos; + + arc_i64 seconds = sign * unsigned_seconds; + if (seconds > kDurationMaxSeconds || seconds < kDurationMinSeconds || + nanos <= -kNanosPerSecond || nanos >= kNanosPerSecond) { + return util::InvalidArgumentError("Duration value exceeds limits"); + } + + ow->ProtoWriter::RenderDataPiece("seconds", DataPiece(seconds)); + ow->ProtoWriter::RenderDataPiece("nanos", DataPiece(nanos)); + return Status(); +} + +Status ProtoStreamObjectWriter::RenderWrapperType(ProtoStreamObjectWriter* ow, + const DataPiece& data) { + if (data.type() == DataPiece::TYPE_NULL) return Status(); + ow->ProtoWriter::RenderDataPiece("value", data); + return Status(); +} + +ProtoStreamObjectWriter* ProtoStreamObjectWriter::RenderDataPiece( + StringPiece name, const DataPiece& data) { + Status status; + if (invalid_depth() > 0) return this; + + if (current_ == nullptr) { + const TypeRenderer* type_renderer = + FindTypeRenderer(GetFullTypeWithUrl(master_type_.name())); + if (type_renderer == nullptr) { + InvalidName(name, "Root element must be a message."); + return this; + } + // Render the special type. + // "<name>": { + // ... Render special type ... + // } + ProtoWriter::StartObject(name); + status = (*type_renderer)(this, data); + if (!status.ok()) { + InvalidValue(master_type_.name(), + StrCat("Field '", name, "', ", status.message())); + } + ProtoWriter::EndObject(); + return this; + } + + if (current_->IsAny()) { + current_->any()->RenderDataPiece(name, data); + return this; + } + + const google::protobuf::Field* field = nullptr; + if (current_->IsMap()) { + if (!ValidMapKey(name)) return this; + + field = Lookup("value"); + if (field == nullptr) { + GOOGLE_LOG(DFATAL) << "Map does not have a value field."; + return this; + } + + if (options_.ignore_null_value_map_entry) { + // If we are rendering explicit null values and the backend proto field is + // not of the google.protobuf.NullType type, interpret null as absence. + if (data.type() == DataPiece::TYPE_NULL && + field->type_url() != kStructNullValueTypeUrl) { + return this; + } + } + + // Render an item in repeated map list. + // { "key": "<name>", "value": + Push("", Item::MESSAGE, false, false); + ProtoWriter::RenderDataPiece("key", + DataPiece(name, use_strict_base64_decoding())); + + const TypeRenderer* type_renderer = FindTypeRenderer(field->type_url()); + if (type_renderer != nullptr) { + // Map's value type is a special type. Render it like a message: + // "value": { + // ... Render special type ... + // } + Push("value", Item::MESSAGE, true, false); + status = (*type_renderer)(this, data); + if (!status.ok()) { + InvalidValue(field->type_url(), + StrCat("Field '", name, "', ", status.message())); + } + Pop(); + return this; + } + + // If we are rendering explicit null values and the backend proto field is + // not of the google.protobuf.NullType type, we do nothing. + if (data.type() == DataPiece::TYPE_NULL && + field->type_url() != kStructNullValueTypeUrl) { + Pop(); + return this; + } + + // Render the map value as a primitive type. + ProtoWriter::RenderDataPiece("value", data); + Pop(); + return this; + } + + field = Lookup(name); + if (field == nullptr) return this; + + // Check if the field is of special type. Render it accordingly if so. + const TypeRenderer* type_renderer = FindTypeRenderer(field->type_url()); + if (type_renderer != nullptr) { + // Pass through null value only for google.protobuf.Value. For other + // types we ignore null value just like for regular field types. + if (data.type() != DataPiece::TYPE_NULL || + field->type_url() == kStructValueTypeUrl) { + Push(name, Item::MESSAGE, false, false); + status = (*type_renderer)(this, data); + if (!status.ok()) { + InvalidValue(field->type_url(), + StrCat("Field '", name, "', ", status.message())); + } + Pop(); + } + return this; + } + + // If we are rendering explicit null values and the backend proto field is + // not of the google.protobuf.NullType type, we do nothing. + if (data.type() == DataPiece::TYPE_NULL && + field->type_url() != kStructNullValueTypeUrl) { + return this; + } + + if (IsRepeated(*field) && !current_->is_list()) { + if (options_.disable_implicit_scalar_list) { + if (!options_.suppress_implicit_scalar_list_error) { + InvalidValue( + field->name(), + "Starting an primitive in a repeated field but the parent field " + "is not a list"); + } + + return this; + } + } + + ProtoWriter::RenderDataPiece(name, data); + return this; +} + +// Map of functions that are responsible for rendering well known type +// represented by the key. +std::unordered_map<TProtoStringType, ProtoStreamObjectWriter::TypeRenderer>* + ProtoStreamObjectWriter::renderers_ = nullptr; +PROTOBUF_NAMESPACE_ID::internal::once_flag writer_renderers_init_; + +void ProtoStreamObjectWriter::InitRendererMap() { + renderers_ = new std::unordered_map<TProtoStringType, + ProtoStreamObjectWriter::TypeRenderer>(); + (*renderers_)["type.googleapis.com/google.protobuf.Timestamp"] = + &ProtoStreamObjectWriter::RenderTimestamp; + (*renderers_)["type.googleapis.com/google.protobuf.Duration"] = + &ProtoStreamObjectWriter::RenderDuration; + (*renderers_)["type.googleapis.com/google.protobuf.FieldMask"] = + &ProtoStreamObjectWriter::RenderFieldMask; + (*renderers_)["type.googleapis.com/google.protobuf.Double"] = + &ProtoStreamObjectWriter::RenderWrapperType; + (*renderers_)["type.googleapis.com/google.protobuf.Float"] = + &ProtoStreamObjectWriter::RenderWrapperType; + (*renderers_)["type.googleapis.com/google.protobuf.Int64"] = + &ProtoStreamObjectWriter::RenderWrapperType; + (*renderers_)["type.googleapis.com/google.protobuf.UInt64"] = + &ProtoStreamObjectWriter::RenderWrapperType; + (*renderers_)["type.googleapis.com/google.protobuf.Int32"] = + &ProtoStreamObjectWriter::RenderWrapperType; + (*renderers_)["type.googleapis.com/google.protobuf.UInt32"] = + &ProtoStreamObjectWriter::RenderWrapperType; + (*renderers_)["type.googleapis.com/google.protobuf.Bool"] = + &ProtoStreamObjectWriter::RenderWrapperType; + (*renderers_)["type.googleapis.com/google.protobuf.String"] = + &ProtoStreamObjectWriter::RenderWrapperType; + (*renderers_)["type.googleapis.com/google.protobuf.Bytes"] = + &ProtoStreamObjectWriter::RenderWrapperType; + (*renderers_)["type.googleapis.com/google.protobuf.DoubleValue"] = + &ProtoStreamObjectWriter::RenderWrapperType; + (*renderers_)["type.googleapis.com/google.protobuf.FloatValue"] = + &ProtoStreamObjectWriter::RenderWrapperType; + (*renderers_)["type.googleapis.com/google.protobuf.Int64Value"] = + &ProtoStreamObjectWriter::RenderWrapperType; + (*renderers_)["type.googleapis.com/google.protobuf.UInt64Value"] = + &ProtoStreamObjectWriter::RenderWrapperType; + (*renderers_)["type.googleapis.com/google.protobuf.Int32Value"] = + &ProtoStreamObjectWriter::RenderWrapperType; + (*renderers_)["type.googleapis.com/google.protobuf.UInt32Value"] = + &ProtoStreamObjectWriter::RenderWrapperType; + (*renderers_)["type.googleapis.com/google.protobuf.BoolValue"] = + &ProtoStreamObjectWriter::RenderWrapperType; + (*renderers_)["type.googleapis.com/google.protobuf.StringValue"] = + &ProtoStreamObjectWriter::RenderWrapperType; + (*renderers_)["type.googleapis.com/google.protobuf.BytesValue"] = + &ProtoStreamObjectWriter::RenderWrapperType; + (*renderers_)["type.googleapis.com/google.protobuf.Value"] = + &ProtoStreamObjectWriter::RenderStructValue; + ::google::protobuf::internal::OnShutdown(&DeleteRendererMap); +} + +void ProtoStreamObjectWriter::DeleteRendererMap() { + delete ProtoStreamObjectWriter::renderers_; + renderers_ = nullptr; +} + +ProtoStreamObjectWriter::TypeRenderer* +ProtoStreamObjectWriter::FindTypeRenderer(const TProtoStringType& type_url) { + PROTOBUF_NAMESPACE_ID::internal::call_once(writer_renderers_init_, + InitRendererMap); + return FindOrNull(*renderers_, type_url); +} + +bool ProtoStreamObjectWriter::ValidMapKey(StringPiece unnormalized_name) { + if (current_ == nullptr) return true; + + if (!current_->InsertMapKeyIfNotPresent(unnormalized_name)) { + listener()->InvalidName( + location(), unnormalized_name, + StrCat("Repeated map key: '", unnormalized_name, + "' is already set.")); + return false; + } + + return true; +} + +void ProtoStreamObjectWriter::Push( + StringPiece name, Item::ItemType item_type, bool is_placeholder, + bool is_list) { + is_list ? ProtoWriter::StartList(name) : ProtoWriter::StartObject(name); + + // invalid_depth == 0 means it is a successful StartObject or StartList. + if (invalid_depth() == 0) + current_.reset( + new Item(current_.release(), item_type, is_placeholder, is_list)); +} + +void ProtoStreamObjectWriter::Pop() { + // Pop all placeholder items sending StartObject or StartList events to + // ProtoWriter according to is_list value. + while (current_ != nullptr && current_->is_placeholder()) { + PopOneElement(); + } + if (current_ != nullptr) { + PopOneElement(); + } +} + +void ProtoStreamObjectWriter::PopOneElement() { + current_->is_list() ? ProtoWriter::EndList() : ProtoWriter::EndObject(); + current_.reset(current_->pop<Item>()); +} + +bool ProtoStreamObjectWriter::IsMap(const google::protobuf::Field& field) { + if (field.type_url().empty() || + field.kind() != google::protobuf::Field::TYPE_MESSAGE || + field.cardinality() != google::protobuf::Field::CARDINALITY_REPEATED) { + return false; + } + const google::protobuf::Type* field_type = + typeinfo()->GetTypeByTypeUrl(field.type_url()); + + return converter::IsMap(field, *field_type); +} + +bool ProtoStreamObjectWriter::IsAny(const google::protobuf::Field& field) { + return GetTypeWithoutUrl(field.type_url()) == kAnyType; +} + +bool ProtoStreamObjectWriter::IsStruct(const google::protobuf::Field& field) { + return GetTypeWithoutUrl(field.type_url()) == kStructType; +} + +bool ProtoStreamObjectWriter::IsStructValue( + const google::protobuf::Field& field) { + return GetTypeWithoutUrl(field.type_url()) == kStructValueType; +} + +bool ProtoStreamObjectWriter::IsStructListValue( + const google::protobuf::Field& field) { + return GetTypeWithoutUrl(field.type_url()) == kStructListValueType; +} + +} // namespace converter +} // namespace util +} // namespace protobuf +} // namespace google diff --git a/contrib/libs/protobuf_old/src/google/protobuf/util/internal/protostream_objectwriter.h b/contrib/libs/protobuf_old/src/google/protobuf/util/internal/protostream_objectwriter.h new file mode 100644 index 0000000000..d70fa425ea --- /dev/null +++ b/contrib/libs/protobuf_old/src/google/protobuf/util/internal/protostream_objectwriter.h @@ -0,0 +1,452 @@ +// 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_UTIL_CONVERTER_PROTOSTREAM_OBJECTWRITER_H__ +#define GOOGLE_PROTOBUF_UTIL_CONVERTER_PROTOSTREAM_OBJECTWRITER_H__ + +#include <deque> +#include <string> +#include <unordered_map> +#include <unordered_set> + +#include <google/protobuf/stubs/common.h> +#include <google/protobuf/type.pb.h> +#include <google/protobuf/io/coded_stream.h> +#include <google/protobuf/io/zero_copy_stream_impl.h> +#include <google/protobuf/descriptor.h> +#include <google/protobuf/util/internal/type_info.h> +#include <google/protobuf/util/internal/datapiece.h> +#include <google/protobuf/util/internal/error_listener.h> +#include <google/protobuf/util/internal/proto_writer.h> +#include <google/protobuf/util/internal/structured_objectwriter.h> +#include <google/protobuf/util/type_resolver.h> +#include <google/protobuf/stubs/bytestream.h> +#include <google/protobuf/stubs/status.h> +#include <google/protobuf/stubs/hash.h> + +#include <google/protobuf/port_def.inc> + +namespace google { +namespace protobuf { +namespace util { +namespace converter { + +class ObjectLocationTracker; + +// An ObjectWriter that can write protobuf bytes directly from writer events. +// This class supports all special types like Struct and Map. It uses +// the ProtoWriter class to write raw proto bytes. +// +// It also supports streaming. +class PROTOBUF_EXPORT ProtoStreamObjectWriter : public ProtoWriter { + public: + // Options that control ProtoStreamObjectWriter class's behavior. + struct Options { + // Treats numeric inputs in google.protobuf.Struct as strings. Normally, + // numeric values are returned in double field "number_value" of + // google.protobuf.Struct. However, this can cause precision loss for + // int64/uint64/double inputs. This option is provided for cases that want + // to preserve number precision. + // + // TODO(skarvaje): Rename to struct_numbers_as_strings as it covers double + // as well. + bool struct_integers_as_strings; + + // Not treat unknown fields as an error. If there is an unknown fields, + // just ignore it and continue to process the rest. Note that this doesn't + // apply to unknown enum values. + bool ignore_unknown_fields; + + // Ignore unknown enum values. + bool ignore_unknown_enum_values; + + // If true, check if enum name in camel case or without underscore matches + // the field name. + bool use_lower_camel_for_enums; + + // If true, check if enum name in UPPER_CASE matches the field name. + bool case_insensitive_enum_parsing; + + // If true, skips rendering the map entry if map value is null unless the + // value type is google.protobuf.NullType. + bool ignore_null_value_map_entry; + + // If true, accepts repeated key/value pair for a map proto field. + bool use_legacy_json_map_format; + + // If true, disable implicitly creating message list. + bool disable_implicit_message_list; + + // If true, suppress the error of implicitly creating message list when it + // is disabled. + bool suppress_implicit_message_list_error; + + // If true, disable implicitly creating scalar list. + bool disable_implicit_scalar_list; + + // If true, suppress the error of implicitly creating scalar list when it + // is disabled. + bool suppress_implicit_scalar_list_error; + + // If true, suppress the error of rendering scalar field if the source is an + // object. + bool suppress_object_to_scalar_error; + + // If true, use the json name in missing fields errors. + bool use_json_name_in_missing_fields; + + Options() + : struct_integers_as_strings(false), + ignore_unknown_fields(false), + ignore_unknown_enum_values(false), + use_lower_camel_for_enums(false), + case_insensitive_enum_parsing(false), + ignore_null_value_map_entry(false), + use_legacy_json_map_format(false), + disable_implicit_message_list(false), + suppress_implicit_message_list_error(false), + disable_implicit_scalar_list(false), + suppress_implicit_scalar_list_error(false), + suppress_object_to_scalar_error(false), + use_json_name_in_missing_fields(false) {} + + // Default instance of Options with all options set to defaults. + static const Options& Defaults() { + static Options defaults; + return defaults; + } + }; + + // Constructor. Does not take ownership of any parameter passed in. + ProtoStreamObjectWriter(TypeResolver* type_resolver, + const google::protobuf::Type& type, + strings::ByteSink* output, ErrorListener* listener, + const ProtoStreamObjectWriter::Options& options = + ProtoStreamObjectWriter::Options::Defaults()); + ~ProtoStreamObjectWriter() override; + + // ObjectWriter methods. + ProtoStreamObjectWriter* StartObject(StringPiece name) override; + ProtoStreamObjectWriter* EndObject() override; + ProtoStreamObjectWriter* StartList(StringPiece name) override; + ProtoStreamObjectWriter* EndList() override; + + // Renders a DataPiece 'value' into a field whose wire type is determined + // from the given field 'name'. + ProtoStreamObjectWriter* RenderDataPiece(StringPiece name, + const DataPiece& data) override; + + protected: + // Function that renders a well known type with modified behavior. + typedef util::Status (*TypeRenderer)(ProtoStreamObjectWriter*, + const DataPiece&); + + // Handles writing Anys out using nested object writers and the like. + class PROTOBUF_EXPORT AnyWriter { + public: + explicit AnyWriter(ProtoStreamObjectWriter* parent); + ~AnyWriter(); + + // Passes a StartObject call through to the Any writer. + void StartObject(StringPiece name); + + // Passes an EndObject call through to the Any. Returns true if the any + // handled the EndObject call, false if the Any is now all done and is no + // longer needed. + bool EndObject(); + + // Passes a StartList call through to the Any writer. + void StartList(StringPiece name); + + // Passes an EndList call through to the Any writer. + void EndList(); + + // Renders a data piece on the any. + void RenderDataPiece(StringPiece name, const DataPiece& value); + + private: + // Before the "@type" field is encountered, we store all incoming data + // into this Event struct and replay them after we get the "@type" field. + class PROTOBUF_EXPORT Event { + public: + enum Type { + START_OBJECT = 0, + END_OBJECT = 1, + START_LIST = 2, + END_LIST = 3, + RENDER_DATA_PIECE = 4, + }; + + // Constructor for END_OBJECT and END_LIST events. + explicit Event(Type type) : type_(type), value_(DataPiece::NullData()) {} + + // Constructor for START_OBJECT and START_LIST events. + explicit Event(Type type, StringPiece name) + : type_(type), name_(name), value_(DataPiece::NullData()) {} + + // Constructor for RENDER_DATA_PIECE events. + explicit Event(StringPiece name, const DataPiece& value) + : type_(RENDER_DATA_PIECE), name_(name), value_(value) { + DeepCopy(); + } + + Event(const Event& other) + : type_(other.type_), name_(other.name_), value_(other.value_) { + DeepCopy(); + } + + Event& operator=(const Event& other) { + type_ = other.type_; + name_ = other.name_; + value_ = other.value_; + DeepCopy(); + return *this; + } + + void Replay(AnyWriter* writer) const; + + private: + void DeepCopy(); + + Type type_; + TProtoStringType name_; + DataPiece value_; + TProtoStringType value_storage_; + }; + + // Handles starting up the any once we have a type. + void StartAny(const DataPiece& value); + + // Writes the Any out to the parent writer in its serialized form. + void WriteAny(); + + // The parent of this writer, needed for various bits such as type info and + // the listeners. + ProtoStreamObjectWriter* parent_; + + // The nested object writer, used to write events. + std::unique_ptr<ProtoStreamObjectWriter> ow_; + + // The type_url_ that this Any represents. + TProtoStringType type_url_; + + // Whether this any is invalid. This allows us to only report an invalid + // Any message a single time rather than every time we get a nested field. + bool invalid_; + + // The output data and wrapping ByteSink. + TProtoStringType data_; + strings::StringByteSink output_; + + // The depth within the Any, so we can track when we're done. + int depth_; + + // True if the type is a well-known type. Well-known types in Any + // has a special formatting: + // { + // "@type": "type.googleapis.com/google.protobuf.XXX", + // "value": <JSON representation of the type>, + // } + bool is_well_known_type_; + TypeRenderer* well_known_type_render_; + + // Store data before the "@type" field. + std::vector<Event> uninterpreted_events_; + }; + + // Represents an item in a stack of items used to keep state between + // ObjectWrier events. + class PROTOBUF_EXPORT Item : public BaseElement { + public: + // Indicates the type of item. + enum ItemType { + MESSAGE, // Simple message + MAP, // Proto3 map type + ANY, // Proto3 Any type + }; + + // Constructor for the root item. + Item(ProtoStreamObjectWriter* enclosing, ItemType item_type, + bool is_placeholder, bool is_list); + + // Constructor for a field of a message. + Item(Item* parent, ItemType item_type, bool is_placeholder, bool is_list); + + ~Item() override {} + + // These functions return true if the element type is corresponding to the + // type in function name. + bool IsMap() { return item_type_ == MAP; } + bool IsAny() { return item_type_ == ANY; } + + AnyWriter* any() const { return any_.get(); } + + Item* parent() const override { + return static_cast<Item*>(BaseElement::parent()); + } + + // Inserts map key into hash set if and only if the key did NOT already + // exist in hash set. + // The hash set (map_keys_) is ONLY used to keep track of map keys. + // Return true if insert successfully; returns false if the map key was + // already present. + bool InsertMapKeyIfNotPresent(StringPiece map_key); + + bool is_placeholder() const { return is_placeholder_; } + bool is_list() const { return is_list_; } + + private: + // Used for access to variables of the enclosing instance of + // ProtoStreamObjectWriter. + ProtoStreamObjectWriter* ow_; + + // A writer for Any objects, handles all Any-related nonsense. + std::unique_ptr<AnyWriter> any_; + + // The type of this element, see enum for permissible types. + ItemType item_type_; + + // Set of map keys already seen for the type_. Used to validate incoming + // messages so no map key appears more than once. + std::unique_ptr<std::unordered_set<TProtoStringType> > map_keys_; + + // Conveys whether this Item is a placeholder or not. Placeholder items are + // pushed to stack to account for special types. + bool is_placeholder_; + + // Conveys whether this Item is a list or not. This is used to send + // StartList or EndList calls to underlying ObjectWriter. + bool is_list_; + + GOOGLE_DISALLOW_IMPLICIT_CONSTRUCTORS(Item); + }; + + ProtoStreamObjectWriter(const TypeInfo* typeinfo, + const google::protobuf::Type& type, + strings::ByteSink* output, ErrorListener* listener); + + ProtoStreamObjectWriter(const TypeInfo* typeinfo, + const google::protobuf::Type& type, + strings::ByteSink* output, ErrorListener* listener, + const ProtoStreamObjectWriter::Options& options); + + // Returns true if the field is a map. + inline bool IsMap(const google::protobuf::Field& field); + + // Returns true if the field is an any. + inline bool IsAny(const google::protobuf::Field& field); + + // Returns true if the field is google.protobuf.Struct. + inline bool IsStruct(const google::protobuf::Field& field); + + // Returns true if the field is google.protobuf.Value. + inline bool IsStructValue(const google::protobuf::Field& field); + + // Returns true if the field is google.protobuf.ListValue. + inline bool IsStructListValue(const google::protobuf::Field& field); + + // Renders google.protobuf.Value in struct.proto. It picks the right oneof + // type based on value's type. + static util::Status RenderStructValue(ProtoStreamObjectWriter* ow, + const DataPiece& data); + + // Renders google.protobuf.Timestamp value. + static util::Status RenderTimestamp(ProtoStreamObjectWriter* ow, + const DataPiece& data); + + // Renders google.protobuf.FieldMask value. + static util::Status RenderFieldMask(ProtoStreamObjectWriter* ow, + const DataPiece& data); + + // Renders google.protobuf.Duration value. + static util::Status RenderDuration(ProtoStreamObjectWriter* ow, + const DataPiece& data); + + // Renders wrapper message types for primitive types in + // google/protobuf/wrappers.proto. + static util::Status RenderWrapperType(ProtoStreamObjectWriter* ow, + const DataPiece& data); + + static void InitRendererMap(); + static void DeleteRendererMap(); + static TypeRenderer* FindTypeRenderer(const TProtoStringType& type_url); + + // Returns true if the map key for type_ is not duplicated key. + // If map key is duplicated key, this function returns false. + // Note that caller should make sure that the current proto element (current_) + // is of element type MAP or STRUCT_MAP. + // It also calls the appropriate error callback and unnormalzied_name is used + // for error string. + bool ValidMapKey(StringPiece unnormalized_name); + + // Pushes an item on to the stack. Also calls either StartObject or StartList + // on the underlying ObjectWriter depending on whether is_list is false or + // not. + // is_placeholder conveys whether the item is a placeholder item or not. + // Placeholder items are pushed when adding auxiliary types' StartObject or + // StartList calls. + void Push(StringPiece name, Item::ItemType item_type, + bool is_placeholder, bool is_list); + + + // Pops items from the stack. All placeholder items are popped until a + // non-placeholder item is found. + void Pop(); + + // Pops one element from the stack. Calls EndObject() or EndList() on the + // underlying ObjectWriter depending on the value of is_list_. + void PopOneElement(); + + private: + // Helper functions to create the map and find functions responsible for + // rendering well known types, keyed by type URL. + static std::unordered_map<TProtoStringType, TypeRenderer>* renderers_; + + // Variables for describing the structure of the input tree: + // master_type_: descriptor for the whole protobuf message. + const google::protobuf::Type& master_type_; + + // The current element, variable for internal state processing. + std::unique_ptr<Item> current_; + + // Reference to the options that control this class's behavior. + const ProtoStreamObjectWriter::Options options_; + + GOOGLE_DISALLOW_IMPLICIT_CONSTRUCTORS(ProtoStreamObjectWriter); +}; + +} // namespace converter +} // namespace util +} // namespace protobuf +} // namespace google + +#include <google/protobuf/port_undef.inc> + +#endif // GOOGLE_PROTOBUF_UTIL_CONVERTER_PROTOSTREAM_OBJECTWRITER_H__ diff --git a/contrib/libs/protobuf_old/src/google/protobuf/util/internal/structured_objectwriter.h b/contrib/libs/protobuf_old/src/google/protobuf/util/internal/structured_objectwriter.h new file mode 100644 index 0000000000..01cbb9e1ac --- /dev/null +++ b/contrib/libs/protobuf_old/src/google/protobuf/util/internal/structured_objectwriter.h @@ -0,0 +1,120 @@ +// 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_UTIL_CONVERTER_STRUCTURED_OBJECTWRITER_H__ +#define GOOGLE_PROTOBUF_UTIL_CONVERTER_STRUCTURED_OBJECTWRITER_H__ + +#include <memory> + +#include <google/protobuf/stubs/casts.h> +#include <google/protobuf/stubs/common.h> +#include <google/protobuf/util/internal/object_writer.h> + +#include <google/protobuf/port_def.inc> + +namespace google { +namespace protobuf { +namespace util { +namespace converter { + +// An StructuredObjectWriter is an ObjectWriter for writing +// tree-structured data in a stream of events representing objects +// and collections. Implementation of this interface can be used to +// write an object stream to an in-memory structure, protobufs, +// JSON, XML, or any other output format desired. The ObjectSource +// interface is typically used as the source of an object stream. +// +// See JsonObjectWriter for a sample implementation of +// StructuredObjectWriter and its use. +// +// Derived classes could be thread-unsafe. +class PROTOBUF_EXPORT StructuredObjectWriter : public ObjectWriter { + public: + virtual ~StructuredObjectWriter() {} + + protected: + // A base element class for subclasses to extend, makes tracking state easier. + // + // StructuredObjectWriter behaves as a visitor. BaseElement represents a node + // in the input tree. Implementation of StructuredObjectWriter should also + // extend BaseElement to keep track of the location in the input tree. + class PROTOBUF_EXPORT BaseElement { + public: + // Takes ownership of the parent Element. + explicit BaseElement(BaseElement* parent) + : parent_(parent), + level_(parent == nullptr ? 0 : parent->level() + 1) {} + virtual ~BaseElement() {} + + // Releases ownership of the parent and returns a pointer to it. + template <typename ElementType> + ElementType* pop() { + return down_cast<ElementType*>(parent_.release()); + } + + // Returns true if this element is the root. + bool is_root() const { return parent_ == nullptr; } + + // Returns the number of hops from this element to the root element. + int level() const { return level_; } + + protected: + // Returns pointer to parent element without releasing ownership. + virtual BaseElement* parent() const { return parent_.get(); } + + private: + // Pointer to the parent Element. + std::unique_ptr<BaseElement> parent_; + + // Number of hops to the root Element. + // The root Element has nullptr parent_ and a level_ of 0. + const int level_; + + GOOGLE_DISALLOW_IMPLICIT_CONSTRUCTORS(BaseElement); + }; + + StructuredObjectWriter() {} + + // Returns the current element. Used for indentation and name overrides. + virtual BaseElement* element() = 0; + + private: + // Do not add any data members to this class. + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(StructuredObjectWriter); +}; + +} // namespace converter +} // namespace util +} // namespace protobuf +} // namespace google + +#include <google/protobuf/port_undef.inc> + +#endif // GOOGLE_PROTOBUF_UTIL_CONVERTER_STRUCTURED_OBJECTWRITER_H__ diff --git a/contrib/libs/protobuf_old/src/google/protobuf/util/internal/type_info.cc b/contrib/libs/protobuf_old/src/google/protobuf/util/internal/type_info.cc new file mode 100644 index 0000000000..6a4ea2a768 --- /dev/null +++ b/contrib/libs/protobuf_old/src/google/protobuf/util/internal/type_info.cc @@ -0,0 +1,182 @@ +// 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 <google/protobuf/util/internal/type_info.h> + +#include <map> +#include <set> + +#include <google/protobuf/stubs/common.h> +#include <google/protobuf/type.pb.h> +#include <google/protobuf/util/internal/utility.h> +#include <google/protobuf/stubs/status.h> +#include <google/protobuf/stubs/statusor.h> +#include <google/protobuf/stubs/strutil.h> +#include <google/protobuf/stubs/map_util.h> +#include <google/protobuf/stubs/status.h> + +namespace google { +namespace protobuf { +namespace util { +namespace converter { + +namespace { +// A TypeInfo that looks up information provided by a TypeResolver. +class TypeInfoForTypeResolver : public TypeInfo { + public: + explicit TypeInfoForTypeResolver(TypeResolver* type_resolver) + : type_resolver_(type_resolver) {} + + virtual ~TypeInfoForTypeResolver() { + DeleteCachedTypes(&cached_types_); + DeleteCachedTypes(&cached_enums_); + } + + util::StatusOr<const google::protobuf::Type*> ResolveTypeUrl( + StringPiece type_url) const override { + std::map<StringPiece, StatusOrType>::iterator it = + cached_types_.find(type_url); + if (it != cached_types_.end()) { + return it->second; + } + // Stores the string value so it can be referenced using StringPiece in the + // cached_types_ map. + const TProtoStringType& string_type_url = + *string_storage_.insert(TProtoStringType(type_url)).first; + std::unique_ptr<google::protobuf::Type> type(new google::protobuf::Type()); + util::Status status = + type_resolver_->ResolveMessageType(string_type_url, type.get()); + StatusOrType result = + status.ok() ? StatusOrType(type.release()) : StatusOrType(status); + cached_types_[string_type_url] = result; + return result; + } + + const google::protobuf::Type* GetTypeByTypeUrl( + StringPiece type_url) const override { + StatusOrType result = ResolveTypeUrl(type_url); + return result.ok() ? result.value() : NULL; + } + + const google::protobuf::Enum* GetEnumByTypeUrl( + StringPiece type_url) const override { + std::map<StringPiece, StatusOrEnum>::iterator it = + cached_enums_.find(type_url); + if (it != cached_enums_.end()) { + return it->second.ok() ? it->second.value() : NULL; + } + // Stores the string value so it can be referenced using StringPiece in the + // cached_enums_ map. + const TProtoStringType& string_type_url = + *string_storage_.insert(TProtoStringType(type_url)).first; + std::unique_ptr<google::protobuf::Enum> enum_type( + new google::protobuf::Enum()); + util::Status status = + type_resolver_->ResolveEnumType(string_type_url, enum_type.get()); + StatusOrEnum result = + status.ok() ? StatusOrEnum(enum_type.release()) : StatusOrEnum(status); + cached_enums_[string_type_url] = result; + return result.ok() ? result.value() : NULL; + } + + const google::protobuf::Field* FindField( + const google::protobuf::Type* type, + StringPiece camel_case_name) const override { + std::map<const google::protobuf::Type*, CamelCaseNameTable>::const_iterator + it = indexed_types_.find(type); + const CamelCaseNameTable& camel_case_name_table = + (it == indexed_types_.end()) + ? PopulateNameLookupTable(type, &indexed_types_[type]) + : it->second; + StringPiece name = FindWithDefault( + camel_case_name_table, camel_case_name, StringPiece()); + if (name.empty()) { + // Didn't find a mapping. Use whatever provided. + name = camel_case_name; + } + return FindFieldInTypeOrNull(type, name); + } + + private: + typedef util::StatusOr<const google::protobuf::Type*> StatusOrType; + typedef util::StatusOr<const google::protobuf::Enum*> StatusOrEnum; + typedef std::map<StringPiece, StringPiece> CamelCaseNameTable; + + template <typename T> + static void DeleteCachedTypes(std::map<StringPiece, T>* cached_types) { + for (typename std::map<StringPiece, T>::iterator it = + cached_types->begin(); + it != cached_types->end(); ++it) { + if (it->second.ok()) { + delete it->second.value(); + } + } + } + + const CamelCaseNameTable& PopulateNameLookupTable( + const google::protobuf::Type* type, + CamelCaseNameTable* camel_case_name_table) const { + for (int i = 0; i < type->fields_size(); ++i) { + const google::protobuf::Field& field = type->fields(i); + StringPiece name = field.name(); + StringPiece camel_case_name = field.json_name(); + const StringPiece* existing = InsertOrReturnExisting( + camel_case_name_table, camel_case_name, name); + if (existing && *existing != name) { + GOOGLE_LOG(WARNING) << "Field '" << name << "' and '" << *existing + << "' map to the same camel case name '" << camel_case_name + << "'."; + } + } + return *camel_case_name_table; + } + + TypeResolver* type_resolver_; + + // Stores string values that will be referenced by StringPieces in + // cached_types_, cached_enums_. + mutable std::set<TProtoStringType> string_storage_; + + mutable std::map<StringPiece, StatusOrType> cached_types_; + mutable std::map<StringPiece, StatusOrEnum> cached_enums_; + + mutable std::map<const google::protobuf::Type*, CamelCaseNameTable> + indexed_types_; +}; +} // namespace + +TypeInfo* TypeInfo::NewTypeInfo(TypeResolver* type_resolver) { + return new TypeInfoForTypeResolver(type_resolver); +} + +} // namespace converter +} // namespace util +} // namespace protobuf +} // namespace google diff --git a/contrib/libs/protobuf_old/src/google/protobuf/util/internal/type_info.h b/contrib/libs/protobuf_old/src/google/protobuf/util/internal/type_info.h new file mode 100644 index 0000000000..d8d679e1fe --- /dev/null +++ b/contrib/libs/protobuf_old/src/google/protobuf/util/internal/type_info.h @@ -0,0 +1,97 @@ +// 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_UTIL_CONVERTER_TYPE_INFO_H__ +#define GOOGLE_PROTOBUF_UTIL_CONVERTER_TYPE_INFO_H__ + +#include <google/protobuf/stubs/common.h> +#include <google/protobuf/type.pb.h> +#include <google/protobuf/util/type_resolver.h> +#include <google/protobuf/stubs/statusor.h> +#include <google/protobuf/stubs/strutil.h> +#include <google/protobuf/stubs/status.h> + +// Must be included last. +#include <google/protobuf/port_def.inc> + +namespace google { +namespace protobuf { +namespace util { +namespace converter { +// Internal helper class for type resolving. Note that this class is not +// thread-safe and should only be accessed in one thread. +class PROTOBUF_EXPORT TypeInfo { + public: + TypeInfo() {} + virtual ~TypeInfo() {} + + // Resolves a type url into a Type. If the type url is invalid, returns + // INVALID_ARGUMENT error status. If the type url is valid but the + // corresponding type cannot be found, returns a NOT_FOUND error status. + // + // This TypeInfo class retains the ownership of the returned pointer. + virtual util::StatusOr<const google::protobuf::Type*> ResolveTypeUrl( + StringPiece type_url) const = 0; + + // Resolves a type url into a Type. Like ResolveTypeUrl() but returns + // NULL if the type url is invalid or the type cannot be found. + // + // This TypeInfo class retains the ownership of the returned pointer. + virtual const google::protobuf::Type* GetTypeByTypeUrl( + StringPiece type_url) const = 0; + + // Resolves a type url for an enum. Returns NULL if the type url is + // invalid or the type cannot be found. + // + // This TypeInfo class retains the ownership of the returned pointer. + virtual const google::protobuf::Enum* GetEnumByTypeUrl( + StringPiece type_url) const = 0; + + // Looks up a field in the specified type given a CamelCase name. + virtual const google::protobuf::Field* FindField( + const google::protobuf::Type* type, + StringPiece camel_case_name) const = 0; + + // Creates a TypeInfo object that looks up type information from a + // TypeResolver. Caller takes ownership of the returned pointer. + static TypeInfo* NewTypeInfo(TypeResolver* type_resolver); + + private: + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(TypeInfo); +}; + +} // namespace converter +} // namespace util +} // namespace protobuf +} // namespace google + +#include <google/protobuf/port_undef.inc> + +#endif // GOOGLE_PROTOBUF_UTIL_CONVERTER_TYPE_INFO_H__ diff --git a/contrib/libs/protobuf_old/src/google/protobuf/util/internal/utility.cc b/contrib/libs/protobuf_old/src/google/protobuf/util/internal/utility.cc new file mode 100644 index 0000000000..3c1ee570c7 --- /dev/null +++ b/contrib/libs/protobuf_old/src/google/protobuf/util/internal/utility.cc @@ -0,0 +1,414 @@ +// 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 <google/protobuf/util/internal/utility.h> + +#include <algorithm> +#include <cmath> +#include <cstdint> +#include <limits> + +#include <google/protobuf/stubs/callback.h> +#include <google/protobuf/stubs/common.h> +#include <google/protobuf/stubs/logging.h> +#include <google/protobuf/wrappers.pb.h> +#include <google/protobuf/descriptor.pb.h> +#include <google/protobuf/descriptor.h> +#include <google/protobuf/util/internal/constants.h> +#include <google/protobuf/stubs/strutil.h> +#include <google/protobuf/stubs/map_util.h> + +#include <util/string/util.h> + +// clang-format off +#include <google/protobuf/port_def.inc> +// clang-format on + +namespace google { +namespace protobuf { +namespace util { +namespace converter { + +bool GetBoolOptionOrDefault( + const RepeatedPtrField<google::protobuf::Option>& options, + StringPiece option_name, bool default_value) { + const google::protobuf::Option* opt = FindOptionOrNull(options, option_name); + if (opt == nullptr) { + return default_value; + } + return GetBoolFromAny(opt->value()); +} + +arc_i64 GetInt64OptionOrDefault( + const RepeatedPtrField<google::protobuf::Option>& options, + StringPiece option_name, arc_i64 default_value) { + const google::protobuf::Option* opt = FindOptionOrNull(options, option_name); + if (opt == nullptr) { + return default_value; + } + return GetInt64FromAny(opt->value()); +} + +double GetDoubleOptionOrDefault( + const RepeatedPtrField<google::protobuf::Option>& options, + StringPiece option_name, double default_value) { + const google::protobuf::Option* opt = FindOptionOrNull(options, option_name); + if (opt == nullptr) { + return default_value; + } + return GetDoubleFromAny(opt->value()); +} + +TProtoStringType GetStringOptionOrDefault( + const RepeatedPtrField<google::protobuf::Option>& options, + StringPiece option_name, StringPiece default_value) { + const google::protobuf::Option* opt = FindOptionOrNull(options, option_name); + if (opt == nullptr) { + return TProtoStringType(default_value); + } + return GetStringFromAny(opt->value()); +} + +template <typename T> +void ParseFromAny(const TProtoStringType& data, T* result) { + result->ParseFromString(data); +} + +// Returns a boolean value contained in Any type. +// TODO(skarvaje): Add type checking & error messages here. +bool GetBoolFromAny(const google::protobuf::Any& any) { + google::protobuf::BoolValue b; + ParseFromAny(any.value(), &b); + return b.value(); +} + +arc_i64 GetInt64FromAny(const google::protobuf::Any& any) { + google::protobuf::Int64Value i; + ParseFromAny(any.value(), &i); + return i.value(); +} + +double GetDoubleFromAny(const google::protobuf::Any& any) { + google::protobuf::DoubleValue i; + ParseFromAny(any.value(), &i); + return i.value(); +} + +TProtoStringType GetStringFromAny(const google::protobuf::Any& any) { + google::protobuf::StringValue s; + ParseFromAny(any.value(), &s); + return s.value(); +} + +const StringPiece GetTypeWithoutUrl(StringPiece type_url) { + if (type_url.size() > kTypeUrlSize && type_url[kTypeUrlSize] == '/') { + return type_url.substr(kTypeUrlSize + 1); + } else { + size_t idx = type_url.rfind('/'); + if (idx != type_url.npos) { + type_url.remove_prefix(idx + 1); + } + return type_url; + } +} + +const TProtoStringType GetFullTypeWithUrl(StringPiece simple_type) { + return StrCat(kTypeServiceBaseUrl, "/", simple_type); +} + +const google::protobuf::Option* FindOptionOrNull( + const RepeatedPtrField<google::protobuf::Option>& options, + StringPiece option_name) { + for (int i = 0; i < options.size(); ++i) { + const google::protobuf::Option& opt = options.Get(i); + if (opt.name() == option_name) { + return &opt; + } + } + return nullptr; +} + +const google::protobuf::Field* FindFieldInTypeOrNull( + const google::protobuf::Type* type, StringPiece field_name) { + if (type != nullptr) { + for (int i = 0; i < type->fields_size(); ++i) { + const google::protobuf::Field& field = type->fields(i); + if (field.name() == field_name) { + return &field; + } + } + } + return nullptr; +} + +const google::protobuf::Field* FindJsonFieldInTypeOrNull( + const google::protobuf::Type* type, StringPiece json_name) { + if (type != nullptr) { + for (int i = 0; i < type->fields_size(); ++i) { + const google::protobuf::Field& field = type->fields(i); + if (field.json_name() == json_name) { + return &field; + } + } + } + return nullptr; +} + +const google::protobuf::Field* FindFieldInTypeByNumberOrNull( + const google::protobuf::Type* type, arc_i32 number) { + if (type != nullptr) { + for (int i = 0; i < type->fields_size(); ++i) { + const google::protobuf::Field& field = type->fields(i); + if (field.number() == number) { + return &field; + } + } + } + return nullptr; +} + +const google::protobuf::EnumValue* FindEnumValueByNameOrNull( + const google::protobuf::Enum* enum_type, StringPiece enum_name) { + if (enum_type != nullptr) { + for (int i = 0; i < enum_type->enumvalue_size(); ++i) { + const google::protobuf::EnumValue& enum_value = enum_type->enumvalue(i); + if (enum_value.name() == enum_name) { + return &enum_value; + } + } + } + return nullptr; +} + +const google::protobuf::EnumValue* FindEnumValueByNumberOrNull( + const google::protobuf::Enum* enum_type, arc_i32 value) { + if (enum_type != nullptr) { + for (int i = 0; i < enum_type->enumvalue_size(); ++i) { + const google::protobuf::EnumValue& enum_value = enum_type->enumvalue(i); + if (enum_value.number() == value) { + return &enum_value; + } + } + } + return nullptr; +} + +const google::protobuf::EnumValue* FindEnumValueByNameWithoutUnderscoreOrNull( + const google::protobuf::Enum* enum_type, StringPiece enum_name) { + if (enum_type != nullptr) { + for (int i = 0; i < enum_type->enumvalue_size(); ++i) { + const google::protobuf::EnumValue& enum_value = enum_type->enumvalue(i); + TProtoStringType enum_name_without_underscore = enum_value.name(); + + // Remove underscore from the name. + RemoveAll(enum_name_without_underscore, '_'); + // Make the name uppercase. + for (TProtoStringType::iterator it = enum_name_without_underscore.begin(); + it != enum_name_without_underscore.end(); ++it) { + *it = ascii_toupper(*it); + } + + if (enum_name_without_underscore == enum_name) { + return &enum_value; + } + } + } + return nullptr; +} + +TProtoStringType EnumValueNameToLowerCamelCase(StringPiece input) { + TProtoStringType input_string(input); + input_string.to_lower(); + return ToCamelCase(input_string); +} + +TProtoStringType ToCamelCase(StringPiece input) { + bool capitalize_next = false; + bool was_cap = true; + bool is_cap = false; + bool first_word = true; + TProtoStringType result; + result.reserve(input.size()); + + for (size_t i = 0; i < input.size(); ++i, was_cap = is_cap) { + is_cap = ascii_isupper(input[i]); + if (input[i] == '_') { + capitalize_next = true; + if (!result.empty()) first_word = false; + continue; + } else if (first_word) { + // Consider when the current character B is capitalized, + // first word ends when: + // 1) following a lowercase: "...aB..." + // 2) followed by a lowercase: "...ABc..." + if (!result.empty() && is_cap && + (!was_cap || + (i + 1 < input.size() && ascii_islower(input[i + 1])))) { + first_word = false; + result.push_back(input[i]); + } else { + result.push_back(ascii_tolower(input[i])); + continue; + } + } else if (capitalize_next) { + capitalize_next = false; + if (ascii_islower(input[i])) { + result.push_back(ascii_toupper(input[i])); + continue; + } else { + result.push_back(input[i]); + continue; + } + } else { + result.push_back(ascii_tolower(input[i])); + } + } + return result; +} + +TProtoStringType ToSnakeCase(StringPiece input) { + bool was_not_underscore = false; // Initialize to false for case 1 (below) + bool was_not_cap = false; + TProtoStringType result; + result.reserve(input.size() << 1); + + for (size_t i = 0; i < input.size(); ++i) { + if (ascii_isupper(input[i])) { + // Consider when the current character B is capitalized: + // 1) At beginning of input: "B..." => "b..." + // (e.g. "Biscuit" => "biscuit") + // 2) Following a lowercase: "...aB..." => "...a_b..." + // (e.g. "gBike" => "g_bike") + // 3) At the end of input: "...AB" => "...ab" + // (e.g. "GoogleLAB" => "google_lab") + // 4) Followed by a lowercase: "...ABc..." => "...a_bc..." + // (e.g. "GBike" => "g_bike") + if (was_not_underscore && // case 1 out + (was_not_cap || // case 2 in, case 3 out + (i + 1 < input.size() && // case 3 out + ascii_islower(input[i + 1])))) { // case 4 in + // We add an underscore for case 2 and case 4. + result.push_back('_'); + } + result.push_back(ascii_tolower(input[i])); + was_not_underscore = true; + was_not_cap = false; + } else { + result.push_back(input[i]); + was_not_underscore = input[i] != '_'; + was_not_cap = true; + } + } + return result; +} + +std::set<TProtoStringType>* well_known_types_ = nullptr; +PROTOBUF_NAMESPACE_ID::internal::once_flag well_known_types_init_; +const char* well_known_types_name_array_[] = { + "google.protobuf.Timestamp", "google.protobuf.Duration", + "google.protobuf.DoubleValue", "google.protobuf.FloatValue", + "google.protobuf.Int64Value", "google.protobuf.UInt64Value", + "google.protobuf.Int32Value", "google.protobuf.UInt32Value", + "google.protobuf.BoolValue", "google.protobuf.StringValue", + "google.protobuf.BytesValue", "google.protobuf.FieldMask"}; + +void DeleteWellKnownTypes() { delete well_known_types_; } + +void InitWellKnownTypes() { + well_known_types_ = new std::set<TProtoStringType>; + for (int i = 0; i < GOOGLE_ARRAYSIZE(well_known_types_name_array_); ++i) { + well_known_types_->insert(well_known_types_name_array_[i]); + } + google::protobuf::internal::OnShutdown(&DeleteWellKnownTypes); +} + +bool IsWellKnownType(const TProtoStringType& type_name) { + PROTOBUF_NAMESPACE_ID::internal::call_once(well_known_types_init_, + InitWellKnownTypes); + return ContainsKey(*well_known_types_, type_name); +} + +bool IsValidBoolString(StringPiece bool_string) { + return bool_string == "true" || bool_string == "false" || + bool_string == "1" || bool_string == "0"; +} + +bool IsMap(const google::protobuf::Field& field, + const google::protobuf::Type& type) { + return field.cardinality() == google::protobuf::Field::CARDINALITY_REPEATED && + (GetBoolOptionOrDefault(type.options(), "map_entry", false) || + GetBoolOptionOrDefault(type.options(), + "google.protobuf.MessageOptions.map_entry", + false)); +} + +bool IsMessageSetWireFormat(const google::protobuf::Type& type) { + return GetBoolOptionOrDefault(type.options(), "message_set_wire_format", + false) || + GetBoolOptionOrDefault( + type.options(), + "google.protobuf.MessageOptions.message_set_wire_format", false); +} + +TProtoStringType DoubleAsString(double value) { + if (value == std::numeric_limits<double>::infinity()) return "Infinity"; + if (value == -std::numeric_limits<double>::infinity()) return "-Infinity"; + if (std::isnan(value)) return "NaN"; + + return SimpleDtoa(value); +} + +TProtoStringType FloatAsString(float value) { + if (std::isfinite(value)) return SimpleFtoa(value); + return DoubleAsString(value); +} + +bool SafeStrToFloat(StringPiece str, float* value) { + double double_value; + if (!safe_strtod(str, &double_value)) { + return false; + } + + if (std::isinf(double_value) || std::isnan(double_value)) return false; + + // Fail if the value is not representable in float. + if (double_value > std::numeric_limits<float>::max() || + double_value < -std::numeric_limits<float>::max()) { + return false; + } + + *value = static_cast<float>(double_value); + return true; +} + +} // namespace converter +} // namespace util +} // namespace protobuf +} // namespace google diff --git a/contrib/libs/protobuf_old/src/google/protobuf/util/internal/utility.h b/contrib/libs/protobuf_old/src/google/protobuf/util/internal/utility.h new file mode 100644 index 0000000000..223e635902 --- /dev/null +++ b/contrib/libs/protobuf_old/src/google/protobuf/util/internal/utility.h @@ -0,0 +1,204 @@ +// 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_UTIL_CONVERTER_UTILITY_H__ +#define GOOGLE_PROTOBUF_UTIL_CONVERTER_UTILITY_H__ + +#include <cstdint> +#include <memory> +#include <string> +#include <utility> + +#include <google/protobuf/stubs/common.h> +#include <google/protobuf/stubs/logging.h> +#include <google/protobuf/any.pb.h> +#include <google/protobuf/type.pb.h> +#include <google/protobuf/repeated_field.h> +#include <google/protobuf/stubs/strutil.h> +#include <google/protobuf/stubs/statusor.h> +#include <google/protobuf/stubs/status.h> + +// Must be included last. +#include <google/protobuf/port_def.inc> + +namespace google { +namespace protobuf { +namespace util { +namespace converter { + +// Size of "type.googleapis.com" +static const arc_i64 kTypeUrlSize = 19; + +// Finds the tech option identified by option_name. Parses the boolean value and +// returns it. +// When the option with the given name is not found, default_value is returned. +PROTOBUF_EXPORT bool GetBoolOptionOrDefault( + const RepeatedPtrField<google::protobuf::Option>& options, + StringPiece option_name, bool default_value); + +// Returns int64 option value. If the option isn't found, returns the +// default_value. +PROTOBUF_EXPORT arc_i64 GetInt64OptionOrDefault( + const RepeatedPtrField<google::protobuf::Option>& options, + StringPiece option_name, arc_i64 default_value); + +// Returns double option value. If the option isn't found, returns the +// default_value. +PROTOBUF_EXPORT double GetDoubleOptionOrDefault( + const RepeatedPtrField<google::protobuf::Option>& options, + StringPiece option_name, double default_value); + +// Returns string option value. If the option isn't found, returns the +// default_value. +PROTOBUF_EXPORT TProtoStringType GetStringOptionOrDefault( + const RepeatedPtrField<google::protobuf::Option>& options, + StringPiece option_name, StringPiece default_value); + +// Returns a boolean value contained in Any type. +// TODO(skarvaje): Make these utilities dealing with Any types more generic, +// add more error checking and move to a more public/shareable location so +// others can use. +PROTOBUF_EXPORT bool GetBoolFromAny(const google::protobuf::Any& any); + +// Returns int64 value contained in Any type. +PROTOBUF_EXPORT arc_i64 GetInt64FromAny(const google::protobuf::Any& any); + +// Returns double value contained in Any type. +PROTOBUF_EXPORT double GetDoubleFromAny(const google::protobuf::Any& any); + +// Returns string value contained in Any type. +PROTOBUF_EXPORT TProtoStringType GetStringFromAny(const google::protobuf::Any& any); + +// Returns the type string without the url prefix. e.g.: If the passed type is +// 'type.googleapis.com/tech.type.Bool', the returned value is 'tech.type.Bool'. +PROTOBUF_EXPORT const StringPiece GetTypeWithoutUrl( + StringPiece type_url); + +// Returns the simple_type with the base type url (kTypeServiceBaseUrl) +// prefixed. +// +// E.g: +// GetFullTypeWithUrl("google.protobuf.Timestamp") returns the string +// "type.googleapis.com/google.protobuf.Timestamp". +PROTOBUF_EXPORT const TProtoStringType GetFullTypeWithUrl( + StringPiece simple_type); + +// Finds and returns option identified by name and option_name within the +// provided map. Returns nullptr if none found. +const google::protobuf::Option* FindOptionOrNull( + const RepeatedPtrField<google::protobuf::Option>& options, + StringPiece option_name); + +// Finds and returns the field identified by field_name in the passed tech Type +// object. Returns nullptr if none found. +const google::protobuf::Field* FindFieldInTypeOrNull( + const google::protobuf::Type* type, StringPiece field_name); + +// Similar to FindFieldInTypeOrNull, but this looks up fields with given +// json_name. +const google::protobuf::Field* FindJsonFieldInTypeOrNull( + const google::protobuf::Type* type, StringPiece json_name); + +// Similar to FindFieldInTypeOrNull, but this looks up fields by number. +const google::protobuf::Field* FindFieldInTypeByNumberOrNull( + const google::protobuf::Type* type, arc_i32 number); + +// Finds and returns the EnumValue identified by enum_name in the passed tech +// Enum object. Returns nullptr if none found. +const google::protobuf::EnumValue* FindEnumValueByNameOrNull( + const google::protobuf::Enum* enum_type, StringPiece enum_name); + +// Finds and returns the EnumValue identified by value in the passed tech +// Enum object. Returns nullptr if none found. +const google::protobuf::EnumValue* FindEnumValueByNumberOrNull( + const google::protobuf::Enum* enum_type, arc_i32 value); + +// Finds and returns the EnumValue identified by enum_name without underscore in +// the passed tech Enum object. Returns nullptr if none found. +// For Ex. if enum_name is ACTIONANDADVENTURE it can get accepted if +// EnumValue's name is action_and_adventure or ACTION_AND_ADVENTURE. +const google::protobuf::EnumValue* FindEnumValueByNameWithoutUnderscoreOrNull( + const google::protobuf::Enum* enum_type, StringPiece enum_name); + +// Converts input to camel-case and returns it. +PROTOBUF_EXPORT TProtoStringType ToCamelCase(const StringPiece input); + +// Converts enum name string to camel-case and returns it. +TProtoStringType EnumValueNameToLowerCamelCase(const StringPiece input); + +// Converts input to snake_case and returns it. +PROTOBUF_EXPORT TProtoStringType ToSnakeCase(StringPiece input); + +// Returns true if type_name represents a well-known type. +PROTOBUF_EXPORT bool IsWellKnownType(const TProtoStringType& type_name); + +// Returns true if 'bool_string' represents a valid boolean value. Only "true", +// "false", "0" and "1" are allowed. +PROTOBUF_EXPORT bool IsValidBoolString(StringPiece bool_string); + +// Returns true if "field" is a protobuf map field based on its type. +PROTOBUF_EXPORT bool IsMap(const google::protobuf::Field& field, + const google::protobuf::Type& type); + +// Returns true if the given type has special MessageSet wire format. +bool IsMessageSetWireFormat(const google::protobuf::Type& type); + +// Infinity/NaN-aware conversion to string. +PROTOBUF_EXPORT TProtoStringType DoubleAsString(double value); +PROTOBUF_EXPORT TProtoStringType FloatAsString(float value); + +// Convert from int32, int64, uint32, uint64, double or float to string. +template <typename T> +TProtoStringType ValueAsString(T value) { + return StrCat(value); +} + +template <> +inline TProtoStringType ValueAsString(float value) { + return FloatAsString(value); +} + +template <> +inline TProtoStringType ValueAsString(double value) { + return DoubleAsString(value); +} + +// Converts a string to float. Unlike safe_strtof, conversion will fail if the +// value fits into double but not float (e.g., DBL_MAX). +PROTOBUF_EXPORT bool SafeStrToFloat(StringPiece str, float* value); + +} // namespace converter +} // namespace util +} // namespace protobuf +} // namespace google + +#include <google/protobuf/port_undef.inc> + +#endif // GOOGLE_PROTOBUF_UTIL_CONVERTER_UTILITY_H__ diff --git a/contrib/libs/protobuf_old/src/google/protobuf/util/json_util.cc b/contrib/libs/protobuf_old/src/google/protobuf/util/json_util.cc new file mode 100644 index 0000000000..d96bd8e17e --- /dev/null +++ b/contrib/libs/protobuf_old/src/google/protobuf/util/json_util.cc @@ -0,0 +1,282 @@ +// 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 <google/protobuf/util/json_util.h> + +#include <google/protobuf/stubs/common.h> +#include <google/protobuf/io/coded_stream.h> +#include <google/protobuf/io/zero_copy_stream.h> +#include <google/protobuf/stubs/once.h> +#include <google/protobuf/util/internal/default_value_objectwriter.h> +#include <google/protobuf/util/internal/error_listener.h> +#include <google/protobuf/util/internal/json_objectwriter.h> +#include <google/protobuf/util/internal/json_stream_parser.h> +#include <google/protobuf/util/internal/protostream_objectsource.h> +#include <google/protobuf/util/internal/protostream_objectwriter.h> +#include <google/protobuf/util/type_resolver.h> +#include <google/protobuf/util/type_resolver_util.h> +#include <google/protobuf/stubs/bytestream.h> +#include <google/protobuf/stubs/status.h> +#include <google/protobuf/stubs/strutil.h> +#include <google/protobuf/stubs/status_macros.h> + +// clang-format off +#include <google/protobuf/port_def.inc> +// clang-format on + +namespace google { +namespace protobuf { +namespace util { + +namespace internal { +ZeroCopyStreamByteSink::~ZeroCopyStreamByteSink() { + if (buffer_size_ > 0) { + stream_->BackUp(buffer_size_); + } +} + +void ZeroCopyStreamByteSink::Append(const char* bytes, size_t len) { + while (true) { + if (len <= buffer_size_) { + memcpy(buffer_, bytes, len); + buffer_ = static_cast<char*>(buffer_) + len; + buffer_size_ -= len; + return; + } + if (buffer_size_ > 0) { + memcpy(buffer_, bytes, buffer_size_); + bytes += buffer_size_; + len -= buffer_size_; + } + if (!stream_->Next(&buffer_, &buffer_size_)) { + // There isn't a way for ByteSink to report errors. + buffer_size_ = 0; + return; + } + } +} +} // namespace internal + +util::Status BinaryToJsonStream(TypeResolver* resolver, + const TProtoStringType& type_url, + io::ZeroCopyInputStream* binary_input, + io::ZeroCopyOutputStream* json_output, + const JsonPrintOptions& options) { + io::CodedInputStream in_stream(binary_input); + google::protobuf::Type type; + RETURN_IF_ERROR(resolver->ResolveMessageType(type_url, &type)); + converter::ProtoStreamObjectSource::RenderOptions render_options; + render_options.use_ints_for_enums = options.always_print_enums_as_ints; + render_options.preserve_proto_field_names = + options.preserve_proto_field_names; + converter::ProtoStreamObjectSource proto_source(&in_stream, resolver, type, + render_options); + io::CodedOutputStream out_stream(json_output); + converter::JsonObjectWriter json_writer(options.add_whitespace ? " " : "", + &out_stream); + if (options.always_print_primitive_fields) { + converter::DefaultValueObjectWriter default_value_writer(resolver, type, + &json_writer); + default_value_writer.set_preserve_proto_field_names( + options.preserve_proto_field_names); + default_value_writer.set_print_enums_as_ints( + options.always_print_enums_as_ints); + return proto_source.WriteTo(&default_value_writer); + } else { + return proto_source.WriteTo(&json_writer); + } +} + +util::Status BinaryToJsonString(TypeResolver* resolver, + const TProtoStringType& type_url, + const TProtoStringType& binary_input, + TProtoStringType* json_output, + const JsonPrintOptions& options) { + io::ArrayInputStream input_stream(binary_input.data(), binary_input.size()); + io::StringOutputStream output_stream(json_output); + return BinaryToJsonStream(resolver, type_url, &input_stream, &output_stream, + options); +} + +namespace { +class StatusErrorListener : public converter::ErrorListener { + public: + StatusErrorListener() {} + ~StatusErrorListener() override {} + + util::Status GetStatus() { return status_; } + + void InvalidName(const converter::LocationTrackerInterface& loc, + StringPiece unknown_name, + StringPiece message) override { + TProtoStringType loc_string = GetLocString(loc); + if (!loc_string.empty()) { + loc_string.append(" "); + } + status_ = util::InvalidArgumentError( + StrCat(loc_string, unknown_name, ": ", message)); + } + + void InvalidValue(const converter::LocationTrackerInterface& loc, + StringPiece type_name, + StringPiece value) override { + status_ = util::InvalidArgumentError( + StrCat(GetLocString(loc), ": invalid value ", TProtoStringType(value), + " for type ", TProtoStringType(type_name))); + } + + void MissingField(const converter::LocationTrackerInterface& loc, + StringPiece missing_name) override { + status_ = util::InvalidArgumentError(StrCat( + GetLocString(loc), ": missing field ", TProtoStringType(missing_name))); + } + + private: + util::Status status_; + + TProtoStringType GetLocString(const converter::LocationTrackerInterface& loc) { + TProtoStringType loc_string = loc.ToString(); + StripWhitespace(&loc_string); + if (!loc_string.empty()) { + loc_string = StrCat("(", loc_string, ")"); + } + return loc_string; + } + + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(StatusErrorListener); +}; +} // namespace + +util::Status JsonToBinaryStream(TypeResolver* resolver, + const TProtoStringType& type_url, + io::ZeroCopyInputStream* json_input, + io::ZeroCopyOutputStream* binary_output, + const JsonParseOptions& options) { + google::protobuf::Type type; + RETURN_IF_ERROR(resolver->ResolveMessageType(type_url, &type)); + internal::ZeroCopyStreamByteSink sink(binary_output); + StatusErrorListener listener; + converter::ProtoStreamObjectWriter::Options proto_writer_options; + proto_writer_options.ignore_unknown_fields = options.ignore_unknown_fields; + proto_writer_options.ignore_unknown_enum_values = + options.ignore_unknown_fields; + proto_writer_options.case_insensitive_enum_parsing = + options.case_insensitive_enum_parsing; + converter::ProtoStreamObjectWriter proto_writer( + resolver, type, &sink, &listener, proto_writer_options); + + converter::JsonStreamParser parser(&proto_writer); + const void* buffer; + int length; + while (json_input->Next(&buffer, &length)) { + if (length == 0) continue; + RETURN_IF_ERROR(parser.Parse( + StringPiece(static_cast<const char*>(buffer), length))); + } + RETURN_IF_ERROR(parser.FinishParse()); + + return listener.GetStatus(); +} + +util::Status JsonToBinaryString(TypeResolver* resolver, + const TProtoStringType& type_url, + StringPiece json_input, + TProtoStringType* binary_output, + const JsonParseOptions& options) { + io::ArrayInputStream input_stream(json_input.data(), json_input.size()); + io::StringOutputStream output_stream(binary_output); + return JsonToBinaryStream(resolver, type_url, &input_stream, &output_stream, + options); +} + +namespace { +const char* kTypeUrlPrefix = "type.googleapis.com"; +TypeResolver* generated_type_resolver_ = NULL; +PROTOBUF_NAMESPACE_ID::internal::once_flag generated_type_resolver_init_; + +TProtoStringType GetTypeUrl(const Message& message) { + return TProtoStringType(kTypeUrlPrefix) + "/" + + message.GetDescriptor()->full_name(); +} + +void DeleteGeneratedTypeResolver() { delete generated_type_resolver_; } + +void InitGeneratedTypeResolver() { + generated_type_resolver_ = NewTypeResolverForDescriptorPool( + kTypeUrlPrefix, DescriptorPool::generated_pool()); + ::google::protobuf::internal::OnShutdown(&DeleteGeneratedTypeResolver); +} + +TypeResolver* GetGeneratedTypeResolver() { + PROTOBUF_NAMESPACE_ID::internal::call_once(generated_type_resolver_init_, + InitGeneratedTypeResolver); + return generated_type_resolver_; +} +} // namespace + +util::Status MessageToJsonString(const Message& message, TProtoStringType* output, + const JsonOptions& options) { + const DescriptorPool* pool = message.GetDescriptor()->file()->pool(); + TypeResolver* resolver = + pool == DescriptorPool::generated_pool() + ? GetGeneratedTypeResolver() + : NewTypeResolverForDescriptorPool(kTypeUrlPrefix, pool); + util::Status result = + BinaryToJsonString(resolver, GetTypeUrl(message), + message.SerializeAsString(), output, options); + if (pool != DescriptorPool::generated_pool()) { + delete resolver; + } + return result; +} + +util::Status JsonStringToMessage(StringPiece input, Message* message, + const JsonParseOptions& options) { + const DescriptorPool* pool = message->GetDescriptor()->file()->pool(); + TypeResolver* resolver = + pool == DescriptorPool::generated_pool() + ? GetGeneratedTypeResolver() + : NewTypeResolverForDescriptorPool(kTypeUrlPrefix, pool); + TProtoStringType binary; + util::Status result = JsonToBinaryString(resolver, GetTypeUrl(*message), + input, &binary, options); + if (result.ok() && !message->ParseFromString(binary)) { + result = util::InvalidArgumentError( + "JSON transcoder produced invalid protobuf output."); + } + if (pool != DescriptorPool::generated_pool()) { + delete resolver; + } + return result; +} + +} // namespace util +} // namespace protobuf +} // namespace google diff --git a/contrib/libs/protobuf_old/src/google/protobuf/util/json_util.h b/contrib/libs/protobuf_old/src/google/protobuf/util/json_util.h new file mode 100644 index 0000000000..7be7f4222c --- /dev/null +++ b/contrib/libs/protobuf_old/src/google/protobuf/util/json_util.h @@ -0,0 +1,204 @@ +// 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. + +// Utility functions to convert between protobuf binary format and proto3 JSON +// format. +#ifndef GOOGLE_PROTOBUF_UTIL_JSON_UTIL_H__ +#define GOOGLE_PROTOBUF_UTIL_JSON_UTIL_H__ + +#include <google/protobuf/message.h> +#include <google/protobuf/util/type_resolver.h> +#include <google/protobuf/stubs/bytestream.h> +#include <google/protobuf/stubs/status.h> +#include <google/protobuf/stubs/strutil.h> + +#include <google/protobuf/port_def.inc> + +namespace google { +namespace protobuf { +namespace io { +class ZeroCopyInputStream; +class ZeroCopyOutputStream; +} // namespace io +namespace util { + +struct JsonParseOptions { + // Whether to ignore unknown JSON fields during parsing + bool ignore_unknown_fields; + + // If true, when a lowercase enum value fails to parse, try convert it to + // UPPER_CASE and see if it matches a valid enum. + // WARNING: This option exists only to preserve legacy behavior. Avoid using + // this option. If your enum needs to support different casing, consider using + // allow_alias instead. + bool case_insensitive_enum_parsing; + + JsonParseOptions() + : ignore_unknown_fields(false), + case_insensitive_enum_parsing(false) {} +}; + +struct JsonPrintOptions { + // Whether to add spaces, line breaks and indentation to make the JSON output + // easy to read. + bool add_whitespace; + // Whether to always print primitive fields. By default proto3 primitive + // fields with default values will be omitted in JSON output. For example, an + // int32 field set to 0 will be omitted. Set this flag to true will override + // the default behavior and print primitive fields regardless of their values. + bool always_print_primitive_fields; + // Whether to always print enums as ints. By default they are rendered as + // strings. + bool always_print_enums_as_ints; + // Whether to preserve proto field names + bool preserve_proto_field_names; + + JsonPrintOptions() + : add_whitespace(false), + always_print_primitive_fields(false), + always_print_enums_as_ints(false), + preserve_proto_field_names(false) {} +}; + +// DEPRECATED. Use JsonPrintOptions instead. +typedef JsonPrintOptions JsonOptions; + +// Converts from protobuf message to JSON and appends it to |output|. This is a +// simple wrapper of BinaryToJsonString(). It will use the DescriptorPool of the +// passed-in message to resolve Any types. +PROTOBUF_EXPORT util::Status MessageToJsonString(const Message& message, + TProtoStringType* output, + const JsonOptions& options); + +inline util::Status MessageToJsonString(const Message& message, + TProtoStringType* output) { + return MessageToJsonString(message, output, JsonOptions()); +} + +// Converts from JSON to protobuf message. This is a simple wrapper of +// JsonStringToBinary(). It will use the DescriptorPool of the passed-in +// message to resolve Any types. +PROTOBUF_EXPORT util::Status JsonStringToMessage( + StringPiece input, Message* message, const JsonParseOptions& options); + +inline util::Status JsonStringToMessage(StringPiece input, + Message* message) { + return JsonStringToMessage(input, message, JsonParseOptions()); +} + +// Converts protobuf binary data to JSON. +// The conversion will fail if: +// 1. TypeResolver fails to resolve a type. +// 2. input is not valid protobuf wire format, or conflicts with the type +// information returned by TypeResolver. +// Note that unknown fields will be discarded silently. +PROTOBUF_EXPORT util::Status BinaryToJsonStream( + TypeResolver* resolver, const TProtoStringType& type_url, + io::ZeroCopyInputStream* binary_input, + io::ZeroCopyOutputStream* json_output, const JsonPrintOptions& options); + +inline util::Status BinaryToJsonStream(TypeResolver* resolver, + const TProtoStringType& type_url, + io::ZeroCopyInputStream* binary_input, + io::ZeroCopyOutputStream* json_output) { + return BinaryToJsonStream(resolver, type_url, binary_input, json_output, + JsonPrintOptions()); +} + +PROTOBUF_EXPORT util::Status BinaryToJsonString( + TypeResolver* resolver, const TProtoStringType& type_url, + const TProtoStringType& binary_input, TProtoStringType* json_output, + const JsonPrintOptions& options); + +inline util::Status BinaryToJsonString(TypeResolver* resolver, + const TProtoStringType& type_url, + const TProtoStringType& binary_input, + TProtoStringType* json_output) { + return BinaryToJsonString(resolver, type_url, binary_input, json_output, + JsonPrintOptions()); +} + +// Converts JSON data to protobuf binary format. +// The conversion will fail if: +// 1. TypeResolver fails to resolve a type. +// 2. input is not valid JSON format, or conflicts with the type +// information returned by TypeResolver. +PROTOBUF_EXPORT util::Status JsonToBinaryStream( + TypeResolver* resolver, const TProtoStringType& type_url, + io::ZeroCopyInputStream* json_input, + io::ZeroCopyOutputStream* binary_output, const JsonParseOptions& options); + +inline util::Status JsonToBinaryStream( + TypeResolver* resolver, const TProtoStringType& type_url, + io::ZeroCopyInputStream* json_input, + io::ZeroCopyOutputStream* binary_output) { + return JsonToBinaryStream(resolver, type_url, json_input, binary_output, + JsonParseOptions()); +} + +PROTOBUF_EXPORT util::Status JsonToBinaryString( + TypeResolver* resolver, const TProtoStringType& type_url, + StringPiece json_input, TProtoStringType* binary_output, + const JsonParseOptions& options); + +inline util::Status JsonToBinaryString(TypeResolver* resolver, + const TProtoStringType& type_url, + StringPiece json_input, + TProtoStringType* binary_output) { + return JsonToBinaryString(resolver, type_url, json_input, binary_output, + JsonParseOptions()); +} + +namespace internal { +// Internal helper class. Put in the header so we can write unit-tests for it. +class PROTOBUF_EXPORT ZeroCopyStreamByteSink : public strings::ByteSink { + public: + explicit ZeroCopyStreamByteSink(io::ZeroCopyOutputStream* stream) + : stream_(stream), buffer_(NULL), buffer_size_(0) {} + ~ZeroCopyStreamByteSink(); + + void Append(const char* bytes, size_t len) override; + + private: + io::ZeroCopyOutputStream* stream_; + void* buffer_; + int buffer_size_; + + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ZeroCopyStreamByteSink); +}; +} // namespace internal + +} // namespace util +} // namespace protobuf +} // namespace google + +#include <google/protobuf/port_undef.inc> + +#endif // GOOGLE_PROTOBUF_UTIL_JSON_UTIL_H__ diff --git a/contrib/libs/protobuf_old/src/google/protobuf/util/message_differencer.cc b/contrib/libs/protobuf_old/src/google/protobuf/util/message_differencer.cc new file mode 100644 index 0000000000..5c2b9b6f97 --- /dev/null +++ b/contrib/libs/protobuf_old/src/google/protobuf/util/message_differencer.cc @@ -0,0 +1,2222 @@ +// 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: jschorr@google.com (Joseph Schorr) +// Based on original Protocol Buffers design by +// Sanjay Ghemawat, Jeff Dean, and others. + +#include <google/protobuf/util/message_differencer.h> + +#include <algorithm> +#include <cstddef> +#include <cstdint> +#include <functional> +#include <limits> +#include <memory> +#include <utility> + +#include <google/protobuf/stubs/logging.h> +#include <google/protobuf/stubs/common.h> +#include <google/protobuf/stubs/stringprintf.h> +#include <google/protobuf/io/printer.h> +#include <google/protobuf/io/zero_copy_stream.h> +#include <google/protobuf/io/zero_copy_stream_impl.h> +#include <google/protobuf/descriptor.pb.h> +#include <google/protobuf/descriptor.h> +#include <google/protobuf/dynamic_message.h> +#include <google/protobuf/generated_enum_reflection.h> +#include <google/protobuf/map_field.h> +#include <google/protobuf/message.h> +#include <google/protobuf/text_format.h> +#include <google/protobuf/util/field_comparator.h> +#include <google/protobuf/stubs/strutil.h> + +// Always include as last one, otherwise it can break compilation +#include <google/protobuf/port_def.inc> + +namespace google { +namespace protobuf { + +namespace util { + +// A reporter to report the total number of diffs. +// TODO(ykzhu): we can improve this to take into account the value differencers. +class NumDiffsReporter : public google::protobuf::util::MessageDifferencer::Reporter { + public: + NumDiffsReporter() : num_diffs_(0) {} + + // Returns the total number of diffs. + arc_i32 GetNumDiffs() const { return num_diffs_; } + void Reset() { num_diffs_ = 0; } + + // Report that a field has been added into Message2. + void ReportAdded( + const google::protobuf::Message& /* message1 */, + const google::protobuf::Message& /* message2 */, + const std::vector<google::protobuf::util::MessageDifferencer::SpecificField>& + /*field_path*/) override { + ++num_diffs_; + } + + // Report that a field has been deleted from Message1. + void ReportDeleted( + const google::protobuf::Message& /* message1 */, + const google::protobuf::Message& /* message2 */, + const std::vector<google::protobuf::util::MessageDifferencer::SpecificField>& + /*field_path*/) override { + ++num_diffs_; + } + + // Report that the value of a field has been modified. + void ReportModified( + const google::protobuf::Message& /* message1 */, + const google::protobuf::Message& /* message2 */, + const std::vector<google::protobuf::util::MessageDifferencer::SpecificField>& + /*field_path*/) override { + ++num_diffs_; + } + + private: + arc_i32 num_diffs_; +}; + +// When comparing a repeated field as map, MultipleFieldMapKeyComparator can +// be used to specify multiple fields as key for key comparison. +// Two elements of a repeated field will be regarded as having the same key +// iff they have the same value for every specified key field. +// Note that you can also specify only one field as key. +class MessageDifferencer::MultipleFieldsMapKeyComparator + : public MessageDifferencer::MapKeyComparator { + public: + MultipleFieldsMapKeyComparator( + MessageDifferencer* message_differencer, + const std::vector<std::vector<const FieldDescriptor*> >& key_field_paths) + : message_differencer_(message_differencer), + key_field_paths_(key_field_paths) { + GOOGLE_CHECK(!key_field_paths_.empty()); + for (const auto& path : key_field_paths_) { + GOOGLE_CHECK(!path.empty()); + } + } + MultipleFieldsMapKeyComparator(MessageDifferencer* message_differencer, + const FieldDescriptor* key) + : message_differencer_(message_differencer) { + std::vector<const FieldDescriptor*> key_field_path; + key_field_path.push_back(key); + key_field_paths_.push_back(key_field_path); + } + bool IsMatch(const Message& message1, const Message& message2, + const std::vector<SpecificField>& parent_fields) const override { + for (const auto& path : key_field_paths_) { + if (!IsMatchInternal(message1, message2, parent_fields, path, 0)) { + return false; + } + } + return true; + } + + private: + bool IsMatchInternal( + const Message& message1, const Message& message2, + const std::vector<SpecificField>& parent_fields, + const std::vector<const FieldDescriptor*>& key_field_path, + int path_index) const { + const FieldDescriptor* field = key_field_path[path_index]; + std::vector<SpecificField> current_parent_fields(parent_fields); + if (path_index == static_cast<arc_i64>(key_field_path.size() - 1)) { + if (field->is_map()) { + return message_differencer_->CompareMapField(message1, message2, field, + ¤t_parent_fields); + } else if (field->is_repeated()) { + return message_differencer_->CompareRepeatedField( + message1, message2, field, ¤t_parent_fields); + } else { + return message_differencer_->CompareFieldValueUsingParentFields( + message1, message2, field, -1, -1, ¤t_parent_fields); + } + } else { + const Reflection* reflection1 = message1.GetReflection(); + const Reflection* reflection2 = message2.GetReflection(); + bool has_field1 = reflection1->HasField(message1, field); + bool has_field2 = reflection2->HasField(message2, field); + if (!has_field1 && !has_field2) { + return true; + } + if (has_field1 != has_field2) { + return false; + } + SpecificField specific_field; + specific_field.field = field; + current_parent_fields.push_back(specific_field); + return IsMatchInternal(reflection1->GetMessage(message1, field), + reflection2->GetMessage(message2, field), + current_parent_fields, key_field_path, + path_index + 1); + } + } + MessageDifferencer* message_differencer_; + std::vector<std::vector<const FieldDescriptor*> > key_field_paths_; + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(MultipleFieldsMapKeyComparator); +}; + +// Preserve the order when treating repeated field as SMART_LIST. The current +// implementation is to find the longest matching sequence from the first +// element. The optimal solution requires to use //util/diff/lcs.h, which is +// not open sourced yet. Overwrite this method if you want to have that. +// TODO(ykzhu): change to use LCS once it is open sourced. +void MatchIndicesPostProcessorForSmartList(std::vector<int>* match_list1, + std::vector<int>* match_list2) { + int last_matched_index = -1; + for (size_t i = 0; i < match_list1->size(); ++i) { + if (match_list1->at(i) < 0) { + continue; + } + if (last_matched_index < 0 || match_list1->at(i) > last_matched_index) { + last_matched_index = match_list1->at(i); + } else { + match_list2->at(match_list1->at(i)) = -1; + match_list1->at(i) = -1; + } + } +} + +void AddSpecificIndex( + google::protobuf::util::MessageDifferencer::SpecificField* specific_field, + const Message& message, const FieldDescriptor* field, int index) { + if (field->is_map()) { + const Reflection* reflection = message.GetReflection(); + specific_field->map_entry1 = + &reflection->GetRepeatedMessage(message, field, index); + } + specific_field->index = index; +} + +void AddSpecificNewIndex( + google::protobuf::util::MessageDifferencer::SpecificField* specific_field, + const Message& message, const FieldDescriptor* field, int index) { + if (field->is_map()) { + const Reflection* reflection = message.GetReflection(); + specific_field->map_entry2 = + &reflection->GetRepeatedMessage(message, field, index); + } + specific_field->new_index = index; +} + +MessageDifferencer::MapEntryKeyComparator::MapEntryKeyComparator( + MessageDifferencer* message_differencer) + : message_differencer_(message_differencer) {} + +bool MessageDifferencer::MapEntryKeyComparator::IsMatch( + const Message& message1, const Message& message2, + const std::vector<SpecificField>& parent_fields) const { + // Map entry has its key in the field with tag 1. See the comment for + // map_entry in MessageOptions. + const FieldDescriptor* key = message1.GetDescriptor()->FindFieldByNumber(1); + // If key is not present in message1 and we're doing partial comparison or if + // map key is explicitly ignored treat the field as set instead, + const bool treat_as_set = + (message_differencer_->scope() == PARTIAL && + !message1.GetReflection()->HasField(message1, key)) || + message_differencer_->IsIgnored(message1, message2, key, parent_fields); + + std::vector<SpecificField> current_parent_fields(parent_fields); + if (treat_as_set) { + return message_differencer_->Compare(message1, message2, + ¤t_parent_fields); + } + return message_differencer_->CompareFieldValueUsingParentFields( + message1, message2, key, -1, -1, ¤t_parent_fields); +} + +bool MessageDifferencer::Equals(const Message& message1, + const Message& message2) { + MessageDifferencer differencer; + + return differencer.Compare(message1, message2); +} + +bool MessageDifferencer::Equivalent(const Message& message1, + const Message& message2) { + MessageDifferencer differencer; + differencer.set_message_field_comparison(MessageDifferencer::EQUIVALENT); + + return differencer.Compare(message1, message2); +} + +bool MessageDifferencer::ApproximatelyEquals(const Message& message1, + const Message& message2) { + MessageDifferencer differencer; + differencer.set_float_comparison(MessageDifferencer::APPROXIMATE); + + return differencer.Compare(message1, message2); +} + +bool MessageDifferencer::ApproximatelyEquivalent(const Message& message1, + const Message& message2) { + MessageDifferencer differencer; + differencer.set_message_field_comparison(MessageDifferencer::EQUIVALENT); + differencer.set_float_comparison(MessageDifferencer::APPROXIMATE); + + return differencer.Compare(message1, message2); +} + +// =========================================================================== + +MessageDifferencer::MessageDifferencer() + : reporter_(NULL), + message_field_comparison_(EQUAL), + scope_(FULL), + repeated_field_comparison_(AS_LIST), + map_entry_key_comparator_(this), + report_matches_(false), + report_moves_(true), + report_ignores_(true), + output_string_(nullptr), + match_indices_for_smart_list_callback_( + MatchIndicesPostProcessorForSmartList) {} + +MessageDifferencer::~MessageDifferencer() { + for (MapKeyComparator* comparator : owned_key_comparators_) { + delete comparator; + } + for (IgnoreCriteria* criteria : ignore_criteria_) { + delete criteria; + } +} + +void MessageDifferencer::set_field_comparator(FieldComparator* comparator) { + GOOGLE_CHECK(comparator) << "Field comparator can't be NULL."; + field_comparator_kind_ = kFCBase; + field_comparator_.base = comparator; +} + +#ifdef PROTOBUF_FUTURE_BREAKING_CHANGES +void MessageDifferencer::set_field_comparator( + DefaultFieldComparator* comparator) { + GOOGLE_CHECK(comparator) << "Field comparator can't be NULL."; + field_comparator_kind_ = kFCDefault; + field_comparator_.default_impl = comparator; +} +#endif // PROTOBUF_FUTURE_BREAKING_CHANGES + +void MessageDifferencer::set_message_field_comparison( + MessageFieldComparison comparison) { + message_field_comparison_ = comparison; +} + +void MessageDifferencer::set_scope(Scope scope) { scope_ = scope; } + +MessageDifferencer::Scope MessageDifferencer::scope() { return scope_; } + +void MessageDifferencer::set_float_comparison(FloatComparison comparison) { + default_field_comparator_.set_float_comparison( + comparison == EXACT ? DefaultFieldComparator::EXACT + : DefaultFieldComparator::APPROXIMATE); +} + +void MessageDifferencer::set_repeated_field_comparison( + RepeatedFieldComparison comparison) { + repeated_field_comparison_ = comparison; +} + +MessageDifferencer::RepeatedFieldComparison +MessageDifferencer::repeated_field_comparison() { + return repeated_field_comparison_; +} + +void MessageDifferencer::CheckRepeatedFieldComparisons( + const FieldDescriptor* field, + const RepeatedFieldComparison& new_comparison) { + GOOGLE_CHECK(field->is_repeated()) + << "Field must be repeated: " << field->full_name(); + const MapKeyComparator* key_comparator = GetMapKeyComparator(field); + GOOGLE_CHECK(key_comparator == NULL) + << "Cannot treat this repeated field as both MAP and " << new_comparison + << " for comparison. Field name is: " << field->full_name(); +} + +void MessageDifferencer::TreatAsSet(const FieldDescriptor* field) { + CheckRepeatedFieldComparisons(field, AS_SET); + repeated_field_comparisons_[field] = AS_SET; +} + +void MessageDifferencer::TreatAsSmartSet(const FieldDescriptor* field) { + CheckRepeatedFieldComparisons(field, AS_SMART_SET); + repeated_field_comparisons_[field] = AS_SMART_SET; +} + +void MessageDifferencer::SetMatchIndicesForSmartListCallback( + std::function<void(std::vector<int>*, std::vector<int>*)> callback) { + match_indices_for_smart_list_callback_ = callback; +} + +void MessageDifferencer::TreatAsList(const FieldDescriptor* field) { + CheckRepeatedFieldComparisons(field, AS_LIST); + repeated_field_comparisons_[field] = AS_LIST; +} + +void MessageDifferencer::TreatAsSmartList(const FieldDescriptor* field) { + CheckRepeatedFieldComparisons(field, AS_SMART_LIST); + repeated_field_comparisons_[field] = AS_SMART_LIST; +} + +void MessageDifferencer::TreatAsMap(const FieldDescriptor* field, + const FieldDescriptor* key) { + GOOGLE_CHECK_EQ(FieldDescriptor::CPPTYPE_MESSAGE, field->cpp_type()) + << "Field has to be message type. Field name is: " << field->full_name(); + GOOGLE_CHECK(key->containing_type() == field->message_type()) + << key->full_name() + << " must be a direct subfield within the repeated field " + << field->full_name() << ", not " << key->containing_type()->full_name(); + GOOGLE_CHECK(repeated_field_comparisons_.find(field) == + repeated_field_comparisons_.end()) + << "Cannot treat the same field as both " + << repeated_field_comparisons_[field] + << " and MAP. Field name is: " << field->full_name(); + MapKeyComparator* key_comparator = + new MultipleFieldsMapKeyComparator(this, key); + owned_key_comparators_.push_back(key_comparator); + map_field_key_comparator_[field] = key_comparator; +} + +void MessageDifferencer::TreatAsMapWithMultipleFieldsAsKey( + const FieldDescriptor* field, + const std::vector<const FieldDescriptor*>& key_fields) { + std::vector<std::vector<const FieldDescriptor*> > key_field_paths; + for (const FieldDescriptor* key_filed : key_fields) { + std::vector<const FieldDescriptor*> key_field_path; + key_field_path.push_back(key_filed); + key_field_paths.push_back(key_field_path); + } + TreatAsMapWithMultipleFieldPathsAsKey(field, key_field_paths); +} + +void MessageDifferencer::TreatAsMapWithMultipleFieldPathsAsKey( + const FieldDescriptor* field, + const std::vector<std::vector<const FieldDescriptor*> >& key_field_paths) { + GOOGLE_CHECK(field->is_repeated()) + << "Field must be repeated: " << field->full_name(); + GOOGLE_CHECK_EQ(FieldDescriptor::CPPTYPE_MESSAGE, field->cpp_type()) + << "Field has to be message type. Field name is: " << field->full_name(); + for (const auto& key_field_path : key_field_paths) { + for (size_t j = 0; j < key_field_path.size(); ++j) { + const FieldDescriptor* parent_field = + j == 0 ? field : key_field_path[j - 1]; + const FieldDescriptor* child_field = key_field_path[j]; + GOOGLE_CHECK(child_field->containing_type() == parent_field->message_type()) + << child_field->full_name() + << " must be a direct subfield within the field: " + << parent_field->full_name(); + if (j != 0) { + GOOGLE_CHECK_EQ(FieldDescriptor::CPPTYPE_MESSAGE, parent_field->cpp_type()) + << parent_field->full_name() << " has to be of type message."; + GOOGLE_CHECK(!parent_field->is_repeated()) + << parent_field->full_name() << " cannot be a repeated field."; + } + } + } + GOOGLE_CHECK(repeated_field_comparisons_.find(field) == + repeated_field_comparisons_.end()) + << "Cannot treat the same field as both " + << repeated_field_comparisons_[field] + << " and MAP. Field name is: " << field->full_name(); + MapKeyComparator* key_comparator = + new MultipleFieldsMapKeyComparator(this, key_field_paths); + owned_key_comparators_.push_back(key_comparator); + map_field_key_comparator_[field] = key_comparator; +} + +void MessageDifferencer::TreatAsMapUsingKeyComparator( + const FieldDescriptor* field, const MapKeyComparator* key_comparator) { + GOOGLE_CHECK(field->is_repeated()) + << "Field must be repeated: " << field->full_name(); + GOOGLE_CHECK(repeated_field_comparisons_.find(field) == + repeated_field_comparisons_.end()) + << "Cannot treat the same field as both " + << repeated_field_comparisons_[field] + << " and MAP. Field name is: " << field->full_name(); + map_field_key_comparator_[field] = key_comparator; +} + +void MessageDifferencer::AddIgnoreCriteria(IgnoreCriteria* ignore_criteria) { + ignore_criteria_.push_back(ignore_criteria); +} + +void MessageDifferencer::IgnoreField(const FieldDescriptor* field) { + ignored_fields_.insert(field); +} + +void MessageDifferencer::SetFractionAndMargin(const FieldDescriptor* field, + double fraction, double margin) { + default_field_comparator_.SetFractionAndMargin(field, fraction, margin); +} + +void MessageDifferencer::ReportDifferencesToString(TProtoStringType* output) { + GOOGLE_DCHECK(output) << "Specified output string was NULL"; + + output_string_ = output; + output_string_->clear(); +} + +void MessageDifferencer::ReportDifferencesTo(Reporter* reporter) { + // If an output string is set, clear it to prevent + // it superseding the specified reporter. + if (output_string_) { + output_string_ = NULL; + } + + reporter_ = reporter; +} + +bool MessageDifferencer::FieldBefore(const FieldDescriptor* field1, + const FieldDescriptor* field2) { + // Handle sentinel values (i.e. make sure NULLs are always ordered + // at the end of the list). + if (field1 == NULL) { + return false; + } + + if (field2 == NULL) { + return true; + } + + // Always order fields by their tag number + return (field1->number() < field2->number()); +} + +bool MessageDifferencer::Compare(const Message& message1, + const Message& message2) { + std::vector<SpecificField> parent_fields; + + bool result = false; + // Setup the internal reporter if need be. + if (output_string_) { + io::StringOutputStream output_stream(output_string_); + StreamReporter reporter(&output_stream); + reporter.SetMessages(message1, message2); + reporter_ = &reporter; + result = Compare(message1, message2, &parent_fields); + reporter_ = NULL; + } else { + result = Compare(message1, message2, &parent_fields); + } + return result; +} + +bool MessageDifferencer::CompareWithFields( + const Message& message1, const Message& message2, + const std::vector<const FieldDescriptor*>& message1_fields_arg, + const std::vector<const FieldDescriptor*>& message2_fields_arg) { + if (message1.GetDescriptor() != message2.GetDescriptor()) { + GOOGLE_LOG(DFATAL) << "Comparison between two messages with different " + << "descriptors."; + return false; + } + + std::vector<SpecificField> parent_fields; + + bool result = false; + + FieldDescriptorArray message1_fields(message1_fields_arg.size() + 1); + FieldDescriptorArray message2_fields(message2_fields_arg.size() + 1); + + std::copy(message1_fields_arg.cbegin(), message1_fields_arg.cend(), + message1_fields.begin()); + std::copy(message2_fields_arg.cbegin(), message2_fields_arg.cend(), + message2_fields.begin()); + + // Append sentinel values. + message1_fields[message1_fields_arg.size()] = nullptr; + message2_fields[message2_fields_arg.size()] = nullptr; + + std::sort(message1_fields.begin(), message1_fields.end(), FieldBefore); + std::sort(message2_fields.begin(), message2_fields.end(), FieldBefore); + + // Setup the internal reporter if need be. + if (output_string_) { + io::StringOutputStream output_stream(output_string_); + StreamReporter reporter(&output_stream); + reporter_ = &reporter; + result = CompareRequestedFieldsUsingSettings( + message1, message2, message1_fields, message2_fields, &parent_fields); + reporter_ = NULL; + } else { + result = CompareRequestedFieldsUsingSettings( + message1, message2, message1_fields, message2_fields, &parent_fields); + } + + return result; +} + +bool MessageDifferencer::Compare(const Message& message1, + const Message& message2, + std::vector<SpecificField>* parent_fields) { + const Descriptor* descriptor1 = message1.GetDescriptor(); + const Descriptor* descriptor2 = message2.GetDescriptor(); + if (descriptor1 != descriptor2) { + GOOGLE_LOG(DFATAL) << "Comparison between two messages with different " + << "descriptors. " << descriptor1->full_name() << " vs " + << descriptor2->full_name(); + return false; + } + + // Expand google.protobuf.Any payload if possible. + if (descriptor1->full_name() == internal::kAnyFullTypeName) { + std::unique_ptr<Message> data1; + std::unique_ptr<Message> data2; + if (unpack_any_field_.UnpackAny(message1, &data1) && + unpack_any_field_.UnpackAny(message2, &data2)) { + // Avoid DFATAL for different descriptors in google.protobuf.Any payloads. + if (data1->GetDescriptor() != data2->GetDescriptor()) { + return false; + } + return Compare(*data1, *data2, parent_fields); + } + } + const Reflection* reflection1 = message1.GetReflection(); + const Reflection* reflection2 = message2.GetReflection(); + + bool unknown_compare_result = true; + // Ignore unknown fields in EQUIVALENT mode + if (message_field_comparison_ != EQUIVALENT) { + const UnknownFieldSet& unknown_field_set1 = + reflection1->GetUnknownFields(message1); + const UnknownFieldSet& unknown_field_set2 = + reflection2->GetUnknownFields(message2); + if (!CompareUnknownFields(message1, message2, unknown_field_set1, + unknown_field_set2, parent_fields)) { + if (reporter_ == NULL) { + return false; + } + unknown_compare_result = false; + } + } + + FieldDescriptorArray message1_fields = RetrieveFields(message1, true); + FieldDescriptorArray message2_fields = RetrieveFields(message2, false); + + return CompareRequestedFieldsUsingSettings(message1, message2, + message1_fields, message2_fields, + parent_fields) && + unknown_compare_result; +} + +FieldDescriptorArray MessageDifferencer::RetrieveFields(const Message& message, + bool base_message) { + const Descriptor* descriptor = message.GetDescriptor(); + + tmp_message_fields_.clear(); + tmp_message_fields_.reserve(descriptor->field_count() + 1); + + const Reflection* reflection = message.GetReflection(); + if (descriptor->options().map_entry()) { + if (this->scope_ == PARTIAL && base_message) { + reflection->ListFields(message, &tmp_message_fields_); + } else { + // Map entry fields are always considered present. + for (int i = 0; i < descriptor->field_count(); i++) { + tmp_message_fields_.push_back(descriptor->field(i)); + } + } + } else { + reflection->ListFields(message, &tmp_message_fields_); + } + // Add sentinel values to deal with the + // case where the number of the fields in + // each list are different. + tmp_message_fields_.push_back(nullptr); + + FieldDescriptorArray message_fields(tmp_message_fields_.begin(), + tmp_message_fields_.end()); + + return message_fields; +} + +bool MessageDifferencer::CompareRequestedFieldsUsingSettings( + const Message& message1, const Message& message2, + const FieldDescriptorArray& message1_fields, + const FieldDescriptorArray& message2_fields, + std::vector<SpecificField>* parent_fields) { + if (scope_ == FULL) { + if (message_field_comparison_ == EQUIVALENT) { + // We need to merge the field lists of both messages (i.e. + // we are merely checking for a difference in field values, + // rather than the addition or deletion of fields). + FieldDescriptorArray fields_union = + CombineFields(message1_fields, FULL, message2_fields, FULL); + return CompareWithFieldsInternal(message1, message2, fields_union, + fields_union, parent_fields); + } else { + // Simple equality comparison, use the unaltered field lists. + return CompareWithFieldsInternal(message1, message2, message1_fields, + message2_fields, parent_fields); + } + } else { + if (message_field_comparison_ == EQUIVALENT) { + // We use the list of fields for message1 for both messages when + // comparing. This way, extra fields in message2 are ignored, + // and missing fields in message2 use their default value. + return CompareWithFieldsInternal(message1, message2, message1_fields, + message1_fields, parent_fields); + } else { + // We need to consider the full list of fields for message1 + // but only the intersection for message2. This way, any fields + // only present in message2 will be ignored, but any fields only + // present in message1 will be marked as a difference. + FieldDescriptorArray fields_intersection = + CombineFields(message1_fields, PARTIAL, message2_fields, PARTIAL); + return CompareWithFieldsInternal(message1, message2, message1_fields, + fields_intersection, parent_fields); + } + } +} + +FieldDescriptorArray MessageDifferencer::CombineFields( + const FieldDescriptorArray& fields1, Scope fields1_scope, + const FieldDescriptorArray& fields2, Scope fields2_scope) { + size_t index1 = 0; + size_t index2 = 0; + + tmp_message_fields_.clear(); + + while (index1 < fields1.size() && index2 < fields2.size()) { + const FieldDescriptor* field1 = fields1[index1]; + const FieldDescriptor* field2 = fields2[index2]; + + if (FieldBefore(field1, field2)) { + if (fields1_scope == FULL) { + tmp_message_fields_.push_back(fields1[index1]); + } + ++index1; + } else if (FieldBefore(field2, field1)) { + if (fields2_scope == FULL) { + tmp_message_fields_.push_back(fields2[index2]); + } + ++index2; + } else { + tmp_message_fields_.push_back(fields1[index1]); + ++index1; + ++index2; + } + } + + tmp_message_fields_.push_back(nullptr); + + FieldDescriptorArray combined_fields(tmp_message_fields_.begin(), + tmp_message_fields_.end()); + + return combined_fields; +} + +bool MessageDifferencer::CompareWithFieldsInternal( + const Message& message1, const Message& message2, + const FieldDescriptorArray& message1_fields, + const FieldDescriptorArray& message2_fields, + std::vector<SpecificField>* parent_fields) { + bool isDifferent = false; + int field_index1 = 0; + int field_index2 = 0; + + const Reflection* reflection1 = message1.GetReflection(); + const Reflection* reflection2 = message2.GetReflection(); + + while (true) { + const FieldDescriptor* field1 = message1_fields[field_index1]; + const FieldDescriptor* field2 = message2_fields[field_index2]; + + // Once we have reached sentinel values, we are done the comparison. + if (field1 == NULL && field2 == NULL) { + break; + } + + // Check for differences in the field itself. + if (FieldBefore(field1, field2)) { + // Field 1 is not in the field list for message 2. + if (IsIgnored(message1, message2, field1, *parent_fields)) { + // We are ignoring field1. Report the ignore and move on to + // the next field in message1_fields. + if (reporter_ != NULL) { + SpecificField specific_field; + specific_field.field = field1; + parent_fields->push_back(specific_field); + if (report_ignores_) { + reporter_->ReportIgnored(message1, message2, *parent_fields); + } + parent_fields->pop_back(); + } + ++field_index1; + continue; + } + + if (reporter_ != NULL) { + assert(field1 != NULL); + int count = field1->is_repeated() + ? reflection1->FieldSize(message1, field1) + : 1; + + for (int i = 0; i < count; ++i) { + SpecificField specific_field; + specific_field.field = field1; + if (field1->is_repeated()) { + AddSpecificIndex(&specific_field, message1, field1, i); + } else { + specific_field.index = -1; + } + + parent_fields->push_back(specific_field); + reporter_->ReportDeleted(message1, message2, *parent_fields); + parent_fields->pop_back(); + } + + isDifferent = true; + } else { + return false; + } + + ++field_index1; + continue; + } else if (FieldBefore(field2, field1)) { + // Field 2 is not in the field list for message 1. + if (IsIgnored(message1, message2, field2, *parent_fields)) { + // We are ignoring field2. Report the ignore and move on to + // the next field in message2_fields. + if (reporter_ != NULL) { + SpecificField specific_field; + specific_field.field = field2; + parent_fields->push_back(specific_field); + if (report_ignores_) { + reporter_->ReportIgnored(message1, message2, *parent_fields); + } + parent_fields->pop_back(); + } + ++field_index2; + continue; + } + + if (reporter_ != NULL) { + int count = field2->is_repeated() + ? reflection2->FieldSize(message2, field2) + : 1; + + for (int i = 0; i < count; ++i) { + SpecificField specific_field; + specific_field.field = field2; + if (field2->is_repeated()) { + specific_field.index = i; + AddSpecificNewIndex(&specific_field, message2, field2, i); + } else { + specific_field.index = -1; + specific_field.new_index = -1; + } + + parent_fields->push_back(specific_field); + reporter_->ReportAdded(message1, message2, *parent_fields); + parent_fields->pop_back(); + } + + isDifferent = true; + } else { + return false; + } + + ++field_index2; + continue; + } + + // By this point, field1 and field2 are guaranteed to point to the same + // field, so we can now compare the values. + if (IsIgnored(message1, message2, field1, *parent_fields)) { + // Ignore this field. Report and move on. + if (reporter_ != NULL) { + SpecificField specific_field; + specific_field.field = field1; + parent_fields->push_back(specific_field); + if (report_ignores_) { + reporter_->ReportIgnored(message1, message2, *parent_fields); + } + parent_fields->pop_back(); + } + + ++field_index1; + ++field_index2; + continue; + } + + bool fieldDifferent = false; + assert(field1 != NULL); + if (field1->is_map()) { + fieldDifferent = + !CompareMapField(message1, message2, field1, parent_fields); + } else if (field1->is_repeated()) { + fieldDifferent = + !CompareRepeatedField(message1, message2, field1, parent_fields); + } else { + fieldDifferent = !CompareFieldValueUsingParentFields( + message1, message2, field1, -1, -1, parent_fields); + + if (reporter_ != nullptr) { + SpecificField specific_field; + specific_field.field = field1; + parent_fields->push_back(specific_field); + if (fieldDifferent) { + reporter_->ReportModified(message1, message2, *parent_fields); + isDifferent = true; + } else if (report_matches_) { + reporter_->ReportMatched(message1, message2, *parent_fields); + } + parent_fields->pop_back(); + } + } + if (fieldDifferent) { + if (reporter_ == nullptr) return false; + isDifferent = true; + } + // Increment the field indices. + ++field_index1; + ++field_index2; + } + + return !isDifferent; +} + +bool MessageDifferencer::IsMatch( + const FieldDescriptor* repeated_field, + const MapKeyComparator* key_comparator, const Message* message1, + const Message* message2, const std::vector<SpecificField>& parent_fields, + Reporter* reporter, int index1, int index2) { + std::vector<SpecificField> current_parent_fields(parent_fields); + if (repeated_field->cpp_type() != FieldDescriptor::CPPTYPE_MESSAGE) { + return CompareFieldValueUsingParentFields(*message1, *message2, + repeated_field, index1, index2, + ¤t_parent_fields); + } + // Back up the Reporter and output_string_. They will be reset in the + // following code. + Reporter* backup_reporter = reporter_; + TProtoStringType* output_string = output_string_; + reporter_ = reporter; + output_string_ = NULL; + bool match; + + if (key_comparator == NULL) { + match = CompareFieldValueUsingParentFields(*message1, *message2, + repeated_field, index1, index2, + ¤t_parent_fields); + } else { + const Reflection* reflection1 = message1->GetReflection(); + const Reflection* reflection2 = message2->GetReflection(); + const Message& m1 = + reflection1->GetRepeatedMessage(*message1, repeated_field, index1); + const Message& m2 = + reflection2->GetRepeatedMessage(*message2, repeated_field, index2); + SpecificField specific_field; + specific_field.field = repeated_field; + if (repeated_field->is_map()) { + specific_field.map_entry1 = &m1; + specific_field.map_entry2 = &m2; + } + specific_field.index = index1; + specific_field.new_index = index2; + current_parent_fields.push_back(specific_field); + match = key_comparator->IsMatch(m1, m2, current_parent_fields); + } + + reporter_ = backup_reporter; + output_string_ = output_string; + return match; +} + +bool MessageDifferencer::CompareMapFieldByMapReflection( + const Message& message1, const Message& message2, + const FieldDescriptor* map_field, std::vector<SpecificField>* parent_fields, + DefaultFieldComparator* comparator) { + GOOGLE_DCHECK_EQ(nullptr, reporter_); + GOOGLE_DCHECK(map_field->is_map()); + GOOGLE_DCHECK(map_field_key_comparator_.find(map_field) == + map_field_key_comparator_.end()); + GOOGLE_DCHECK_EQ(repeated_field_comparison_, AS_LIST); + const Reflection* reflection1 = message1.GetReflection(); + const Reflection* reflection2 = message2.GetReflection(); + const int count1 = reflection1->MapSize(message1, map_field); + const int count2 = reflection2->MapSize(message2, map_field); + const bool treated_as_subset = IsTreatedAsSubset(map_field); + if (count1 != count2 && !treated_as_subset) { + return false; + } + if (count1 > count2) { + return false; + } + + // First pass: check whether the same keys are present. + for (MapIterator it = reflection1->MapBegin(const_cast<Message*>(&message1), + map_field), + it_end = reflection1->MapEnd(const_cast<Message*>(&message1), + map_field); + it != it_end; ++it) { + if (!reflection2->ContainsMapKey(message2, map_field, it.GetKey())) { + return false; + } + } + + // Second pass: compare values for matching keys. + const FieldDescriptor* val_des = map_field->message_type()->map_value(); + switch (val_des->cpp_type()) { +#define HANDLE_TYPE(CPPTYPE, METHOD, COMPAREMETHOD) \ + case FieldDescriptor::CPPTYPE_##CPPTYPE: { \ + for (MapIterator it = reflection1->MapBegin( \ + const_cast<Message*>(&message1), map_field), \ + it_end = reflection1->MapEnd( \ + const_cast<Message*>(&message1), map_field); \ + it != it_end; ++it) { \ + MapValueConstRef value2; \ + reflection2->LookupMapValue(message2, map_field, it.GetKey(), &value2); \ + if (!comparator->Compare##COMPAREMETHOD(*val_des, \ + it.GetValueRef().Get##METHOD(), \ + value2.Get##METHOD())) { \ + return false; \ + } \ + } \ + break; \ + } + HANDLE_TYPE(INT32, Int32Value, Int32); + HANDLE_TYPE(INT64, Int64Value, Int64); + HANDLE_TYPE(UINT32, UInt32Value, UInt32); + HANDLE_TYPE(UINT64, UInt64Value, UInt64); + HANDLE_TYPE(DOUBLE, DoubleValue, Double); + HANDLE_TYPE(FLOAT, FloatValue, Float); + HANDLE_TYPE(BOOL, BoolValue, Bool); + HANDLE_TYPE(STRING, StringValue, String); + HANDLE_TYPE(ENUM, EnumValue, Int32); +#undef HANDLE_TYPE + case FieldDescriptor::CPPTYPE_MESSAGE: { + for (MapIterator it = reflection1->MapBegin( + const_cast<Message*>(&message1), map_field); + it != + reflection1->MapEnd(const_cast<Message*>(&message1), map_field); + ++it) { + if (!reflection2->ContainsMapKey(message2, map_field, it.GetKey())) { + return false; + } + bool compare_result; + MapValueConstRef value2; + reflection2->LookupMapValue(message2, map_field, it.GetKey(), &value2); + // Append currently compared field to the end of parent_fields. + SpecificField specific_value_field; + specific_value_field.field = val_des; + parent_fields->push_back(specific_value_field); + compare_result = Compare(it.GetValueRef().GetMessageValue(), + value2.GetMessageValue(), parent_fields); + parent_fields->pop_back(); + if (!compare_result) { + return false; + } + } + break; + } + } + return true; +} + +bool MessageDifferencer::CompareMapField( + const Message& message1, const Message& message2, + const FieldDescriptor* repeated_field, + std::vector<SpecificField>* parent_fields) { + GOOGLE_DCHECK(repeated_field->is_map()); + + // the input FieldDescriptor is guaranteed to be repeated field. + const Reflection* reflection1 = message1.GetReflection(); + const Reflection* reflection2 = message2.GetReflection(); + + // When both map fields are on map, do not sync to repeated field. + if (reflection1->GetMapData(message1, repeated_field)->IsMapValid() && + reflection2->GetMapData(message2, repeated_field)->IsMapValid() && + // TODO(jieluo): Add support for reporter + reporter_ == nullptr && + // Users didn't set custom map field key comparator + map_field_key_comparator_.find(repeated_field) == + map_field_key_comparator_.end() && + // Users didn't set repeated field comparison + repeated_field_comparison_ == AS_LIST && + // Users didn't set their own FieldComparator implementation + field_comparator_kind_ == kFCDefault) { + const FieldDescriptor* key_des = repeated_field->message_type()->map_key(); + const FieldDescriptor* val_des = + repeated_field->message_type()->map_value(); + std::vector<SpecificField> current_parent_fields(*parent_fields); + SpecificField specific_field; + specific_field.field = repeated_field; + current_parent_fields.push_back(specific_field); + if (!IsIgnored(message1, message2, key_des, current_parent_fields) && + !IsIgnored(message1, message2, val_des, current_parent_fields)) { + return CompareMapFieldByMapReflection(message1, message2, repeated_field, + ¤t_parent_fields, + field_comparator_.default_impl); + } + } + + return CompareRepeatedRep(message1, message2, repeated_field, parent_fields); +} + +bool MessageDifferencer::CompareRepeatedField( + const Message& message1, const Message& message2, + const FieldDescriptor* repeated_field, + std::vector<SpecificField>* parent_fields) { + GOOGLE_DCHECK(!repeated_field->is_map()); + return CompareRepeatedRep(message1, message2, repeated_field, parent_fields); +} + +bool MessageDifferencer::CompareRepeatedRep( + const Message& message1, const Message& message2, + const FieldDescriptor* repeated_field, + std::vector<SpecificField>* parent_fields) { + // the input FieldDescriptor is guaranteed to be repeated field. + GOOGLE_DCHECK(repeated_field->is_repeated()); + const Reflection* reflection1 = message1.GetReflection(); + const Reflection* reflection2 = message2.GetReflection(); + + const int count1 = reflection1->FieldSize(message1, repeated_field); + const int count2 = reflection2->FieldSize(message2, repeated_field); + const bool treated_as_subset = IsTreatedAsSubset(repeated_field); + + // If the field is not treated as subset and no detailed reports is needed, + // we do a quick check on the number of the elements to avoid unnecessary + // comparison. + if (count1 != count2 && reporter_ == NULL && !treated_as_subset) { + return false; + } + // A match can never be found if message1 has more items than message2. + if (count1 > count2 && reporter_ == NULL) { + return false; + } + + // These two list are used for store the index of the correspondent + // element in peer repeated field. + std::vector<int> match_list1; + std::vector<int> match_list2; + + const MapKeyComparator* key_comparator = GetMapKeyComparator(repeated_field); + bool smart_list = IsTreatedAsSmartList(repeated_field); + bool simple_list = key_comparator == nullptr && + !IsTreatedAsSet(repeated_field) && + !IsTreatedAsSmartSet(repeated_field) && !smart_list; + + // For simple lists, we avoid matching repeated field indices, saving the + // memory allocations that would otherwise be needed for match_list1 and + // match_list2. + if (!simple_list) { + // Try to match indices of the repeated fields. Return false if match fails. + if (!MatchRepeatedFieldIndices(message1, message2, repeated_field, + key_comparator, *parent_fields, &match_list1, + &match_list2) && + reporter_ == nullptr) { + return false; + } + } + + bool fieldDifferent = false; + SpecificField specific_field; + specific_field.field = repeated_field; + + // At this point, we have already matched pairs of fields (with the reporting + // to be done later). Now to check if the paired elements are different. + int next_unmatched_index = 0; + for (int i = 0; i < count1; i++) { + if (simple_list && i >= count2) { + break; + } + if (!simple_list && match_list1[i] == -1) { + if (smart_list) { + if (reporter_ == nullptr) return false; + AddSpecificIndex(&specific_field, message1, repeated_field, i); + parent_fields->push_back(specific_field); + reporter_->ReportDeleted(message1, message2, *parent_fields); + parent_fields->pop_back(); + fieldDifferent = true; + // Use -2 to mark this element has been reported. + match_list1[i] = -2; + } + continue; + } + if (smart_list) { + for (int j = next_unmatched_index; j < match_list1[i]; ++j) { + GOOGLE_CHECK_LE(0, j); + if (reporter_ == nullptr) return false; + specific_field.index = j; + AddSpecificNewIndex(&specific_field, message2, repeated_field, j); + parent_fields->push_back(specific_field); + reporter_->ReportAdded(message1, message2, *parent_fields); + parent_fields->pop_back(); + fieldDifferent = true; + // Use -2 to mark this element has been reported. + match_list2[j] = -2; + } + } + AddSpecificIndex(&specific_field, message1, repeated_field, i); + if (simple_list) { + AddSpecificNewIndex(&specific_field, message2, repeated_field, i); + } else { + AddSpecificNewIndex(&specific_field, message2, repeated_field, + match_list1[i]); + next_unmatched_index = match_list1[i] + 1; + } + + const bool result = CompareFieldValueUsingParentFields( + message1, message2, repeated_field, i, specific_field.new_index, + parent_fields); + + // If we have found differences, either report them or terminate if + // no reporter is present. Note that ReportModified, ReportMoved, and + // ReportMatched are all mutually exclusive. + if (!result) { + if (reporter_ == NULL) return false; + parent_fields->push_back(specific_field); + reporter_->ReportModified(message1, message2, *parent_fields); + parent_fields->pop_back(); + fieldDifferent = true; + } else if (reporter_ != NULL && + specific_field.index != specific_field.new_index && + !specific_field.field->is_map() && report_moves_) { + parent_fields->push_back(specific_field); + reporter_->ReportMoved(message1, message2, *parent_fields); + parent_fields->pop_back(); + } else if (report_matches_ && reporter_ != NULL) { + parent_fields->push_back(specific_field); + reporter_->ReportMatched(message1, message2, *parent_fields); + parent_fields->pop_back(); + } + } + + // Report any remaining additions or deletions. + for (int i = 0; i < count2; ++i) { + if (!simple_list && match_list2[i] != -1) continue; + if (simple_list && i < count1) continue; + if (!treated_as_subset) { + fieldDifferent = true; + } + + if (reporter_ == NULL) continue; + specific_field.index = i; + AddSpecificNewIndex(&specific_field, message2, repeated_field, i); + parent_fields->push_back(specific_field); + reporter_->ReportAdded(message1, message2, *parent_fields); + parent_fields->pop_back(); + } + + for (int i = 0; i < count1; ++i) { + if (!simple_list && match_list1[i] != -1) continue; + if (simple_list && i < count2) continue; + assert(reporter_ != NULL); + AddSpecificIndex(&specific_field, message1, repeated_field, i); + parent_fields->push_back(specific_field); + reporter_->ReportDeleted(message1, message2, *parent_fields); + parent_fields->pop_back(); + fieldDifferent = true; + } + return !fieldDifferent; +} + +bool MessageDifferencer::CompareFieldValue(const Message& message1, + const Message& message2, + const FieldDescriptor* field, + int index1, int index2) { + return CompareFieldValueUsingParentFields(message1, message2, field, index1, + index2, NULL); +} + +bool MessageDifferencer::CompareFieldValueUsingParentFields( + const Message& message1, const Message& message2, + const FieldDescriptor* field, int index1, int index2, + std::vector<SpecificField>* parent_fields) { + FieldContext field_context(parent_fields); + FieldComparator::ComparisonResult result = GetFieldComparisonResult( + message1, message2, field, index1, index2, &field_context); + + if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE && + result == FieldComparator::RECURSE) { + // Get the nested messages and compare them using one of the Compare + // methods. + const Reflection* reflection1 = message1.GetReflection(); + const Reflection* reflection2 = message2.GetReflection(); + const Message& m1 = + field->is_repeated() + ? reflection1->GetRepeatedMessage(message1, field, index1) + : reflection1->GetMessage(message1, field); + const Message& m2 = + field->is_repeated() + ? reflection2->GetRepeatedMessage(message2, field, index2) + : reflection2->GetMessage(message2, field); + + // parent_fields is used in calls to Reporter methods. + if (parent_fields != NULL) { + // Append currently compared field to the end of parent_fields. + SpecificField specific_field; + specific_field.field = field; + AddSpecificIndex(&specific_field, message1, field, index1); + AddSpecificNewIndex(&specific_field, message2, field, index2); + parent_fields->push_back(specific_field); + const bool compare_result = Compare(m1, m2, parent_fields); + parent_fields->pop_back(); + return compare_result; + } else { + // Recreates parent_fields as if m1 and m2 had no parents. + return Compare(m1, m2); + } + } else { + return (result == FieldComparator::SAME); + } +} + +bool MessageDifferencer::CheckPathChanged( + const std::vector<SpecificField>& field_path) { + for (const SpecificField& specific_field : field_path) { + // Don't check indexes for map entries -- maps are unordered. + if (specific_field.field != nullptr && specific_field.field->is_map()) + continue; + if (specific_field.index != specific_field.new_index) return true; + } + return false; +} + +bool MessageDifferencer::IsTreatedAsSet(const FieldDescriptor* field) { + if (!field->is_repeated()) return false; + if (repeated_field_comparisons_.find(field) != + repeated_field_comparisons_.end()) { + return repeated_field_comparisons_[field] == AS_SET; + } + return GetMapKeyComparator(field) == nullptr && + repeated_field_comparison_ == AS_SET; +} + +bool MessageDifferencer::IsTreatedAsSmartSet(const FieldDescriptor* field) { + if (!field->is_repeated()) return false; + if (repeated_field_comparisons_.find(field) != + repeated_field_comparisons_.end()) { + return repeated_field_comparisons_[field] == AS_SMART_SET; + } + return GetMapKeyComparator(field) == nullptr && + repeated_field_comparison_ == AS_SMART_SET; +} + +bool MessageDifferencer::IsTreatedAsSmartList(const FieldDescriptor* field) { + if (!field->is_repeated()) return false; + if (repeated_field_comparisons_.find(field) != + repeated_field_comparisons_.end()) { + return repeated_field_comparisons_[field] == AS_SMART_LIST; + } + return GetMapKeyComparator(field) == nullptr && + repeated_field_comparison_ == AS_SMART_LIST; +} + +bool MessageDifferencer::IsTreatedAsSubset(const FieldDescriptor* field) { + return scope_ == PARTIAL && + (IsTreatedAsSet(field) || GetMapKeyComparator(field) != NULL); +} + +bool MessageDifferencer::IsIgnored( + const Message& message1, const Message& message2, + const FieldDescriptor* field, + const std::vector<SpecificField>& parent_fields) { + if (ignored_fields_.find(field) != ignored_fields_.end()) { + return true; + } + for (IgnoreCriteria* criteria : ignore_criteria_) { + if (criteria->IsIgnored(message1, message2, field, parent_fields)) { + return true; + } + } + return false; +} + +bool MessageDifferencer::IsUnknownFieldIgnored( + const Message& message1, const Message& message2, + const SpecificField& field, + const std::vector<SpecificField>& parent_fields) { + for (IgnoreCriteria* criteria : ignore_criteria_) { + if (criteria->IsUnknownFieldIgnored(message1, message2, field, + parent_fields)) { + return true; + } + } + return false; +} + +const MessageDifferencer::MapKeyComparator* +MessageDifferencer ::GetMapKeyComparator(const FieldDescriptor* field) const { + if (!field->is_repeated()) return NULL; + FieldKeyComparatorMap::const_iterator it = + map_field_key_comparator_.find(field); + if (it != map_field_key_comparator_.end()) { + return it->second; + } + if (field->is_map()) { + // field cannot already be treated as list or set since TreatAsList() and + // TreatAsSet() call GetMapKeyComparator() and fail if it returns non-NULL. + return &map_entry_key_comparator_; + } + return NULL; +} + +namespace { + +typedef std::pair<int, const UnknownField*> IndexUnknownFieldPair; + +struct UnknownFieldOrdering { + inline bool operator()(const IndexUnknownFieldPair& a, + const IndexUnknownFieldPair& b) const { + if (a.second->number() < b.second->number()) return true; + if (a.second->number() > b.second->number()) return false; + return a.second->type() < b.second->type(); + } +}; + +} // namespace + +bool MessageDifferencer::UnpackAnyField::UnpackAny( + const Message& any, std::unique_ptr<Message>* data) { + const Reflection* reflection = any.GetReflection(); + const FieldDescriptor* type_url_field; + const FieldDescriptor* value_field; + if (!internal::GetAnyFieldDescriptors(any, &type_url_field, &value_field)) { + return false; + } + const TProtoStringType& type_url = reflection->GetString(any, type_url_field); + TProtoStringType full_type_name; + if (!internal::ParseAnyTypeUrl(type_url, &full_type_name)) { + return false; + } + + const Descriptor* desc = + any.GetDescriptor()->file()->pool()->FindMessageTypeByName( + full_type_name); + if (desc == NULL) { + GOOGLE_LOG(INFO) << "Proto type '" << full_type_name << "' not found"; + return false; + } + + if (dynamic_message_factory_ == NULL) { + dynamic_message_factory_.reset(new DynamicMessageFactory()); + } + data->reset(dynamic_message_factory_->GetPrototype(desc)->New()); + TProtoStringType serialized_value = reflection->GetString(any, value_field); + if (!(*data)->ParsePartialFromString(serialized_value)) { + GOOGLE_DLOG(ERROR) << "Failed to parse value for " << full_type_name; + return false; + } + return true; +} + +bool MessageDifferencer::CompareUnknownFields( + const Message& message1, const Message& message2, + const UnknownFieldSet& unknown_field_set1, + const UnknownFieldSet& unknown_field_set2, + std::vector<SpecificField>* parent_field) { + // Ignore unknown fields in EQUIVALENT mode. + if (message_field_comparison_ == EQUIVALENT) return true; + + if (unknown_field_set1.empty() && unknown_field_set2.empty()) { + return true; + } + + bool is_different = false; + + // We first sort the unknown fields by field number and type (in other words, + // in tag order), making sure to preserve ordering of values with the same + // tag. This allows us to report only meaningful differences between the + // two sets -- that is, differing values for the same tag. We use + // IndexUnknownFieldPairs to keep track of the field's original index for + // reporting purposes. + std::vector<IndexUnknownFieldPair> fields1; // unknown_field_set1, sorted + std::vector<IndexUnknownFieldPair> fields2; // unknown_field_set2, sorted + fields1.reserve(unknown_field_set1.field_count()); + fields2.reserve(unknown_field_set2.field_count()); + + for (int i = 0; i < unknown_field_set1.field_count(); i++) { + fields1.push_back(std::make_pair(i, &unknown_field_set1.field(i))); + } + for (int i = 0; i < unknown_field_set2.field_count(); i++) { + fields2.push_back(std::make_pair(i, &unknown_field_set2.field(i))); + } + + UnknownFieldOrdering is_before; + std::stable_sort(fields1.begin(), fields1.end(), is_before); + std::stable_sort(fields2.begin(), fields2.end(), is_before); + + // In order to fill in SpecificField::index, we have to keep track of how + // many values we've seen with the same field number and type. + // current_repeated points at the first field in this range, and + // current_repeated_start{1,2} are the indexes of the first field in the + // range within fields1 and fields2. + const UnknownField* current_repeated = NULL; + int current_repeated_start1 = 0; + int current_repeated_start2 = 0; + + // Now that we have two sorted lists, we can detect fields which appear only + // in one list or the other by traversing them simultaneously. + size_t index1 = 0; + size_t index2 = 0; + while (index1 < fields1.size() || index2 < fields2.size()) { + enum { + ADDITION, + DELETION, + MODIFICATION, + COMPARE_GROUPS, + NO_CHANGE + } change_type; + + // focus_field is the field we're currently reporting on. (In the case + // of a modification, it's the field on the left side.) + const UnknownField* focus_field; + bool match = false; + + if (index2 == fields2.size() || + (index1 < fields1.size() && + is_before(fields1[index1], fields2[index2]))) { + // fields1[index1] is not present in fields2. + change_type = DELETION; + focus_field = fields1[index1].second; + } else if (index1 == fields1.size() || + is_before(fields2[index2], fields1[index1])) { + // fields2[index2] is not present in fields1. + if (scope_ == PARTIAL) { + // Ignore. + ++index2; + continue; + } + change_type = ADDITION; + focus_field = fields2[index2].second; + } else { + // Field type and number are the same. See if the values differ. + change_type = MODIFICATION; + focus_field = fields1[index1].second; + + switch (focus_field->type()) { + case UnknownField::TYPE_VARINT: + match = fields1[index1].second->varint() == + fields2[index2].second->varint(); + break; + case UnknownField::TYPE_FIXED32: + match = fields1[index1].second->fixed32() == + fields2[index2].second->fixed32(); + break; + case UnknownField::TYPE_FIXED64: + match = fields1[index1].second->fixed64() == + fields2[index2].second->fixed64(); + break; + case UnknownField::TYPE_LENGTH_DELIMITED: + match = fields1[index1].second->length_delimited() == + fields2[index2].second->length_delimited(); + break; + case UnknownField::TYPE_GROUP: + // We must deal with this later, after building the SpecificField. + change_type = COMPARE_GROUPS; + break; + } + if (match && change_type != COMPARE_GROUPS) { + change_type = NO_CHANGE; + } + } + + if (current_repeated == NULL || + focus_field->number() != current_repeated->number() || + focus_field->type() != current_repeated->type()) { + // We've started a new repeated field. + current_repeated = focus_field; + current_repeated_start1 = index1; + current_repeated_start2 = index2; + } + + if (change_type == NO_CHANGE && reporter_ == NULL) { + // Fields were already compared and matched and we have no reporter. + ++index1; + ++index2; + continue; + } + + // Build the SpecificField. This is slightly complicated. + SpecificField specific_field; + specific_field.unknown_field_number = focus_field->number(); + specific_field.unknown_field_type = focus_field->type(); + + specific_field.unknown_field_set1 = &unknown_field_set1; + specific_field.unknown_field_set2 = &unknown_field_set2; + + if (change_type != ADDITION) { + specific_field.unknown_field_index1 = fields1[index1].first; + } + if (change_type != DELETION) { + specific_field.unknown_field_index2 = fields2[index2].first; + } + + // Calculate the field index. + if (change_type == ADDITION) { + specific_field.index = index2 - current_repeated_start2; + specific_field.new_index = index2 - current_repeated_start2; + } else { + specific_field.index = index1 - current_repeated_start1; + specific_field.new_index = index2 - current_repeated_start2; + } + + if (IsUnknownFieldIgnored(message1, message2, specific_field, + *parent_field)) { + if (report_ignores_ && reporter_ != NULL) { + parent_field->push_back(specific_field); + reporter_->ReportUnknownFieldIgnored(message1, message2, *parent_field); + parent_field->pop_back(); + } + if (change_type != ADDITION) ++index1; + if (change_type != DELETION) ++index2; + continue; + } + + if (change_type == ADDITION || change_type == DELETION || + change_type == MODIFICATION) { + if (reporter_ == NULL) { + // We found a difference and we have no reporter. + return false; + } + is_different = true; + } + + parent_field->push_back(specific_field); + + switch (change_type) { + case ADDITION: + reporter_->ReportAdded(message1, message2, *parent_field); + ++index2; + break; + case DELETION: + reporter_->ReportDeleted(message1, message2, *parent_field); + ++index1; + break; + case MODIFICATION: + reporter_->ReportModified(message1, message2, *parent_field); + ++index1; + ++index2; + break; + case COMPARE_GROUPS: + if (!CompareUnknownFields( + message1, message2, fields1[index1].second->group(), + fields2[index2].second->group(), parent_field)) { + if (reporter_ == NULL) return false; + is_different = true; + reporter_->ReportModified(message1, message2, *parent_field); + } + ++index1; + ++index2; + break; + case NO_CHANGE: + ++index1; + ++index2; + if (report_matches_) { + reporter_->ReportMatched(message1, message2, *parent_field); + } + } + + parent_field->pop_back(); + } + + return !is_different; +} + +namespace { + +// Find maximum bipartite matching using the argumenting path algorithm. +class MaximumMatcher { + public: + typedef std::function<bool(int, int)> NodeMatchCallback; + // MaximumMatcher takes ownership of the passed in callback and uses it to + // determine whether a node on the left side of the bipartial graph matches + // a node on the right side. count1 is the number of nodes on the left side + // of the graph and count2 to is the number of nodes on the right side. + // Every node is referred to using 0-based indices. + // If a maximum match is found, the result will be stored in match_list1 and + // match_list2. match_list1[i] == j means the i-th node on the left side is + // matched to the j-th node on the right side and match_list2[x] == y means + // the x-th node on the right side is matched to y-th node on the left side. + // match_list1[i] == -1 means the node is not matched. Same with match_list2. + MaximumMatcher(int count1, int count2, NodeMatchCallback callback, + std::vector<int>* match_list1, std::vector<int>* match_list2); + // Find a maximum match and return the number of matched node pairs. + // If early_return is true, this method will return 0 immediately when it + // finds that not all nodes on the left side can be matched. + int FindMaximumMatch(bool early_return); + + private: + // Determines whether the node on the left side of the bipartial graph + // matches the one on the right side. + bool Match(int left, int right); + // Find an argumenting path starting from the node v on the left side. If a + // path can be found, update match_list2_ to reflect the path and return + // true. + bool FindArgumentPathDFS(int v, std::vector<bool>* visited); + + int count1_; + int count2_; + NodeMatchCallback match_callback_; + std::map<std::pair<int, int>, bool> cached_match_results_; + std::vector<int>* match_list1_; + std::vector<int>* match_list2_; + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(MaximumMatcher); +}; + +MaximumMatcher::MaximumMatcher(int count1, int count2, + NodeMatchCallback callback, + std::vector<int>* match_list1, + std::vector<int>* match_list2) + : count1_(count1), + count2_(count2), + match_callback_(std::move(callback)), + match_list1_(match_list1), + match_list2_(match_list2) { + match_list1_->assign(count1, -1); + match_list2_->assign(count2, -1); +} + +int MaximumMatcher::FindMaximumMatch(bool early_return) { + int result = 0; + for (int i = 0; i < count1_; ++i) { + std::vector<bool> visited(count1_); + if (FindArgumentPathDFS(i, &visited)) { + ++result; + } else if (early_return) { + return 0; + } + } + // Backfill match_list1_ as we only filled match_list2_ when finding + // argumenting paths. + for (int i = 0; i < count2_; ++i) { + if ((*match_list2_)[i] != -1) { + (*match_list1_)[(*match_list2_)[i]] = i; + } + } + return result; +} + +bool MaximumMatcher::Match(int left, int right) { + std::pair<int, int> p(left, right); + std::map<std::pair<int, int>, bool>::iterator it = + cached_match_results_.find(p); + if (it != cached_match_results_.end()) { + return it->second; + } + cached_match_results_[p] = match_callback_(left, right); + return cached_match_results_[p]; +} + +bool MaximumMatcher::FindArgumentPathDFS(int v, std::vector<bool>* visited) { + (*visited)[v] = true; + // We try to match those un-matched nodes on the right side first. This is + // the step that the naive greedy matching algorithm uses. In the best cases + // where the greedy algorithm can find a maximum matching, we will always + // find a match in this step and the performance will be identical to the + // greedy algorithm. + for (int i = 0; i < count2_; ++i) { + int matched = (*match_list2_)[i]; + if (matched == -1 && Match(v, i)) { + (*match_list2_)[i] = v; + return true; + } + } + // Then we try those already matched nodes and see if we can find an + // alternative match for the node matched to them. + // The greedy algorithm will stop before this and fail to produce the + // correct result. + for (int i = 0; i < count2_; ++i) { + int matched = (*match_list2_)[i]; + if (matched != -1 && Match(v, i)) { + if (!(*visited)[matched] && FindArgumentPathDFS(matched, visited)) { + (*match_list2_)[i] = v; + return true; + } + } + } + return false; +} + +} // namespace + +bool MessageDifferencer::MatchRepeatedFieldIndices( + const Message& message1, const Message& message2, + const FieldDescriptor* repeated_field, + const MapKeyComparator* key_comparator, + const std::vector<SpecificField>& parent_fields, + std::vector<int>* match_list1, std::vector<int>* match_list2) { + const int count1 = + message1.GetReflection()->FieldSize(message1, repeated_field); + const int count2 = + message2.GetReflection()->FieldSize(message2, repeated_field); + const bool is_treated_as_smart_set = IsTreatedAsSmartSet(repeated_field); + + match_list1->assign(count1, -1); + match_list2->assign(count2, -1); + // Ensure that we don't report differences during the matching process. Since + // field comparators could potentially use this message differencer object to + // perform further comparisons, turn off reporting here and re-enable it + // before returning. + Reporter* reporter = reporter_; + reporter_ = NULL; + NumDiffsReporter num_diffs_reporter; + std::vector<arc_i32> num_diffs_list1; + if (is_treated_as_smart_set) { + num_diffs_list1.assign(count1, std::numeric_limits<arc_i32>::max()); + } + + bool success = true; + // Find potential match if this is a special repeated field. + if (scope_ == PARTIAL) { + // When partial matching is enabled, Compare(a, b) && Compare(a, c) + // doesn't necessarily imply Compare(b, c). Therefore a naive greedy + // algorithm will fail to find a maximum matching. + // Here we use the augmenting path algorithm. + auto callback = [&](int i1, int i2) { + return IsMatch(repeated_field, key_comparator, &message1, &message2, + parent_fields, nullptr, i1, i2); + }; + MaximumMatcher matcher(count1, count2, std::move(callback), match_list1, + match_list2); + // If diff info is not needed, we should end the matching process as + // soon as possible if not all items can be matched. + bool early_return = (reporter == nullptr); + int match_count = matcher.FindMaximumMatch(early_return); + if (match_count != count1 && early_return) return false; + success = success && (match_count == count1); + } else { + int start_offset = 0; + // If the two repeated fields are treated as sets, optimize for the case + // where both start with same items stored in the same order. + if (IsTreatedAsSet(repeated_field) || is_treated_as_smart_set || + IsTreatedAsSmartList(repeated_field)) { + start_offset = std::min(count1, count2); + for (int i = 0; i < count1 && i < count2; i++) { + if (IsMatch(repeated_field, key_comparator, &message1, &message2, + parent_fields, nullptr, i, i)) { + match_list1->at(i) = i; + match_list2->at(i) = i; + } else { + start_offset = i; + break; + } + } + } + for (int i = start_offset; i < count1; ++i) { + // Indicates any matched elements for this repeated field. + bool match = false; + int matched_j = -1; + + for (int j = start_offset; j < count2; j++) { + if (match_list2->at(j) != -1) { + if (!is_treated_as_smart_set || num_diffs_list1[i] == 0 || + num_diffs_list1[match_list2->at(j)] == 0) { + continue; + } + } + + if (is_treated_as_smart_set) { + num_diffs_reporter.Reset(); + match = IsMatch(repeated_field, key_comparator, &message1, &message2, + parent_fields, &num_diffs_reporter, i, j); + } else { + match = IsMatch(repeated_field, key_comparator, &message1, &message2, + parent_fields, nullptr, i, j); + } + + if (is_treated_as_smart_set) { + if (match) { + num_diffs_list1[i] = 0; + } else if (repeated_field->cpp_type() == + FieldDescriptor::CPPTYPE_MESSAGE) { + // Replace with the one with fewer diffs. + const arc_i32 num_diffs = num_diffs_reporter.GetNumDiffs(); + if (num_diffs < num_diffs_list1[i]) { + // If j has been already matched to some element, ensure the + // current num_diffs is smaller. + if (match_list2->at(j) == -1 || + num_diffs < num_diffs_list1[match_list2->at(j)]) { + num_diffs_list1[i] = num_diffs; + match = true; + } + } + } + } + + if (match) { + matched_j = j; + if (!is_treated_as_smart_set || num_diffs_list1[i] == 0) { + break; + } + } + } + + match = (matched_j != -1); + if (match) { + if (is_treated_as_smart_set && match_list2->at(matched_j) != -1) { + // This is to revert the previously matched index in list2. + match_list1->at(match_list2->at(matched_j)) = -1; + match = false; + } + match_list1->at(i) = matched_j; + match_list2->at(matched_j) = i; + } + if (!match && reporter == nullptr) return false; + success = success && match; + } + } + + if (IsTreatedAsSmartList(repeated_field)) { + match_indices_for_smart_list_callback_(match_list1, match_list2); + } + + reporter_ = reporter; + + return success; +} + +FieldComparator::ComparisonResult MessageDifferencer::GetFieldComparisonResult( + const Message& message1, const Message& message2, + const FieldDescriptor* field, int index1, int index2, + const FieldContext* field_context) { + FieldComparator* comparator = field_comparator_kind_ == kFCBase + ? field_comparator_.base + : field_comparator_.default_impl; + return comparator->Compare(message1, message2, field, index1, index2, + field_context); +} + +// =========================================================================== + +MessageDifferencer::Reporter::Reporter() {} +MessageDifferencer::Reporter::~Reporter() {} + +// =========================================================================== + +MessageDifferencer::MapKeyComparator::MapKeyComparator() {} +MessageDifferencer::MapKeyComparator::~MapKeyComparator() {} + +// =========================================================================== + +MessageDifferencer::IgnoreCriteria::IgnoreCriteria() {} +MessageDifferencer::IgnoreCriteria::~IgnoreCriteria() {} + +// =========================================================================== + +// Note that the printer's delimiter is not used, because if we are given a +// printer, we don't know its delimiter. +MessageDifferencer::StreamReporter::StreamReporter( + io::ZeroCopyOutputStream* output) + : printer_(new io::Printer(output, '$')), + delete_printer_(true), + report_modified_aggregates_(false), + message1_(nullptr), + message2_(nullptr) {} + +MessageDifferencer::StreamReporter::StreamReporter(io::Printer* printer) + : printer_(printer), + delete_printer_(false), + report_modified_aggregates_(false), + message1_(nullptr), + message2_(nullptr) {} + +MessageDifferencer::StreamReporter::~StreamReporter() { + if (delete_printer_) delete printer_; +} + +void MessageDifferencer::StreamReporter::PrintPath( + const std::vector<SpecificField>& field_path, bool left_side) { + for (size_t i = 0; i < field_path.size(); ++i) { + SpecificField specific_field = field_path[i]; + + if (specific_field.field != nullptr && + specific_field.field->name() == "value") { + // check to see if this the value label of a map value. If so, skip it + // because it isn't meaningful + if (i > 0 && field_path[i - 1].field->is_map()) { + continue; + } + } + if (i > 0) { + printer_->Print("."); + } + if (specific_field.field != NULL) { + if (specific_field.field->is_extension()) { + printer_->Print("($name$)", "name", specific_field.field->full_name()); + } else { + printer_->PrintRaw(specific_field.field->name()); + } + + if (specific_field.field->is_map()) { + PrintMapKey(left_side, specific_field); + continue; + } + } else { + printer_->PrintRaw(StrCat(specific_field.unknown_field_number)); + } + if (left_side && specific_field.index >= 0) { + printer_->Print("[$name$]", "name", StrCat(specific_field.index)); + } + if (!left_side && specific_field.new_index >= 0) { + printer_->Print("[$name$]", "name", + StrCat(specific_field.new_index)); + } + } +} + + +void MessageDifferencer::StreamReporter::PrintValue( + const Message& message, const std::vector<SpecificField>& field_path, + bool left_side) { + const SpecificField& specific_field = field_path.back(); + const FieldDescriptor* field = specific_field.field; + if (field != NULL) { + TProtoStringType output; + int index = left_side ? specific_field.index : specific_field.new_index; + if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) { + const Reflection* reflection = message.GetReflection(); + const Message& field_message = + field->is_repeated() + ? reflection->GetRepeatedMessage(message, field, index) + : reflection->GetMessage(message, field); + const FieldDescriptor* fd = nullptr; + + if (field->is_map() && message1_ != nullptr && message2_ != nullptr) { + fd = field_message.GetDescriptor()->field(1); + if (fd->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) { + output = field_message.GetReflection() + ->GetMessage(field_message, fd) + .ShortDebugString(); + } else { + TextFormat::PrintFieldValueToString(field_message, fd, -1, &output); + } + } else { + output = field_message.ShortDebugString(); + } + if (output.empty()) { + printer_->Print("{ }"); + } else { + if ((fd != nullptr) && + (fd->cpp_type() != FieldDescriptor::CPPTYPE_MESSAGE)) { + printer_->PrintRaw(output); + } else { + printer_->Print("{ $name$ }", "name", output); + } + } + } else { + TextFormat::PrintFieldValueToString(message, field, index, &output); + printer_->PrintRaw(output); + } + } else { + const UnknownFieldSet* unknown_fields = + (left_side ? specific_field.unknown_field_set1 + : specific_field.unknown_field_set2); + const UnknownField* unknown_field = + &unknown_fields->field(left_side ? specific_field.unknown_field_index1 + : specific_field.unknown_field_index2); + PrintUnknownFieldValue(unknown_field); + } +} + +void MessageDifferencer::StreamReporter::PrintUnknownFieldValue( + const UnknownField* unknown_field) { + GOOGLE_CHECK(unknown_field != NULL) << " Cannot print NULL unknown_field."; + + TProtoStringType output; + switch (unknown_field->type()) { + case UnknownField::TYPE_VARINT: + output = StrCat(unknown_field->varint()); + break; + case UnknownField::TYPE_FIXED32: + output = StrCat( + "0x", strings::Hex(unknown_field->fixed32(), strings::ZERO_PAD_8)); + break; + case UnknownField::TYPE_FIXED64: + output = StrCat( + "0x", strings::Hex(unknown_field->fixed64(), strings::ZERO_PAD_16)); + break; + case UnknownField::TYPE_LENGTH_DELIMITED: + output = StringPrintf( + "\"%s\"", CEscape(unknown_field->length_delimited()).c_str()); + break; + case UnknownField::TYPE_GROUP: + // TODO(kenton): Print the contents of the group like we do for + // messages. Requires an equivalent of ShortDebugString() for + // UnknownFieldSet. + output = "{ ... }"; + break; + } + printer_->PrintRaw(output); +} + +void MessageDifferencer::StreamReporter::Print(const TProtoStringType& str) { + printer_->Print(str.c_str()); +} + +void MessageDifferencer::StreamReporter::PrintMapKey( + bool left_side, const SpecificField& specific_field) { + if (message1_ == nullptr || message2_ == nullptr) { + GOOGLE_LOG(INFO) << "PrintPath cannot log map keys; " + "use SetMessages to provide the messages " + "being compared prior to any processing."; + return; + } + + const Message* found_message = + left_side ? specific_field.map_entry1 : specific_field.map_entry2; + TProtoStringType key_string = ""; + if (found_message != nullptr) { + // NB: the map key is always the first field + const FieldDescriptor* fd = found_message->GetDescriptor()->field(0); + if (fd->cpp_type() == FieldDescriptor::CPPTYPE_STRING) { + // Not using PrintFieldValueToString for strings to avoid extra + // characters + key_string = found_message->GetReflection()->GetString( + *found_message, found_message->GetDescriptor()->field(0)); + } else { + TextFormat::PrintFieldValueToString(*found_message, fd, -1, &key_string); + } + if (key_string.empty()) { + key_string = "''"; + } + printer_->PrintRaw(StrCat("[", key_string, "]")); + } +} + +void MessageDifferencer::StreamReporter::ReportAdded( + const Message& /*message1*/, const Message& message2, + const std::vector<SpecificField>& field_path) { + printer_->Print("added: "); + PrintPath(field_path, false); + printer_->Print(": "); + PrintValue(message2, field_path, false); + printer_->Print("\n"); // Print for newlines. +} + +void MessageDifferencer::StreamReporter::ReportDeleted( + const Message& message1, const Message& /*message2*/, + const std::vector<SpecificField>& field_path) { + printer_->Print("deleted: "); + PrintPath(field_path, true); + printer_->Print(": "); + PrintValue(message1, field_path, true); + printer_->Print("\n"); // Print for newlines +} + +void MessageDifferencer::StreamReporter::ReportModified( + const Message& message1, const Message& message2, + const std::vector<SpecificField>& field_path) { + if (!report_modified_aggregates_ && field_path.back().field == NULL) { + if (field_path.back().unknown_field_type == UnknownField::TYPE_GROUP) { + // Any changes to the subfields have already been printed. + return; + } + } else if (!report_modified_aggregates_) { + if (field_path.back().field->cpp_type() == + FieldDescriptor::CPPTYPE_MESSAGE) { + // Any changes to the subfields have already been printed. + return; + } + } + + printer_->Print("modified: "); + PrintPath(field_path, true); + if (CheckPathChanged(field_path)) { + printer_->Print(" -> "); + PrintPath(field_path, false); + } + printer_->Print(": "); + PrintValue(message1, field_path, true); + printer_->Print(" -> "); + PrintValue(message2, field_path, false); + printer_->Print("\n"); // Print for newlines. +} + +void MessageDifferencer::StreamReporter::ReportMoved( + const Message& message1, const Message& /*message2*/, + const std::vector<SpecificField>& field_path) { + printer_->Print("moved: "); + PrintPath(field_path, true); + printer_->Print(" -> "); + PrintPath(field_path, false); + printer_->Print(" : "); + PrintValue(message1, field_path, true); + printer_->Print("\n"); // Print for newlines. +} + +void MessageDifferencer::StreamReporter::ReportMatched( + const Message& message1, const Message& /*message2*/, + const std::vector<SpecificField>& field_path) { + printer_->Print("matched: "); + PrintPath(field_path, true); + if (CheckPathChanged(field_path)) { + printer_->Print(" -> "); + PrintPath(field_path, false); + } + printer_->Print(" : "); + PrintValue(message1, field_path, true); + printer_->Print("\n"); // Print for newlines. +} + +void MessageDifferencer::StreamReporter::ReportIgnored( + const Message& /*message1*/, const Message& /*message2*/, + const std::vector<SpecificField>& field_path) { + printer_->Print("ignored: "); + PrintPath(field_path, true); + if (CheckPathChanged(field_path)) { + printer_->Print(" -> "); + PrintPath(field_path, false); + } + printer_->Print("\n"); // Print for newlines. +} + +void MessageDifferencer::StreamReporter::SetMessages(const Message& message1, + const Message& message2) { + message1_ = &message1; + message2_ = &message2; +} + +void MessageDifferencer::StreamReporter::ReportUnknownFieldIgnored( + const Message& /*message1*/, const Message& /*message2*/, + const std::vector<SpecificField>& field_path) { + printer_->Print("ignored: "); + PrintPath(field_path, true); + if (CheckPathChanged(field_path)) { + printer_->Print(" -> "); + PrintPath(field_path, false); + } + printer_->Print("\n"); // Print for newlines. +} + +MessageDifferencer::MapKeyComparator* +MessageDifferencer::CreateMultipleFieldsMapKeyComparator( + const std::vector<std::vector<const FieldDescriptor*> >& key_field_paths) { + return new MultipleFieldsMapKeyComparator(this, key_field_paths); +} + +} // namespace util +} // namespace protobuf +} // namespace google diff --git a/contrib/libs/protobuf_old/src/google/protobuf/util/message_differencer.h b/contrib/libs/protobuf_old/src/google/protobuf/util/message_differencer.h new file mode 100644 index 0000000000..cd569075cd --- /dev/null +++ b/contrib/libs/protobuf_old/src/google/protobuf/util/message_differencer.h @@ -0,0 +1,976 @@ +// 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: jschorr@google.com (Joseph Schorr) +// Based on original Protocol Buffers design by +// Sanjay Ghemawat, Jeff Dean, and others. +// +// This file defines static methods and classes for comparing Protocol +// Messages. +// +// Aug. 2008: Added Unknown Fields Comparison for messages. +// Aug. 2009: Added different options to compare repeated fields. +// Apr. 2010: Moved field comparison to FieldComparator +// Sep. 2020: Added option to output map keys in path + +#ifndef GOOGLE_PROTOBUF_UTIL_MESSAGE_DIFFERENCER_H__ +#define GOOGLE_PROTOBUF_UTIL_MESSAGE_DIFFERENCER_H__ + +#include <functional> +#include <map> +#include <memory> +#include <set> +#include <string> +#include <vector> + +#include <google/protobuf/descriptor.h> // FieldDescriptor +#include <google/protobuf/message.h> // Message +#include <google/protobuf/unknown_field_set.h> +#include <google/protobuf/util/field_comparator.h> + +// Always include as last one, otherwise it can break compilation +#include <google/protobuf/port_def.inc> + +namespace google { +namespace protobuf { + +class DynamicMessageFactory; +class FieldDescriptor; + +namespace io { +class ZeroCopyOutputStream; +class Printer; +} // namespace io + +namespace util { + +class DefaultFieldComparator; +class FieldContext; // declared below MessageDifferencer + +// Defines a collection of field descriptors. +// In case of internal google codebase we are using absl::FixedArray instead +// of vector. It significantly speeds up proto comparison (by ~30%) by +// reducing the number of malloc/free operations +typedef std::vector<const FieldDescriptor*> FieldDescriptorArray; + +// A basic differencer that can be used to determine +// the differences between two specified Protocol Messages. If any differences +// are found, the Compare method will return false, and any differencer reporter +// specified via ReportDifferencesTo will have its reporting methods called (see +// below for implementation of the report). Based off of the original +// ProtocolDifferencer implementation in //net/proto/protocol-differencer.h +// (Thanks Todd!). +// +// MessageDifferencer REQUIRES that compared messages be the same type, defined +// as messages that share the same descriptor. If not, the behavior of this +// class is undefined. +// +// People disagree on what MessageDifferencer should do when asked to compare +// messages with different descriptors. Some people think it should always +// return false. Others expect it to try to look for similar fields and +// compare them anyway -- especially if the descriptors happen to be identical. +// If we chose either of these behaviors, some set of people would find it +// surprising, and could end up writing code expecting the other behavior +// without realizing their error. Therefore, we forbid that usage. +// +// This class is implemented based on the proto2 reflection. The performance +// should be good enough for normal usages. However, for places where the +// performance is extremely sensitive, there are several alternatives: +// - Comparing serialized string +// Downside: false negatives (there are messages that are the same but their +// serialized strings are different). +// - Equals code generator by compiler plugin (net/proto2/contrib/equals_plugin) +// Downside: more generated code; maintenance overhead for the additional rule +// (must be in sync with the original proto_library). +// +// Note on handling of google.protobuf.Any: MessageDifferencer automatically +// unpacks Any::value into a Message and compares its individual fields. +// Messages encoded in a repeated Any cannot be compared using TreatAsMap. +// +// Note on thread-safety: MessageDifferencer is *not* thread-safe. You need to +// guard it with a lock to use the same MessageDifferencer instance from +// multiple threads. Note that it's fine to call static comparison methods +// (like MessageDifferencer::Equals) concurrently, but it's not recommended for +// performance critical code as it leads to extra allocations. +class PROTOBUF_EXPORT MessageDifferencer { + public: + // Determines whether the supplied messages are equal. Equality is defined as + // all fields within the two messages being set to the same value. Primitive + // fields and strings are compared by value while embedded messages/groups + // are compared as if via a recursive call. Use Compare() with IgnoreField() + // if some fields should be ignored in the comparison. Use Compare() with + // TreatAsSet() if there are repeated fields where ordering does not matter. + // + // This method REQUIRES that the two messages have the same + // Descriptor (message1.GetDescriptor() == message2.GetDescriptor()). + static bool Equals(const Message& message1, const Message& message2); + + // Determines whether the supplied messages are equivalent. Equivalency is + // defined as all fields within the two messages having the same value. This + // differs from the Equals method above in that fields with default values + // are considered set to said value automatically. For details on how default + // values are defined for each field type, see: + // https://developers.google.com/protocol-buffers/docs/proto?csw=1#optional. + // Also, Equivalent() ignores unknown fields. Use IgnoreField() and Compare() + // if some fields should be ignored in the comparison. + // + // This method REQUIRES that the two messages have the same + // Descriptor (message1.GetDescriptor() == message2.GetDescriptor()). + static bool Equivalent(const Message& message1, const Message& message2); + + // Determines whether the supplied messages are approximately equal. + // Approximate equality is defined as all fields within the two messages + // being approximately equal. Primitive (non-float) fields and strings are + // compared by value, floats are compared using MathUtil::AlmostEquals() and + // embedded messages/groups are compared as if via a recursive call. Use + // IgnoreField() and Compare() if some fields should be ignored in the + // comparison. + // + // This method REQUIRES that the two messages have the same + // Descriptor (message1.GetDescriptor() == message2.GetDescriptor()). + static bool ApproximatelyEquals(const Message& message1, + const Message& message2); + + // Determines whether the supplied messages are approximately equivalent. + // Approximate equivalency is defined as all fields within the two messages + // being approximately equivalent. As in + // MessageDifferencer::ApproximatelyEquals, primitive (non-float) fields and + // strings are compared by value, floats are compared using + // MathUtil::AlmostEquals() and embedded messages/groups are compared as if + // via a recursive call. However, fields with default values are considered + // set to said value, as per MessageDiffencer::Equivalent. Use IgnoreField() + // and Compare() if some fields should be ignored in the comparison. + // + // This method REQUIRES that the two messages have the same + // Descriptor (message1.GetDescriptor() == message2.GetDescriptor()). + static bool ApproximatelyEquivalent(const Message& message1, + const Message& message2); + + // Identifies an individual field in a message instance. Used for field_path, + // below. + struct SpecificField { + // For known fields, "field" is filled in and "unknown_field_number" is -1. + // For unknown fields, "field" is NULL, "unknown_field_number" is the field + // number, and "unknown_field_type" is its type. + const FieldDescriptor* field = nullptr; + int unknown_field_number = -1; + UnknownField::Type unknown_field_type = UnknownField::Type::TYPE_VARINT; + + // If this a repeated field, "index" is the index within it. For unknown + // fields, this is the index of the field among all unknown fields of the + // same field number and type. + int index = -1; + + // If "field" is a repeated field which is being treated as a map or + // a set (see TreatAsMap() and TreatAsSet(), below), new_index indicates + // the index the position to which the element has moved. If the element + // has not moved, "new_index" will have the same value as "index". + int new_index = -1; + + // If "field" is a map field, point to the map entry. + const Message* map_entry1 = nullptr; + const Message* map_entry2 = nullptr; + + // For unknown fields, these are the pointers to the UnknownFieldSet + // containing the unknown fields. In certain cases (e.g. proto1's + // MessageSet, or nested groups of unknown fields), these may differ from + // the messages' internal UnknownFieldSets. + const UnknownFieldSet* unknown_field_set1 = nullptr; + const UnknownFieldSet* unknown_field_set2 = nullptr; + + // For unknown fields, these are the index of the field within the + // UnknownFieldSets. One or the other will be -1 when + // reporting an addition or deletion. + int unknown_field_index1 = -1; + int unknown_field_index2 = -1; + }; + + // Abstract base class from which all MessageDifferencer + // reporters derive. The five Report* methods below will be called when + // a field has been added, deleted, modified, moved, or matched. The third + // argument is a vector of FieldDescriptor pointers which describes the chain + // of fields that was taken to find the current field. For example, for a + // field found in an embedded message, the vector will contain two + // FieldDescriptors. The first will be the field of the embedded message + // itself and the second will be the actual field in the embedded message + // that was added/deleted/modified. + // Fields will be reported in PostTraversalOrder. + // For example, given following proto, if both baz and quux are changed. + // foo { + // bar { + // baz: 1 + // quux: 2 + // } + // } + // ReportModified will be invoked with following order: + // 1. foo.bar.baz or foo.bar.quux + // 2. foo.bar.quux or foo.bar.baz + // 2. foo.bar + // 3. foo + class PROTOBUF_EXPORT Reporter { + public: + Reporter(); + virtual ~Reporter(); + + // Reports that a field has been added into Message2. + virtual void ReportAdded(const Message& message1, const Message& message2, + const std::vector<SpecificField>& field_path) = 0; + + // Reports that a field has been deleted from Message1. + virtual void ReportDeleted( + const Message& message1, const Message& message2, + const std::vector<SpecificField>& field_path) = 0; + + // Reports that the value of a field has been modified. + virtual void ReportModified( + const Message& message1, const Message& message2, + const std::vector<SpecificField>& field_path) = 0; + + // Reports that a repeated field has been moved to another location. This + // only applies when using TreatAsSet or TreatAsMap() -- see below. Also + // note that for any given field, ReportModified and ReportMoved are + // mutually exclusive. If a field has been both moved and modified, then + // only ReportModified will be called. + virtual void ReportMoved( + const Message& /* message1 */, const Message& /* message2 */, + const std::vector<SpecificField>& /* field_path */) {} + + // Reports that two fields match. Useful for doing side-by-side diffs. + // This function is mutually exclusive with ReportModified and ReportMoved. + // Note that you must call set_report_matches(true) before calling Compare + // to make use of this function. + virtual void ReportMatched( + const Message& /* message1 */, const Message& /* message2 */, + const std::vector<SpecificField>& /* field_path */) {} + + // Reports that two fields would have been compared, but the + // comparison has been skipped because the field was marked as + // 'ignored' using IgnoreField(). This function is mutually + // exclusive with all the other Report() functions. + // + // The contract of ReportIgnored is slightly different than the + // other Report() functions, in that |field_path.back().index| is + // always equal to -1, even if the last field is repeated. This is + // because while the other Report() functions indicate where in a + // repeated field the action (Addition, Deletion, etc...) + // happened, when a repeated field is 'ignored', the differencer + // simply calls ReportIgnored on the repeated field as a whole and + // moves on without looking at its individual elements. + // + // Furthermore, ReportIgnored() does not indicate whether the + // fields were in fact equal or not, as Compare() does not inspect + // these fields at all. It is up to the Reporter to decide whether + // the fields are equal or not (perhaps with a second call to + // Compare()), if it cares. + virtual void ReportIgnored( + const Message& /* message1 */, const Message& /* message2 */, + const std::vector<SpecificField>& /* field_path */) {} + + // Report that an unknown field is ignored. (see comment above). + // Note this is a different function since the last SpecificField in field + // path has a null field. This could break existing Reporter. + virtual void ReportUnknownFieldIgnored( + const Message& /* message1 */, const Message& /* message2 */, + const std::vector<SpecificField>& /* field_path */) {} + + private: + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(Reporter); + }; + + // MapKeyComparator is used to determine if two elements have the same key + // when comparing elements of a repeated field as a map. + class PROTOBUF_EXPORT MapKeyComparator { + public: + MapKeyComparator(); + virtual ~MapKeyComparator(); + + virtual bool IsMatch( + const Message& /* message1 */, const Message& /* message2 */, + const std::vector<SpecificField>& /* parent_fields */) const { + GOOGLE_CHECK(false) << "IsMatch() is not implemented."; + return false; + } + + private: + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(MapKeyComparator); + }; + + // Abstract base class from which all IgnoreCriteria derive. + // By adding IgnoreCriteria more complex ignore logic can be implemented. + // IgnoreCriteria are registered with AddIgnoreCriteria. For each compared + // field IsIgnored is called on each added IgnoreCriteria until one returns + // true or all return false. + // IsIgnored is called for fields where at least one side has a value. + class PROTOBUF_EXPORT IgnoreCriteria { + public: + IgnoreCriteria(); + virtual ~IgnoreCriteria(); + + // Returns true if the field should be ignored. + virtual bool IsIgnored( + const Message& /* message1 */, const Message& /* message2 */, + const FieldDescriptor* /* field */, + const std::vector<SpecificField>& /* parent_fields */) = 0; + + // Returns true if the unknown field should be ignored. + // Note: This will be called for unknown fields as well in which case + // field.field will be null. + virtual bool IsUnknownFieldIgnored( + const Message& /* message1 */, const Message& /* message2 */, + const SpecificField& /* field */, + const std::vector<SpecificField>& /* parent_fields */) { + return false; + } + }; + + // To add a Reporter, construct default here, then use ReportDifferencesTo or + // ReportDifferencesToString. + explicit MessageDifferencer(); + + ~MessageDifferencer(); + + enum MessageFieldComparison { + EQUAL, // Fields must be present in both messages + // for the messages to be considered the same. + EQUIVALENT, // Fields with default values are considered set + // for comparison purposes even if not explicitly + // set in the messages themselves. Unknown fields + // are ignored. + }; + + enum Scope { + FULL, // All fields of both messages are considered in the comparison. + PARTIAL // Only fields present in the first message are considered; fields + // set only in the second message will be skipped during + // comparison. + }; + + // DEPRECATED. Use FieldComparator::FloatComparison instead. + enum FloatComparison { + EXACT, // Floats and doubles are compared exactly. + APPROXIMATE // Floats and doubles are compared using the + // MathUtil::AlmostEquals method. + }; + + enum RepeatedFieldComparison { + AS_LIST, // Repeated fields are compared in order. Differing values at + // the same index are reported using ReportModified(). If the + // repeated fields have different numbers of elements, the + // unpaired elements are reported using ReportAdded() or + // ReportDeleted(). + AS_SET, // Treat all the repeated fields as sets. + // See TreatAsSet(), as below. + AS_SMART_LIST, // Similar to AS_SET, but preserve the order and find the + // longest matching sequence from the first matching + // element. To use an optimal solution, call + // SetMatchIndicesForSmartListCallback() to pass it in. + AS_SMART_SET, // Similar to AS_SET, but match elements with fewest diffs. + }; + + // The elements of the given repeated field will be treated as a set for + // diffing purposes, so different orderings of the same elements will be + // considered equal. Elements which are present on both sides of the + // comparison but which have changed position will be reported with + // ReportMoved(). Elements which only exist on one side or the other are + // reported with ReportAdded() and ReportDeleted() regardless of their + // positions. ReportModified() is never used for this repeated field. If + // the only differences between the compared messages is that some fields + // have been moved, then the comparison returns true. + // + // Note that despite the name of this method, this is really + // comparison as multisets: if one side of the comparison has a duplicate + // in the repeated field but the other side doesn't, this will count as + // a mismatch. + // + // If the scope of comparison is set to PARTIAL, then in addition to what's + // above, extra values added to repeated fields of the second message will + // not cause the comparison to fail. + // + // Note that set comparison is currently O(k * n^2) (where n is the total + // number of elements, and k is the average size of each element). In theory + // it could be made O(n * k) with a more complex hashing implementation. Feel + // free to contribute one if the current implementation is too slow for you. + // If partial matching is also enabled, the time complexity will be O(k * n^2 + // + n^3) in which n^3 is the time complexity of the maximum matching + // algorithm. + // + // REQUIRES: field->is_repeated() and field not registered with TreatAsMap* + void TreatAsSet(const FieldDescriptor* field); + void TreatAsSmartSet(const FieldDescriptor* field); + + // The elements of the given repeated field will be treated as a list for + // diffing purposes, so different orderings of the same elements will NOT be + // considered equal. + // + // REQUIRES: field->is_repeated() and field not registered with TreatAsMap* + void TreatAsList(const FieldDescriptor* field); + // Note that the complexity is similar to treating as SET. + void TreatAsSmartList(const FieldDescriptor* field); + + // The elements of the given repeated field will be treated as a map for + // diffing purposes, with |key| being the map key. Thus, elements with the + // same key will be compared even if they do not appear at the same index. + // Differences are reported similarly to TreatAsSet(), except that + // ReportModified() is used to report elements with the same key but + // different values. Note that if an element is both moved and modified, + // only ReportModified() will be called. As with TreatAsSet, if the only + // differences between the compared messages is that some fields have been + // moved, then the comparison returns true. See TreatAsSet for notes on + // performance. + // + // REQUIRES: field->is_repeated() + // REQUIRES: field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE + // REQUIRES: key->containing_type() == field->message_type() + void TreatAsMap(const FieldDescriptor* field, const FieldDescriptor* key); + // Same as TreatAsMap except that this method will use multiple fields as + // the key in comparison. All specified fields in 'key_fields' should be + // present in the compared elements. Two elements will be treated as having + // the same key iff they have the same value for every specified field. There + // are two steps in the comparison process. The first one is key matching. + // Every element from one message will be compared to every element from + // the other message. Only fields in 'key_fields' are compared in this step + // to decide if two elements have the same key. The second step is value + // comparison. Those pairs of elements with the same key (with equal value + // for every field in 'key_fields') will be compared in this step. + // Time complexity of the first step is O(s * m * n ^ 2) where s is the + // average size of the fields specified in 'key_fields', m is the number of + // fields in 'key_fields' and n is the number of elements. If partial + // matching is enabled, an extra O(n^3) will be incured by the maximum + // matching algorithm. The second step is O(k * n) where k is the average + // size of each element. + void TreatAsMapWithMultipleFieldsAsKey( + const FieldDescriptor* field, + const std::vector<const FieldDescriptor*>& key_fields); + // Same as TreatAsMapWithMultipleFieldsAsKey, except that each of the field + // do not necessarily need to be a direct subfield. Each element in + // key_field_paths indicate a path from the message being compared, listing + // successive subfield to reach the key field. + // + // REQUIRES: + // for key_field_path in key_field_paths: + // key_field_path[0]->containing_type() == field->message_type() + // for i in [0, key_field_path.size() - 1): + // key_field_path[i+1]->containing_type() == + // key_field_path[i]->message_type() + // key_field_path[i]->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE + // !key_field_path[i]->is_repeated() + void TreatAsMapWithMultipleFieldPathsAsKey( + const FieldDescriptor* field, + const std::vector<std::vector<const FieldDescriptor*> >& key_field_paths); + + // Uses a custom MapKeyComparator to determine if two elements have the same + // key when comparing a repeated field as a map. + // The caller is responsible to delete the key_comparator. + // This method varies from TreatAsMapWithMultipleFieldsAsKey only in the + // first key matching step. Rather than comparing some specified fields, it + // will invoke the IsMatch method of the given 'key_comparator' to decide if + // two elements have the same key. + void TreatAsMapUsingKeyComparator(const FieldDescriptor* field, + const MapKeyComparator* key_comparator); + + // Initiates and returns a new instance of MultipleFieldsMapKeyComparator. + MapKeyComparator* CreateMultipleFieldsMapKeyComparator( + const std::vector<std::vector<const FieldDescriptor*> >& key_field_paths); + + // Add a custom ignore criteria that is evaluated in addition to the + // ignored fields added with IgnoreField. + // Takes ownership of ignore_criteria. + void AddIgnoreCriteria(IgnoreCriteria* ignore_criteria); + + // Indicates that any field with the given descriptor should be + // ignored for the purposes of comparing two messages. This applies + // to fields nested in the message structure as well as top level + // ones. When the MessageDifferencer encounters an ignored field, + // ReportIgnored is called on the reporter, if one is specified. + // + // The only place where the field's 'ignored' status is not applied is when + // it is being used as a key in a field passed to TreatAsMap or is one of + // the fields passed to TreatAsMapWithMultipleFieldsAsKey. + // In this case it is compared in key matching but after that it's ignored + // in value comparison. + void IgnoreField(const FieldDescriptor* field); + + // Sets the field comparator used to determine differences between protocol + // buffer fields. By default it's set to a DefaultFieldComparator instance. + // MessageDifferencer doesn't take ownership over the passed object. + // Note that this method must be called before Compare for the comparator to + // be used. + void set_field_comparator(FieldComparator* comparator); +#ifdef PROTOBUF_FUTURE_BREAKING_CHANGES + void set_field_comparator(DefaultFieldComparator* comparator); +#endif // PROTOBUF_FUTURE_BREAKING_CHANGES + + // DEPRECATED. Pass a DefaultFieldComparator instance instead. + // Sets the fraction and margin for the float comparison of a given field. + // Uses MathUtil::WithinFractionOrMargin to compare the values. + // NOTE: this method does nothing if differencer's field comparator has been + // set to a custom object. + // + // REQUIRES: field->cpp_type == FieldDescriptor::CPPTYPE_DOUBLE or + // field->cpp_type == FieldDescriptor::CPPTYPE_FLOAT + // REQUIRES: float_comparison_ == APPROXIMATE + void SetFractionAndMargin(const FieldDescriptor* field, double fraction, + double margin); + + // Sets the type of comparison (as defined in the MessageFieldComparison + // enumeration above) that is used by this differencer when determining how + // to compare fields in messages. + void set_message_field_comparison(MessageFieldComparison comparison); + + // Tells the differencer whether or not to report matches. This method must + // be called before Compare. The default for a new differencer is false. + void set_report_matches(bool report_matches) { + report_matches_ = report_matches; + } + + // Tells the differencer whether or not to report moves (in a set or map + // repeated field). This method must be called before Compare. The default for + // a new differencer is true. + void set_report_moves(bool report_moves) { report_moves_ = report_moves; } + + // Tells the differencer whether or not to report ignored values. This method + // must be called before Compare. The default for a new differencer is true. + void set_report_ignores(bool report_ignores) { + report_ignores_ = report_ignores; + } + + // Sets the scope of the comparison (as defined in the Scope enumeration + // above) that is used by this differencer when determining which fields to + // compare between the messages. + void set_scope(Scope scope); + + // Returns the current scope used by this differencer. + Scope scope(); + + // DEPRECATED. Pass a DefaultFieldComparator instance instead. + // Sets the type of comparison (as defined in the FloatComparison enumeration + // above) that is used by this differencer when comparing float (and double) + // fields in messages. + // NOTE: this method does nothing if differencer's field comparator has been + // set to a custom object. + void set_float_comparison(FloatComparison comparison); + + // Sets the type of comparison for repeated field (as defined in the + // RepeatedFieldComparison enumeration above) that is used by this + // differencer when compare repeated fields in messages. + void set_repeated_field_comparison(RepeatedFieldComparison comparison); + + // Returns the current repeated field comparison used by this differencer. + RepeatedFieldComparison repeated_field_comparison(); + + // Compares the two specified messages, returning true if they are the same, + // false otherwise. If this method returns false, any changes between the + // two messages will be reported if a Reporter was specified via + // ReportDifferencesTo (see also ReportDifferencesToString). + // + // This method REQUIRES that the two messages have the same + // Descriptor (message1.GetDescriptor() == message2.GetDescriptor()). + bool Compare(const Message& message1, const Message& message2); + + // Same as above, except comparing only the list of fields specified by the + // two vectors of FieldDescriptors. + bool CompareWithFields( + const Message& message1, const Message& message2, + const std::vector<const FieldDescriptor*>& message1_fields, + const std::vector<const FieldDescriptor*>& message2_fields); + + // Automatically creates a reporter that will output the differences + // found (if any) to the specified output string pointer. Note that this + // method must be called before Compare. + void ReportDifferencesToString(TProtoStringType* output); + + // Tells the MessageDifferencer to report differences via the specified + // reporter. Note that this method must be called before Compare for + // the reporter to be used. It is the responsibility of the caller to delete + // this object. + // If the provided pointer equals NULL, the MessageDifferencer stops reporting + // differences to any previously set reporters or output strings. + void ReportDifferencesTo(Reporter* reporter); + + private: + // Class for processing Any deserialization. This logic is used by both the + // MessageDifferencer and StreamReporter classes. + class UnpackAnyField { + private: + std::unique_ptr<DynamicMessageFactory> dynamic_message_factory_; + + public: + UnpackAnyField() = default; + ~UnpackAnyField() = default; + // If "any" is of type google.protobuf.Any, extract its payload using + // DynamicMessageFactory and store in "data". + bool UnpackAny(const Message& any, std::unique_ptr<Message>* data); + }; + + public: + // An implementation of the MessageDifferencer Reporter that outputs + // any differences found in human-readable form to the supplied + // ZeroCopyOutputStream or Printer. If a printer is used, the delimiter + // *must* be '$'. + // + // WARNING: this reporter does not necessarily flush its output until it is + // destroyed. As a result, it is not safe to assume the output is valid or + // complete until after you destroy the reporter. For example, if you use a + // StreamReporter to write to a StringOutputStream, the target string may + // contain uninitialized data until the reporter is destroyed. + class PROTOBUF_EXPORT StreamReporter : public Reporter { + public: + explicit StreamReporter(io::ZeroCopyOutputStream* output); + explicit StreamReporter(io::Printer* printer); // delimiter '$' + ~StreamReporter() override; + + // When set to true, the stream reporter will also output aggregates nodes + // (i.e. messages and groups) whose subfields have been modified. When + // false, will only report the individual subfields. Defaults to false. + void set_report_modified_aggregates(bool report) { + report_modified_aggregates_ = report; + } + + // The following are implementations of the methods described above. + + void ReportAdded(const Message& message1, const Message& message2, + const std::vector<SpecificField>& field_path) override; + + void ReportDeleted(const Message& message1, const Message& message2, + const std::vector<SpecificField>& field_path) override; + + void ReportModified(const Message& message1, const Message& message2, + const std::vector<SpecificField>& field_path) override; + + void ReportMoved(const Message& message1, const Message& message2, + const std::vector<SpecificField>& field_path) override; + + void ReportMatched(const Message& message1, const Message& message2, + const std::vector<SpecificField>& field_path) override; + + void ReportIgnored(const Message& message1, const Message& message2, + const std::vector<SpecificField>& field_path) override; + + void ReportUnknownFieldIgnored( + const Message& message1, const Message& message2, + const std::vector<SpecificField>& field_path) override; + + // Messages that are being compared must be provided to StreamReporter prior + // to processing + void SetMessages(const Message& message1, const Message& message2); + + protected: + // Prints the specified path of fields to the buffer. + virtual void PrintPath(const std::vector<SpecificField>& field_path, + bool left_side); + + // Prints the value of fields to the buffer. left_side is true if the + // given message is from the left side of the comparison, false if it + // was the right. This is relevant only to decide whether to follow + // unknown_field_index1 or unknown_field_index2 when an unknown field + // is encountered in field_path. + virtual void PrintValue(const Message& message, + const std::vector<SpecificField>& field_path, + bool left_side); + + // Prints the specified path of unknown fields to the buffer. + virtual void PrintUnknownFieldValue(const UnknownField* unknown_field); + + // Just print a string + void Print(const TProtoStringType& str); + + private: + // helper function for PrintPath that contains logic for printing maps + void PrintMapKey(bool left_side, const SpecificField& specific_field); + + io::Printer* printer_; + bool delete_printer_; + bool report_modified_aggregates_; + const Message* message1_; + const Message* message2_; + MessageDifferencer::UnpackAnyField unpack_any_field_; + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(StreamReporter); + }; + + private: + friend class SimpleFieldComparator; + + // A MapKeyComparator to be used in TreatAsMapUsingKeyComparator. + // Implementation of this class needs to do field value comparison which + // relies on some private methods of MessageDifferencer. That's why this + // class is declared as a nested class of MessageDifferencer. + class MultipleFieldsMapKeyComparator; + + // A MapKeyComparator for use with map_entries. + class PROTOBUF_EXPORT MapEntryKeyComparator : public MapKeyComparator { + public: + explicit MapEntryKeyComparator(MessageDifferencer* message_differencer); + bool IsMatch( + const Message& message1, const Message& message2, + const std::vector<SpecificField>& parent_fields) const override; + + private: + MessageDifferencer* message_differencer_; + }; + + // Returns true if field1's number() is less than field2's. + static bool FieldBefore(const FieldDescriptor* field1, + const FieldDescriptor* field2); + + // Retrieve all the set fields, including extensions. + FieldDescriptorArray RetrieveFields(const Message& message, + bool base_message); + + // Combine the two lists of fields into the combined_fields output vector. + // All fields present in both lists will always be included in the combined + // list. Fields only present in one of the lists will only appear in the + // combined list if the corresponding fields_scope option is set to FULL. + FieldDescriptorArray CombineFields(const FieldDescriptorArray& fields1, + Scope fields1_scope, + const FieldDescriptorArray& fields2, + Scope fields2_scope); + + // Internal version of the Compare method which performs the actual + // comparison. The parent_fields vector is a vector containing field + // descriptors of all fields accessed to get to this comparison operation + // (i.e. if the current message is an embedded message, the parent_fields + // vector will contain the field that has this embedded message). + bool Compare(const Message& message1, const Message& message2, + std::vector<SpecificField>* parent_fields); + + // Compares all the unknown fields in two messages. + bool CompareUnknownFields(const Message& message1, const Message& message2, + const UnknownFieldSet&, const UnknownFieldSet&, + std::vector<SpecificField>* parent_fields); + + // Compares the specified messages for the requested field lists. The field + // lists are modified depending on comparison settings, and then passed to + // CompareWithFieldsInternal. + bool CompareRequestedFieldsUsingSettings( + const Message& message1, const Message& message2, + const FieldDescriptorArray& message1_fields, + const FieldDescriptorArray& message2_fields, + std::vector<SpecificField>* parent_fields); + + // Compares the specified messages with the specified field lists. + bool CompareWithFieldsInternal(const Message& message1, + const Message& message2, + const FieldDescriptorArray& message1_fields, + const FieldDescriptorArray& message2_fields, + std::vector<SpecificField>* parent_fields); + + // Compares the repeated fields, and report the error. + bool CompareRepeatedField(const Message& message1, const Message& message2, + const FieldDescriptor* field, + std::vector<SpecificField>* parent_fields); + + // Compares map fields, and report the error. + bool CompareMapField(const Message& message1, const Message& message2, + const FieldDescriptor* field, + std::vector<SpecificField>* parent_fields); + + // Helper for CompareRepeatedField and CompareMapField: compares and reports + // differences element-wise. This is the implementation for non-map fields, + // and can also compare map fields by using the underlying representation. + bool CompareRepeatedRep(const Message& message1, const Message& message2, + const FieldDescriptor* field, + std::vector<SpecificField>* parent_fields); + + // Helper for CompareMapField: compare the map fields using map reflection + // instead of sync to repeated. + bool CompareMapFieldByMapReflection(const Message& message1, + const Message& message2, + const FieldDescriptor* field, + std::vector<SpecificField>* parent_fields, + DefaultFieldComparator* comparator); + + // Shorthand for CompareFieldValueUsingParentFields with NULL parent_fields. + bool CompareFieldValue(const Message& message1, const Message& message2, + const FieldDescriptor* field, int index1, int index2); + + // Compares the specified field on the two messages, returning + // true if they are the same, false otherwise. For repeated fields, + // this method only compares the value in the specified index. This method + // uses Compare functions to recurse into submessages. + // The parent_fields vector is used in calls to a Reporter instance calls. + // It can be NULL, in which case the MessageDifferencer will create new + // list of parent messages if it needs to recursively compare the given field. + // To avoid confusing users you should not set it to NULL unless you modified + // Reporter to handle the change of parent_fields correctly. + bool CompareFieldValueUsingParentFields( + const Message& message1, const Message& message2, + const FieldDescriptor* field, int index1, int index2, + std::vector<SpecificField>* parent_fields); + + // Compares the specified field on the two messages, returning comparison + // result, as returned by appropriate FieldComparator. + FieldComparator::ComparisonResult GetFieldComparisonResult( + const Message& message1, const Message& message2, + const FieldDescriptor* field, int index1, int index2, + const FieldContext* field_context); + + // Check if the two elements in the repeated field are match to each other. + // if the key_comprator is NULL, this function returns true when the two + // elements are equal. + bool IsMatch(const FieldDescriptor* repeated_field, + const MapKeyComparator* key_comparator, const Message* message1, + const Message* message2, + const std::vector<SpecificField>& parent_fields, + Reporter* reporter, int index1, int index2); + + // Returns true when this repeated field has been configured to be treated + // as a Set / SmartSet / SmartList. + bool IsTreatedAsSet(const FieldDescriptor* field); + bool IsTreatedAsSmartSet(const FieldDescriptor* field); + + bool IsTreatedAsSmartList(const FieldDescriptor* field); + // When treating as SMART_LIST, it uses MatchIndicesPostProcessorForSmartList + // by default to find the longest matching sequence from the first matching + // element. The callback takes two vectors showing the matching indices from + // the other vector, where -1 means an unmatch. + void SetMatchIndicesForSmartListCallback( + std::function<void(std::vector<int>*, std::vector<int>*)> callback); + + // Returns true when this repeated field is to be compared as a subset, ie. + // has been configured to be treated as a set or map and scope is set to + // PARTIAL. + bool IsTreatedAsSubset(const FieldDescriptor* field); + + // Returns true if this field is to be ignored when this + // MessageDifferencer compares messages. + bool IsIgnored(const Message& message1, const Message& message2, + const FieldDescriptor* field, + const std::vector<SpecificField>& parent_fields); + + // Returns true if this unknown field is to be ignored when this + // MessageDifferencer compares messages. + bool IsUnknownFieldIgnored(const Message& message1, const Message& message2, + const SpecificField& field, + const std::vector<SpecificField>& parent_fields); + + // Returns MapKeyComparator* when this field has been configured to be treated + // as a map or its is_map() return true. If not, returns NULL. + const MapKeyComparator* GetMapKeyComparator( + const FieldDescriptor* field) const; + + // Attempts to match indices of a repeated field, so that the contained values + // match. Clears output vectors and sets their values to indices of paired + // messages, ie. if message1[0] matches message2[1], then match_list1[0] == 1 + // and match_list2[1] == 0. The unmatched indices are indicated by -1. + // Assumes the repeated field is not treated as a simple list. + // This method returns false if the match failed. However, it doesn't mean + // that the comparison succeeds when this method returns true (you need to + // double-check in this case). + bool MatchRepeatedFieldIndices( + const Message& message1, const Message& message2, + const FieldDescriptor* repeated_field, + const MapKeyComparator* key_comparator, + const std::vector<SpecificField>& parent_fields, + std::vector<int>* match_list1, std::vector<int>* match_list2); + + // Checks if index is equal to new_index in all the specific fields. + static bool CheckPathChanged(const std::vector<SpecificField>& parent_fields); + + // CHECKs that the given repeated field can be compared according to + // new_comparison. + void CheckRepeatedFieldComparisons( + const FieldDescriptor* field, + const RepeatedFieldComparison& new_comparison); + + // Defines a map between field descriptors and their MapKeyComparators. + // Used for repeated fields when they are configured as TreatAsMap. + typedef std::map<const FieldDescriptor*, const MapKeyComparator*> + FieldKeyComparatorMap; + + // Defines a set to store field descriptors. Used for repeated fields when + // they are configured as TreatAsSet. + typedef std::set<const FieldDescriptor*> FieldSet; + typedef std::map<const FieldDescriptor*, RepeatedFieldComparison> FieldMap; + + Reporter* reporter_; + DefaultFieldComparator default_field_comparator_; + MessageFieldComparison message_field_comparison_; + Scope scope_; + RepeatedFieldComparison repeated_field_comparison_; + + FieldMap repeated_field_comparisons_; + // Keeps track of MapKeyComparators that are created within + // MessageDifferencer. These MapKeyComparators should be deleted + // before MessageDifferencer is destroyed. + // When TreatAsMap or TreatAsMapWithMultipleFieldsAsKey is called, we don't + // store the supplied FieldDescriptors directly. Instead, a new + // MapKeyComparator is created for comparison purpose. + std::vector<MapKeyComparator*> owned_key_comparators_; + FieldKeyComparatorMap map_field_key_comparator_; + MapEntryKeyComparator map_entry_key_comparator_; + std::vector<IgnoreCriteria*> ignore_criteria_; + // Reused multiple times in RetrieveFields to avoid extra allocations + std::vector<const FieldDescriptor*> tmp_message_fields_; + + FieldSet ignored_fields_; + + union { + DefaultFieldComparator* default_impl; + FieldComparator* base; + } field_comparator_ = {&default_field_comparator_}; + enum { kFCDefault, kFCBase } field_comparator_kind_ = kFCDefault; + + bool report_matches_; + bool report_moves_; + bool report_ignores_; + + TProtoStringType* output_string_; + + // Callback to post-process the matched indices to support SMART_LIST. + std::function<void(std::vector<int>*, std::vector<int>*)> + match_indices_for_smart_list_callback_; + + MessageDifferencer::UnpackAnyField unpack_any_field_; + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(MessageDifferencer); +}; + +// This class provides extra information to the FieldComparator::Compare +// function. +class PROTOBUF_EXPORT FieldContext { + public: + explicit FieldContext( + std::vector<MessageDifferencer::SpecificField>* parent_fields) + : parent_fields_(parent_fields) {} + + std::vector<MessageDifferencer::SpecificField>* parent_fields() const { + return parent_fields_; + } + + private: + std::vector<MessageDifferencer::SpecificField>* parent_fields_; +}; + +} // namespace util +} // namespace protobuf +} // namespace google + +#include <google/protobuf/port_undef.inc> + +#endif // GOOGLE_PROTOBUF_UTIL_MESSAGE_DIFFERENCER_H__ diff --git a/contrib/libs/protobuf_old/src/google/protobuf/util/time_util.cc b/contrib/libs/protobuf_old/src/google/protobuf/util/time_util.cc new file mode 100644 index 0000000000..d30a4bffbc --- /dev/null +++ b/contrib/libs/protobuf_old/src/google/protobuf/util/time_util.cc @@ -0,0 +1,511 @@ +// 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 <google/protobuf/util/time_util.h> + +#include <cstdint> + +#include <google/protobuf/stubs/stringprintf.h> +#include <google/protobuf/stubs/strutil.h> +#include <google/protobuf/duration.pb.h> +#include <google/protobuf/timestamp.pb.h> +#include <google/protobuf/stubs/int128.h> +#include <google/protobuf/stubs/time.h> + +// Must go after other includes. +#include <google/protobuf/port_def.inc> + +namespace google { +namespace protobuf { +namespace util { + +using google::protobuf::Duration; +using google::protobuf::Timestamp; + +namespace { +static const int kNanosPerSecond = 1000000000; +static const int kMicrosPerSecond = 1000000; +static const int kMillisPerSecond = 1000; +static const int kNanosPerMillisecond = 1000000; +static const int kNanosPerMicrosecond = 1000; +static const int kSecondsPerMinute = 60; // Note that we ignore leap seconds. +static const int kSecondsPerHour = 3600; + +template <typename T> +T CreateNormalized(arc_i64 seconds, arc_i64 nanos); + +template <> +Timestamp CreateNormalized(arc_i64 seconds, arc_i64 nanos) { + // Make sure nanos is in the range. + if (nanos <= -kNanosPerSecond || nanos >= kNanosPerSecond) { + seconds += nanos / kNanosPerSecond; + nanos = nanos % kNanosPerSecond; + } + // For Timestamp nanos should be in the range [0, 999999999] + if (nanos < 0) { + seconds -= 1; + nanos += kNanosPerSecond; + } + GOOGLE_DCHECK(seconds >= TimeUtil::kTimestampMinSeconds && + seconds <= TimeUtil::kTimestampMaxSeconds); + Timestamp result; + result.set_seconds(seconds); + result.set_nanos(static_cast<arc_i32>(nanos)); + return result; +} + +template <> +Duration CreateNormalized(arc_i64 seconds, arc_i64 nanos) { + // Make sure nanos is in the range. + if (nanos <= -kNanosPerSecond || nanos >= kNanosPerSecond) { + seconds += nanos / kNanosPerSecond; + nanos = nanos % kNanosPerSecond; + } + // nanos should have the same sign as seconds. + if (seconds < 0 && nanos > 0) { + seconds += 1; + nanos -= kNanosPerSecond; + } else if (seconds > 0 && nanos < 0) { + seconds -= 1; + nanos += kNanosPerSecond; + } + GOOGLE_DCHECK(seconds >= TimeUtil::kDurationMinSeconds && + seconds <= TimeUtil::kDurationMaxSeconds); + Duration result; + result.set_seconds(seconds); + result.set_nanos(static_cast<arc_i32>(nanos)); + return result; +} + +// Format nanoseconds with either 3, 6, or 9 digits depending on the required +// precision to represent the exact value. +TProtoStringType FormatNanos(arc_i32 nanos) { + if (nanos % kNanosPerMillisecond == 0) { + return StringPrintf("%03d", nanos / kNanosPerMillisecond); + } else if (nanos % kNanosPerMicrosecond == 0) { + return StringPrintf("%06d", nanos / kNanosPerMicrosecond); + } else { + return StringPrintf("%09d", nanos); + } +} + +TProtoStringType FormatTime(int64 seconds, int32 nanos) { + return ::google::protobuf::internal::FormatTime(seconds, nanos); +} + +bool ParseTime(const TProtoStringType& value, int64* seconds, int32* nanos) { + return ::google::protobuf::internal::ParseTime(value, seconds, nanos); +} + +void CurrentTime(int64* seconds, int32* nanos) { + return ::google::protobuf::internal::GetCurrentTime(seconds, nanos); +} + +// Truncates the remainder part after division. +arc_i64 RoundTowardZero(arc_i64 value, arc_i64 divider) { + arc_i64 result = value / divider; + arc_i64 remainder = value % divider; + // Before C++11, the sign of the remainder is implementation dependent if + // any of the operands is negative. Here we try to enforce C++11's "rounded + // toward zero" semantics. For example, for (-5) / 2 an implementation may + // give -3 as the result with the remainder being 1. This function ensures + // we always return -2 (closer to zero) regardless of the implementation. + if (result < 0 && remainder > 0) { + return result + 1; + } else { + return result; + } +} +} // namespace + +// Actually define these static const integers. Required by C++ standard (but +// some compilers don't like it). +#ifndef _MSC_VER +const arc_i64 TimeUtil::kTimestampMinSeconds; +const arc_i64 TimeUtil::kTimestampMaxSeconds; +const arc_i64 TimeUtil::kDurationMaxSeconds; +const arc_i64 TimeUtil::kDurationMinSeconds; +#endif // !_MSC_VER + +TProtoStringType TimeUtil::ToString(const Timestamp& timestamp) { + return FormatTime(timestamp.seconds(), timestamp.nanos()); +} + +bool TimeUtil::FromString(const TProtoStringType& value, Timestamp* timestamp) { + arc_i64 seconds; + arc_i32 nanos; + if (!ParseTime(value, &seconds, &nanos)) { + return false; + } + *timestamp = CreateNormalized<Timestamp>(seconds, nanos); + return true; +} + +Timestamp TimeUtil::GetCurrentTime() { + arc_i64 seconds; + arc_i32 nanos; + CurrentTime(&seconds, &nanos); + return CreateNormalized<Timestamp>(seconds, nanos); +} + +Timestamp TimeUtil::GetEpoch() { return Timestamp(); } + +TProtoStringType TimeUtil::ToString(const Duration& duration) { + TProtoStringType result; + arc_i64 seconds = duration.seconds(); + arc_i32 nanos = duration.nanos(); + if (seconds < 0 || nanos < 0) { + result += "-"; + seconds = -seconds; + nanos = -nanos; + } + result += StrCat(seconds); + if (nanos != 0) { + result += "." + FormatNanos(nanos); + } + result += "s"; + return result; +} + +static arc_i64 Pow(arc_i64 x, int y) { + arc_i64 result = 1; + for (int i = 0; i < y; ++i) { + result *= x; + } + return result; +} + +bool TimeUtil::FromString(const TProtoStringType& value, Duration* duration) { + if (value.length() <= 1 || value[value.length() - 1] != 's') { + return false; + } + bool negative = (value[0] == '-'); + int sign_length = (negative ? 1 : 0); + // Parse the duration value as two integers rather than a float value + // to avoid precision loss. + TProtoStringType seconds_part, nanos_part; + size_t pos = value.find_last_of('.'); + if (pos == TProtoStringType::npos) { + seconds_part = value.substr(sign_length, value.length() - 1 - sign_length); + nanos_part = "0"; + } else { + seconds_part = value.substr(sign_length, pos - sign_length); + nanos_part = value.substr(pos + 1, value.length() - pos - 2); + } + char* end; + arc_i64 seconds = strto64(seconds_part.c_str(), &end, 10); + if (end != seconds_part.c_str() + seconds_part.length()) { + return false; + } + arc_i64 nanos = strto64(nanos_part.c_str(), &end, 10); + if (end != nanos_part.c_str() + nanos_part.length()) { + return false; + } + nanos = nanos * Pow(10, 9 - nanos_part.length()); + if (negative) { + // If a Duration is negative, both seconds and nanos should be negative. + seconds = -seconds; + nanos = -nanos; + } + duration->set_seconds(seconds); + duration->set_nanos(static_cast<arc_i32>(nanos)); + return true; +} + +Duration TimeUtil::NanosecondsToDuration(arc_i64 nanos) { + return CreateNormalized<Duration>(nanos / kNanosPerSecond, + nanos % kNanosPerSecond); +} + +Duration TimeUtil::MicrosecondsToDuration(arc_i64 micros) { + return CreateNormalized<Duration>( + micros / kMicrosPerSecond, + (micros % kMicrosPerSecond) * kNanosPerMicrosecond); +} + +Duration TimeUtil::MillisecondsToDuration(arc_i64 millis) { + return CreateNormalized<Duration>( + millis / kMillisPerSecond, + (millis % kMillisPerSecond) * kNanosPerMillisecond); +} + +Duration TimeUtil::SecondsToDuration(arc_i64 seconds) { + return CreateNormalized<Duration>(seconds, 0); +} + +Duration TimeUtil::MinutesToDuration(arc_i64 minutes) { + return CreateNormalized<Duration>(minutes * kSecondsPerMinute, 0); +} + +Duration TimeUtil::HoursToDuration(arc_i64 hours) { + return CreateNormalized<Duration>(hours * kSecondsPerHour, 0); +} + +arc_i64 TimeUtil::DurationToNanoseconds(const Duration& duration) { + return duration.seconds() * kNanosPerSecond + duration.nanos(); +} + +arc_i64 TimeUtil::DurationToMicroseconds(const Duration& duration) { + return duration.seconds() * kMicrosPerSecond + + RoundTowardZero(duration.nanos(), kNanosPerMicrosecond); +} + +arc_i64 TimeUtil::DurationToMilliseconds(const Duration& duration) { + return duration.seconds() * kMillisPerSecond + + RoundTowardZero(duration.nanos(), kNanosPerMillisecond); +} + +arc_i64 TimeUtil::DurationToSeconds(const Duration& duration) { + return duration.seconds(); +} + +arc_i64 TimeUtil::DurationToMinutes(const Duration& duration) { + return RoundTowardZero(duration.seconds(), kSecondsPerMinute); +} + +arc_i64 TimeUtil::DurationToHours(const Duration& duration) { + return RoundTowardZero(duration.seconds(), kSecondsPerHour); +} + +Timestamp TimeUtil::NanosecondsToTimestamp(arc_i64 nanos) { + return CreateNormalized<Timestamp>(nanos / kNanosPerSecond, + nanos % kNanosPerSecond); +} + +Timestamp TimeUtil::MicrosecondsToTimestamp(arc_i64 micros) { + return CreateNormalized<Timestamp>( + micros / kMicrosPerSecond, + micros % kMicrosPerSecond * kNanosPerMicrosecond); +} + +Timestamp TimeUtil::MillisecondsToTimestamp(arc_i64 millis) { + return CreateNormalized<Timestamp>( + millis / kMillisPerSecond, + millis % kMillisPerSecond * kNanosPerMillisecond); +} + +Timestamp TimeUtil::SecondsToTimestamp(arc_i64 seconds) { + return CreateNormalized<Timestamp>(seconds, 0); +} + +arc_i64 TimeUtil::TimestampToNanoseconds(const Timestamp& timestamp) { + return timestamp.seconds() * kNanosPerSecond + timestamp.nanos(); +} + +arc_i64 TimeUtil::TimestampToMicroseconds(const Timestamp& timestamp) { + return timestamp.seconds() * kMicrosPerSecond + + RoundTowardZero(timestamp.nanos(), kNanosPerMicrosecond); +} + +arc_i64 TimeUtil::TimestampToMilliseconds(const Timestamp& timestamp) { + return timestamp.seconds() * kMillisPerSecond + + RoundTowardZero(timestamp.nanos(), kNanosPerMillisecond); +} + +arc_i64 TimeUtil::TimestampToSeconds(const Timestamp& timestamp) { + return timestamp.seconds(); +} + +Timestamp TimeUtil::TimeTToTimestamp(time_t value) { + return CreateNormalized<Timestamp>(static_cast<arc_i64>(value), 0); +} + +time_t TimeUtil::TimestampToTimeT(const Timestamp& value) { + return static_cast<time_t>(value.seconds()); +} + +Timestamp TimeUtil::TimevalToTimestamp(const timeval& value) { + return CreateNormalized<Timestamp>(value.tv_sec, + value.tv_usec * kNanosPerMicrosecond); +} + +timeval TimeUtil::TimestampToTimeval(const Timestamp& value) { + timeval result; + result.tv_sec = value.seconds(); + result.tv_usec = RoundTowardZero(value.nanos(), kNanosPerMicrosecond); + return result; +} + +Duration TimeUtil::TimevalToDuration(const timeval& value) { + return CreateNormalized<Duration>(value.tv_sec, + value.tv_usec * kNanosPerMicrosecond); +} + +timeval TimeUtil::DurationToTimeval(const Duration& value) { + timeval result; + result.tv_sec = value.seconds(); + result.tv_usec = RoundTowardZero(value.nanos(), kNanosPerMicrosecond); + // timeval.tv_usec's range is [0, 1000000) + if (result.tv_usec < 0) { + result.tv_sec -= 1; + result.tv_usec += kMicrosPerSecond; + } + return result; +} + +} // namespace util +} // namespace protobuf +} // namespace google + +namespace google { +namespace protobuf { +namespace { +using ::PROTOBUF_NAMESPACE_ID::util::CreateNormalized; +using ::PROTOBUF_NAMESPACE_ID::util::kNanosPerSecond; + +// Convert a Duration to uint128. +void ToUint128(const Duration& value, uint128* result, bool* negative) { + if (value.seconds() < 0 || value.nanos() < 0) { + *negative = true; + *result = static_cast<arc_ui64>(-value.seconds()); + *result = *result * kNanosPerSecond + static_cast<arc_ui32>(-value.nanos()); + } else { + *negative = false; + *result = static_cast<arc_ui64>(value.seconds()); + *result = *result * kNanosPerSecond + static_cast<arc_ui32>(value.nanos()); + } +} + +void ToDuration(const uint128& value, bool negative, Duration* duration) { + arc_i64 seconds = + static_cast<arc_i64>(Uint128Low64(value / kNanosPerSecond)); + arc_i32 nanos = + static_cast<arc_i32>(Uint128Low64(value % kNanosPerSecond)); + if (negative) { + seconds = -seconds; + nanos = -nanos; + } + duration->set_seconds(seconds); + duration->set_nanos(nanos); +} +} // namespace + +Duration& operator+=(Duration& d1, const Duration& d2) { + d1 = CreateNormalized<Duration>(d1.seconds() + d2.seconds(), + d1.nanos() + d2.nanos()); + return d1; +} + +Duration& operator-=(Duration& d1, const Duration& d2) { // NOLINT + d1 = CreateNormalized<Duration>(d1.seconds() - d2.seconds(), + d1.nanos() - d2.nanos()); + return d1; +} + +Duration& operator*=(Duration& d, arc_i64 r) { // NOLINT + bool negative; + uint128 value; + ToUint128(d, &value, &negative); + if (r > 0) { + value *= static_cast<arc_ui64>(r); + } else { + negative = !negative; + value *= static_cast<arc_ui64>(-r); + } + ToDuration(value, negative, &d); + return d; +} + +Duration& operator*=(Duration& d, double r) { // NOLINT + double result = (d.seconds() * 1.0 + 1.0 * d.nanos() / kNanosPerSecond) * r; + arc_i64 seconds = static_cast<arc_i64>(result); + arc_i32 nanos = static_cast<arc_i32>((result - seconds) * kNanosPerSecond); + // Note that we normalize here not just because nanos can have a different + // sign from seconds but also that nanos can be any arbitrary value when + // overflow happens (i.e., the result is a much larger value than what + // int64 can represent). + d = CreateNormalized<Duration>(seconds, nanos); + return d; +} + +Duration& operator/=(Duration& d, arc_i64 r) { // NOLINT + bool negative; + uint128 value; + ToUint128(d, &value, &negative); + if (r > 0) { + value /= static_cast<arc_ui64>(r); + } else { + negative = !negative; + value /= static_cast<arc_ui64>(-r); + } + ToDuration(value, negative, &d); + return d; +} + +Duration& operator/=(Duration& d, double r) { // NOLINT + return d *= 1.0 / r; +} + +Duration& operator%=(Duration& d1, const Duration& d2) { // NOLINT + bool negative1, negative2; + uint128 value1, value2; + ToUint128(d1, &value1, &negative1); + ToUint128(d2, &value2, &negative2); + uint128 result = value1 % value2; + // When negative values are involved in division, we round the division + // result towards zero. With this semantics, sign of the remainder is the + // same as the dividend. For example: + // -5 / 10 = 0, -5 % 10 = -5 + // -5 / (-10) = 0, -5 % (-10) = -5 + // 5 / (-10) = 0, 5 % (-10) = 5 + ToDuration(result, negative1, &d1); + return d1; +} + +arc_i64 operator/(const Duration& d1, const Duration& d2) { + bool negative1, negative2; + uint128 value1, value2; + ToUint128(d1, &value1, &negative1); + ToUint128(d2, &value2, &negative2); + arc_i64 result = Uint128Low64(value1 / value2); + if (negative1 != negative2) { + result = -result; + } + return result; +} + +Timestamp& operator+=(Timestamp& t, const Duration& d) { // NOLINT + t = CreateNormalized<Timestamp>(t.seconds() + d.seconds(), + t.nanos() + d.nanos()); + return t; +} + +Timestamp& operator-=(Timestamp& t, const Duration& d) { // NOLINT + t = CreateNormalized<Timestamp>(t.seconds() - d.seconds(), + t.nanos() - d.nanos()); + return t; +} + +Duration operator-(const Timestamp& t1, const Timestamp& t2) { + return CreateNormalized<Duration>(t1.seconds() - t2.seconds(), + t1.nanos() - t2.nanos()); +} +} // namespace protobuf +} // namespace google diff --git a/contrib/libs/protobuf_old/src/google/protobuf/util/time_util.h b/contrib/libs/protobuf_old/src/google/protobuf/util/time_util.h new file mode 100644 index 0000000000..58530353b7 --- /dev/null +++ b/contrib/libs/protobuf_old/src/google/protobuf/util/time_util.h @@ -0,0 +1,313 @@ +// 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. + +// Defines utilities for the Timestamp and Duration well known types. + +#ifndef GOOGLE_PROTOBUF_UTIL_TIME_UTIL_H__ +#define GOOGLE_PROTOBUF_UTIL_TIME_UTIL_H__ + +#include <cstdint> +#include <ctime> +#include <ostream> +#include <string> +#ifdef _MSC_VER +#ifdef _XBOX_ONE +struct timeval { + int64 tv_sec; /* seconds */ + int64 tv_usec; /* and microseconds */ +}; +#else +#include <winsock2.h> +#endif // _XBOX_ONE +#else +#include <sys/time.h> +#endif + +#include <google/protobuf/duration.pb.h> +#include <google/protobuf/timestamp.pb.h> + +#include <google/protobuf/port_def.inc> + +namespace google { +namespace protobuf { +namespace util { + +// Utility functions for Timestamp and Duration. +class PROTOBUF_EXPORT TimeUtil { + typedef google::protobuf::Timestamp Timestamp; + typedef google::protobuf::Duration Duration; + + public: + // The min/max Timestamp/Duration values we support. + // + // For "0001-01-01T00:00:00Z". + static const arc_i64 kTimestampMinSeconds = -62135596800LL; + // For "9999-12-31T23:59:59.999999999Z". + static const arc_i64 kTimestampMaxSeconds = 253402300799LL; + static const arc_i64 kDurationMinSeconds = -315576000000LL; + static const arc_i64 kDurationMaxSeconds = 315576000000LL; + + // Converts Timestamp to/from RFC 3339 date string format. + // Generated output will always be Z-normalized and uses 3, 6 or 9 + // fractional digits as required to represent the exact time. When + // parsing, any fractional digits (or none) and any offset are + // accepted as long as they fit into nano-seconds precision. + // Note that Timestamp can only represent time from + // 0001-01-01T00:00:00Z to 9999-12-31T23:59:59.999999999Z. Converting + // a Timestamp outside of this range is undefined behavior. + // See https://www.ietf.org/rfc/rfc3339.txt + // + // Example of generated format: + // "1972-01-01T10:00:20.021Z" + // + // Example of accepted format: + // "1972-01-01T10:00:20.021-05:00" + static TProtoStringType ToString(const Timestamp& timestamp); + static bool FromString(const TProtoStringType& value, Timestamp* timestamp); + + // Converts Duration to/from string format. The string format will contains + // 3, 6, or 9 fractional digits depending on the precision required to + // represent the exact Duration value. For example: + // "1s", "1.010s", "1.000000100s", "-3.100s" + // The range that can be represented by Duration is from -315,576,000,000 + // to +315,576,000,000 inclusive (in seconds). + static TProtoStringType ToString(const Duration& duration); + static bool FromString(const TProtoStringType& value, Duration* timestamp); + +#ifdef GetCurrentTime +#undef GetCurrentTime // Visual Studio has macro GetCurrentTime +#endif + // Gets the current UTC time. + static Timestamp GetCurrentTime(); + // Returns the Time representing "1970-01-01 00:00:00". + static Timestamp GetEpoch(); + + // Converts between Duration and integer types. The behavior is undefined if + // the input value is not in the valid range of Duration. + static Duration NanosecondsToDuration(arc_i64 nanos); + static Duration MicrosecondsToDuration(arc_i64 micros); + static Duration MillisecondsToDuration(arc_i64 millis); + static Duration SecondsToDuration(arc_i64 seconds); + static Duration MinutesToDuration(arc_i64 minutes); + static Duration HoursToDuration(arc_i64 hours); + // Result will be truncated towards zero. For example, "-1.5s" will be + // truncated to "-1s", and "1.5s" to "1s" when converting to seconds. + // It's undefined behavior if the input duration is not valid or the result + // exceeds the range of int64. A duration is not valid if it's not in the + // valid range of Duration, or have an invalid nanos value (i.e., larger + // than 999999999, less than -999999999, or have a different sign from the + // seconds part). + static arc_i64 DurationToNanoseconds(const Duration& duration); + static arc_i64 DurationToMicroseconds(const Duration& duration); + static arc_i64 DurationToMilliseconds(const Duration& duration); + static arc_i64 DurationToSeconds(const Duration& duration); + static arc_i64 DurationToMinutes(const Duration& duration); + static arc_i64 DurationToHours(const Duration& duration); + // Creates Timestamp from integer types. The integer value indicates the + // time elapsed from Epoch time. The behavior is undefined if the input + // value is not in the valid range of Timestamp. + static Timestamp NanosecondsToTimestamp(arc_i64 nanos); + static Timestamp MicrosecondsToTimestamp(arc_i64 micros); + static Timestamp MillisecondsToTimestamp(arc_i64 millis); + static Timestamp SecondsToTimestamp(arc_i64 seconds); + // Result will be truncated down to the nearest integer value. For example, + // with "1969-12-31T23:59:59.9Z", TimestampToMilliseconds() returns -100 + // and TimestampToSeconds() returns -1. It's undefined behavior if the input + // Timestamp is not valid (i.e., its seconds part or nanos part does not fall + // in the valid range) or the return value doesn't fit into int64. + static arc_i64 TimestampToNanoseconds(const Timestamp& timestamp); + static arc_i64 TimestampToMicroseconds(const Timestamp& timestamp); + static arc_i64 TimestampToMilliseconds(const Timestamp& timestamp); + static arc_i64 TimestampToSeconds(const Timestamp& timestamp); + + // Conversion to/from other time/date types. Note that these types may + // have a different precision and time range from Timestamp/Duration. + // When converting to a lower precision type, the value will be truncated + // to the nearest value that can be represented. If the value is + // out of the range of the result type, the return value is undefined. + // + // Conversion to/from time_t + static Timestamp TimeTToTimestamp(time_t value); + static time_t TimestampToTimeT(const Timestamp& value); + + // Conversion to/from timeval + static Timestamp TimevalToTimestamp(const timeval& value); + static timeval TimestampToTimeval(const Timestamp& value); + static Duration TimevalToDuration(const timeval& value); + static timeval DurationToTimeval(const Duration& value); +}; + +} // namespace util +} // namespace protobuf +} // namespace google + +namespace google { +namespace protobuf { +// Overloaded operators for Duration. +// +// Assignment operators. +PROTOBUF_EXPORT Duration& operator+=(Duration& d1, + const Duration& d2); // NOLINT +PROTOBUF_EXPORT Duration& operator-=(Duration& d1, + const Duration& d2); // NOLINT +PROTOBUF_EXPORT Duration& operator*=(Duration& d, arc_i64 r); // NOLINT +PROTOBUF_EXPORT Duration& operator*=(Duration& d, double r); // NOLINT +PROTOBUF_EXPORT Duration& operator/=(Duration& d, arc_i64 r); // NOLINT +PROTOBUF_EXPORT Duration& operator/=(Duration& d, double r); // NOLINT +// Overload for other integer types. +template <typename T> +Duration& operator*=(Duration& d, T r) { // NOLINT + arc_i64 x = r; + return d *= x; +} +template <typename T> +Duration& operator/=(Duration& d, T r) { // NOLINT + arc_i64 x = r; + return d /= x; +} +PROTOBUF_EXPORT Duration& operator%=(Duration& d1, + const Duration& d2); // NOLINT +// Relational operators. +inline bool operator<(const Duration& d1, const Duration& d2) { + if (d1.seconds() == d2.seconds()) { + return d1.nanos() < d2.nanos(); + } + return d1.seconds() < d2.seconds(); +} +inline bool operator>(const Duration& d1, const Duration& d2) { + return d2 < d1; +} +inline bool operator>=(const Duration& d1, const Duration& d2) { + return !(d1 < d2); +} +inline bool operator<=(const Duration& d1, const Duration& d2) { + return !(d2 < d1); +} +inline bool operator==(const Duration& d1, const Duration& d2) { + return d1.seconds() == d2.seconds() && d1.nanos() == d2.nanos(); +} +inline bool operator!=(const Duration& d1, const Duration& d2) { + return !(d1 == d2); +} +// Additive operators +inline Duration operator-(const Duration& d) { + Duration result; + result.set_seconds(-d.seconds()); + result.set_nanos(-d.nanos()); + return result; +} +inline Duration operator+(const Duration& d1, const Duration& d2) { + Duration result = d1; + return result += d2; +} +inline Duration operator-(const Duration& d1, const Duration& d2) { + Duration result = d1; + return result -= d2; +} +// Multiplicative operators +template <typename T> +inline Duration operator*(Duration d, T r) { + return d *= r; +} +template <typename T> +inline Duration operator*(T r, Duration d) { + return d *= r; +} +template <typename T> +inline Duration operator/(Duration d, T r) { + return d /= r; +} +PROTOBUF_EXPORT arc_i64 operator/(const Duration& d1, const Duration& d2); + +inline Duration operator%(const Duration& d1, const Duration& d2) { + Duration result = d1; + return result %= d2; +} + +inline std::ostream& operator<<(std::ostream& out, const Duration& d) { + out << ::PROTOBUF_NAMESPACE_ID::util::TimeUtil::ToString(d); + return out; +} + +// Overloaded operators for Timestamp +// +// Assignment operators. +PROTOBUF_EXPORT Timestamp& operator+=(Timestamp& t, + const Duration& d); // NOLINT +PROTOBUF_EXPORT Timestamp& operator-=(Timestamp& t, + const Duration& d); // NOLINT +// Relational operators. +inline bool operator<(const Timestamp& t1, const Timestamp& t2) { + if (t1.seconds() == t2.seconds()) { + return t1.nanos() < t2.nanos(); + } + return t1.seconds() < t2.seconds(); +} +inline bool operator>(const Timestamp& t1, const Timestamp& t2) { + return t2 < t1; +} +inline bool operator>=(const Timestamp& t1, const Timestamp& t2) { + return !(t1 < t2); +} +inline bool operator<=(const Timestamp& t1, const Timestamp& t2) { + return !(t2 < t1); +} +inline bool operator==(const Timestamp& t1, const Timestamp& t2) { + return t1.seconds() == t2.seconds() && t1.nanos() == t2.nanos(); +} +inline bool operator!=(const Timestamp& t1, const Timestamp& t2) { + return !(t1 == t2); +} +// Additive operators. +inline Timestamp operator+(const Timestamp& t, const Duration& d) { + Timestamp result = t; + return result += d; +} +inline Timestamp operator+(const Duration& d, const Timestamp& t) { + Timestamp result = t; + return result += d; +} +inline Timestamp operator-(const Timestamp& t, const Duration& d) { + Timestamp result = t; + return result -= d; +} +PROTOBUF_EXPORT Duration operator-(const Timestamp& t1, const Timestamp& t2); + +inline std::ostream& operator<<(std::ostream& out, const Timestamp& t) { + out << ::PROTOBUF_NAMESPACE_ID::util::TimeUtil::ToString(t); + return out; +} + +} // namespace protobuf +} // namespace google + +#include <google/protobuf/port_undef.inc> + +#endif // GOOGLE_PROTOBUF_UTIL_TIME_UTIL_H__ diff --git a/contrib/libs/protobuf_old/src/google/protobuf/util/type_resolver.h b/contrib/libs/protobuf_old/src/google/protobuf/util/type_resolver.h new file mode 100644 index 0000000000..9bf967a803 --- /dev/null +++ b/contrib/libs/protobuf_old/src/google/protobuf/util/type_resolver.h @@ -0,0 +1,76 @@ +// 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. + +// Defines a TypeResolver for the Any message. + +#ifndef GOOGLE_PROTOBUF_UTIL_TYPE_RESOLVER_H__ +#define GOOGLE_PROTOBUF_UTIL_TYPE_RESOLVER_H__ + +#include <string> + +#include <google/protobuf/stubs/common.h> +#include <google/protobuf/type.pb.h> +#include <google/protobuf/stubs/status.h> +#include <google/protobuf/stubs/status.h> + +#include <google/protobuf/port_def.inc> + +namespace google { +namespace protobuf { +class DescriptorPool; +namespace util { + +// Abstract interface for a type resolver. +// +// Implementations of this interface must be thread-safe. +class PROTOBUF_EXPORT TypeResolver { + public: + TypeResolver() {} + virtual ~TypeResolver() {} + + // Resolves a type url for a message type. + virtual util::Status ResolveMessageType( + const TProtoStringType& type_url, google::protobuf::Type* message_type) = 0; + + // Resolves a type url for an enum type. + virtual util::Status ResolveEnumType(const TProtoStringType& type_url, + google::protobuf::Enum* enum_type) = 0; + + private: + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(TypeResolver); +}; + +} // namespace util +} // namespace protobuf +} // namespace google + +#include <google/protobuf/port_undef.inc> + +#endif // GOOGLE_PROTOBUF_UTIL_TYPE_RESOLVER_H__ diff --git a/contrib/libs/protobuf_old/src/google/protobuf/util/type_resolver_util.cc b/contrib/libs/protobuf_old/src/google/protobuf/util/type_resolver_util.cc new file mode 100644 index 0000000000..6fafbcb652 --- /dev/null +++ b/contrib/libs/protobuf_old/src/google/protobuf/util/type_resolver_util.cc @@ -0,0 +1,370 @@ +// 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 <google/protobuf/util/type_resolver_util.h> + +#include <google/protobuf/type.pb.h> +#include <google/protobuf/wrappers.pb.h> +#include <google/protobuf/descriptor.pb.h> +#include <google/protobuf/descriptor.h> +#include <google/protobuf/util/internal/utility.h> +#include <google/protobuf/util/type_resolver.h> +#include <google/protobuf/stubs/strutil.h> +#include <google/protobuf/stubs/status.h> +#include <google/protobuf/stubs/status.h> + +// clang-format off +#include <google/protobuf/port_def.inc> +// clang-format on + +namespace google { +namespace protobuf { +namespace util { +namespace { +using google::protobuf::Any; +using google::protobuf::BoolValue; +using google::protobuf::BytesValue; +using google::protobuf::DoubleValue; +using google::protobuf::Enum; +using google::protobuf::EnumValue; +using google::protobuf::Field; +using google::protobuf::FloatValue; +using google::protobuf::Int32Value; +using google::protobuf::Int64Value; +using google::protobuf::Option; +using google::protobuf::StringValue; +using google::protobuf::Type; +using google::protobuf::UInt32Value; +using google::protobuf::UInt64Value; + +class DescriptorPoolTypeResolver : public TypeResolver { + public: + DescriptorPoolTypeResolver(const TProtoStringType& url_prefix, + const DescriptorPool* pool) + : url_prefix_(url_prefix), pool_(pool) {} + + util::Status ResolveMessageType(const TProtoStringType& type_url, + Type* type) override { + TProtoStringType type_name; + util::Status status = ParseTypeUrl(type_url, &type_name); + if (!status.ok()) { + return status; + } + + const Descriptor* descriptor = pool_->FindMessageTypeByName(type_name); + if (descriptor == NULL) { + return util::NotFoundError("Invalid type URL, unknown type: " + + type_name); + } + ConvertDescriptor(descriptor, type); + return util::Status(); + } + + util::Status ResolveEnumType(const TProtoStringType& type_url, + Enum* enum_type) override { + TProtoStringType type_name; + util::Status status = ParseTypeUrl(type_url, &type_name); + if (!status.ok()) { + return status; + } + + const EnumDescriptor* descriptor = pool_->FindEnumTypeByName(type_name); + if (descriptor == NULL) { + return util::InvalidArgumentError("Invalid type URL, unknown type: " + + type_name); + } + ConvertEnumDescriptor(descriptor, enum_type); + return util::Status(); + } + + private: + void ConvertDescriptor(const Descriptor* descriptor, Type* type) { + type->Clear(); + type->set_name(descriptor->full_name()); + for (int i = 0; i < descriptor->field_count(); ++i) { + ConvertFieldDescriptor(descriptor->field(i), type->add_fields()); + } + for (int i = 0; i < descriptor->oneof_decl_count(); ++i) { + type->add_oneofs(descriptor->oneof_decl(i)->name()); + } + type->mutable_source_context()->set_file_name(descriptor->file()->name()); + ConvertMessageOptions(descriptor->options(), type->mutable_options()); + } + + void ConvertMessageOptions(const MessageOptions& options, + RepeatedPtrField<Option>* output) { + return ConvertOptionsInternal(options, output); + } + + void ConvertFieldOptions(const FieldOptions& options, + RepeatedPtrField<Option>* output) { + return ConvertOptionsInternal(options, output); + } + + void ConvertEnumOptions(const EnumOptions& options, + RepeatedPtrField<Option>* output) { + return ConvertOptionsInternal(options, output); + } + + void ConvertEnumValueOptions(const EnumValueOptions& options, + RepeatedPtrField<Option>* output) { + return ConvertOptionsInternal(options, output); + } + + // Implementation details for Convert*Options. + void ConvertOptionsInternal(const Message& options, + RepeatedPtrField<Option>* output) { + const Reflection* reflection = options.GetReflection(); + std::vector<const FieldDescriptor*> fields; + reflection->ListFields(options, &fields); + for (const FieldDescriptor* field : fields) { + if (field->is_repeated()) { + const int size = reflection->FieldSize(options, field); + for (int i = 0; i < size; i++) { + ConvertOptionField(reflection, options, field, i, output->Add()); + } + } else { + ConvertOptionField(reflection, options, field, -1, output->Add()); + } + } + } + + static void ConvertOptionField(const Reflection* reflection, + const Message& options, + const FieldDescriptor* field, int index, + Option* out) { + out->set_name(field->is_extension() ? field->full_name() : field->name()); + Any* value = out->mutable_value(); + switch (field->cpp_type()) { + case FieldDescriptor::CPPTYPE_MESSAGE: + value->PackFrom( + field->is_repeated() + ? reflection->GetRepeatedMessage(options, field, index) + : reflection->GetMessage(options, field)); + return; + case FieldDescriptor::CPPTYPE_DOUBLE: + value->PackFrom(WrapValue<DoubleValue>( + field->is_repeated() + ? reflection->GetRepeatedDouble(options, field, index) + : reflection->GetDouble(options, field))); + return; + case FieldDescriptor::CPPTYPE_FLOAT: + value->PackFrom(WrapValue<FloatValue>( + field->is_repeated() + ? reflection->GetRepeatedFloat(options, field, index) + : reflection->GetFloat(options, field))); + return; + case FieldDescriptor::CPPTYPE_INT64: + value->PackFrom(WrapValue<Int64Value>( + field->is_repeated() + ? reflection->GetRepeatedInt64(options, field, index) + : reflection->GetInt64(options, field))); + return; + case FieldDescriptor::CPPTYPE_UINT64: + value->PackFrom(WrapValue<UInt64Value>( + field->is_repeated() + ? reflection->GetRepeatedUInt64(options, field, index) + : reflection->GetUInt64(options, field))); + return; + case FieldDescriptor::CPPTYPE_INT32: + value->PackFrom(WrapValue<Int32Value>( + field->is_repeated() + ? reflection->GetRepeatedInt32(options, field, index) + : reflection->GetInt32(options, field))); + return; + case FieldDescriptor::CPPTYPE_UINT32: + value->PackFrom(WrapValue<UInt32Value>( + field->is_repeated() + ? reflection->GetRepeatedUInt32(options, field, index) + : reflection->GetUInt32(options, field))); + return; + case FieldDescriptor::CPPTYPE_BOOL: + value->PackFrom(WrapValue<BoolValue>( + field->is_repeated() + ? reflection->GetRepeatedBool(options, field, index) + : reflection->GetBool(options, field))); + return; + case FieldDescriptor::CPPTYPE_STRING: { + const TProtoStringType& val = + field->is_repeated() + ? reflection->GetRepeatedString(options, field, index) + : reflection->GetString(options, field); + if (field->type() == FieldDescriptor::TYPE_STRING) { + value->PackFrom(WrapValue<StringValue>(val)); + } else { + value->PackFrom(WrapValue<BytesValue>(val)); + } + return; + } + case FieldDescriptor::CPPTYPE_ENUM: { + const EnumValueDescriptor* val = + field->is_repeated() + ? reflection->GetRepeatedEnum(options, field, index) + : reflection->GetEnum(options, field); + value->PackFrom(WrapValue<Int32Value>(val->number())); + return; + } + } + } + + template <typename WrapperT, typename T> + static WrapperT WrapValue(T value) { + WrapperT wrapper; + wrapper.set_value(value); + return wrapper; + } + + void ConvertFieldDescriptor(const FieldDescriptor* descriptor, Field* field) { + field->set_kind(static_cast<Field::Kind>(descriptor->type())); + switch (descriptor->label()) { + case FieldDescriptor::LABEL_OPTIONAL: + field->set_cardinality(Field::CARDINALITY_OPTIONAL); + break; + case FieldDescriptor::LABEL_REPEATED: + field->set_cardinality(Field::CARDINALITY_REPEATED); + break; + case FieldDescriptor::LABEL_REQUIRED: + field->set_cardinality(Field::CARDINALITY_REQUIRED); + break; + } + field->set_number(descriptor->number()); + field->set_name(descriptor->name()); + field->set_json_name(descriptor->json_name()); + if (descriptor->has_default_value()) { + field->set_default_value(DefaultValueAsString(descriptor)); + } + if (descriptor->type() == FieldDescriptor::TYPE_MESSAGE || + descriptor->type() == FieldDescriptor::TYPE_GROUP) { + field->set_type_url(GetTypeUrl(descriptor->message_type())); + } else if (descriptor->type() == FieldDescriptor::TYPE_ENUM) { + field->set_type_url(GetTypeUrl(descriptor->enum_type())); + } + if (descriptor->containing_oneof() != NULL) { + field->set_oneof_index(descriptor->containing_oneof()->index() + 1); + } + if (descriptor->is_packed()) { + field->set_packed(true); + } + + ConvertFieldOptions(descriptor->options(), field->mutable_options()); + } + + void ConvertEnumDescriptor(const EnumDescriptor* descriptor, + Enum* enum_type) { + enum_type->Clear(); + enum_type->set_name(descriptor->full_name()); + enum_type->mutable_source_context()->set_file_name( + descriptor->file()->name()); + for (int i = 0; i < descriptor->value_count(); ++i) { + const EnumValueDescriptor* value_descriptor = descriptor->value(i); + EnumValue* value = enum_type->mutable_enumvalue()->Add(); + value->set_name(value_descriptor->name()); + value->set_number(value_descriptor->number()); + + ConvertEnumValueOptions(value_descriptor->options(), + value->mutable_options()); + } + + ConvertEnumOptions(descriptor->options(), enum_type->mutable_options()); + } + + TProtoStringType GetTypeUrl(const Descriptor* descriptor) { + return url_prefix_ + "/" + descriptor->full_name(); + } + + TProtoStringType GetTypeUrl(const EnumDescriptor* descriptor) { + return url_prefix_ + "/" + descriptor->full_name(); + } + + util::Status ParseTypeUrl(const TProtoStringType& type_url, + TProtoStringType* type_name) { + if (type_url.substr(0, url_prefix_.size() + 1) != url_prefix_ + "/") { + return util::InvalidArgumentError( + StrCat("Invalid type URL, type URLs must be of the form '", + url_prefix_, "/<typename>', got: ", type_url)); + } + *type_name = type_url.substr(url_prefix_.size() + 1); + return util::Status(); + } + + TProtoStringType DefaultValueAsString(const FieldDescriptor* descriptor) { + switch (descriptor->cpp_type()) { + case FieldDescriptor::CPPTYPE_INT32: + return StrCat(descriptor->default_value_int32()); + break; + case FieldDescriptor::CPPTYPE_INT64: + return StrCat(descriptor->default_value_int64()); + break; + case FieldDescriptor::CPPTYPE_UINT32: + return StrCat(descriptor->default_value_uint32()); + break; + case FieldDescriptor::CPPTYPE_UINT64: + return StrCat(descriptor->default_value_uint64()); + break; + case FieldDescriptor::CPPTYPE_FLOAT: + return SimpleFtoa(descriptor->default_value_float()); + break; + case FieldDescriptor::CPPTYPE_DOUBLE: + return SimpleDtoa(descriptor->default_value_double()); + break; + case FieldDescriptor::CPPTYPE_BOOL: + return descriptor->default_value_bool() ? "true" : "false"; + break; + case FieldDescriptor::CPPTYPE_STRING: + if (descriptor->type() == FieldDescriptor::TYPE_BYTES) { + return CEscape(descriptor->default_value_string()); + } else { + return descriptor->default_value_string(); + } + break; + case FieldDescriptor::CPPTYPE_ENUM: + return descriptor->default_value_enum()->name(); + break; + case FieldDescriptor::CPPTYPE_MESSAGE: + GOOGLE_LOG(DFATAL) << "Messages can't have default values!"; + break; + } + return ""; + } + + TProtoStringType url_prefix_; + const DescriptorPool* pool_; +}; + +} // namespace + +TypeResolver* NewTypeResolverForDescriptorPool(const TProtoStringType& url_prefix, + const DescriptorPool* pool) { + return new DescriptorPoolTypeResolver(url_prefix, pool); +} + +} // namespace util +} // namespace protobuf +} // namespace google diff --git a/contrib/libs/protobuf_old/src/google/protobuf/util/type_resolver_util.h b/contrib/libs/protobuf_old/src/google/protobuf/util/type_resolver_util.h new file mode 100644 index 0000000000..035b385634 --- /dev/null +++ b/contrib/libs/protobuf_old/src/google/protobuf/util/type_resolver_util.h @@ -0,0 +1,58 @@ +// 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. + +// Defines utilities for the TypeResolver. + +#ifndef GOOGLE_PROTOBUF_UTIL_TYPE_RESOLVER_UTIL_H__ +#define GOOGLE_PROTOBUF_UTIL_TYPE_RESOLVER_UTIL_H__ + +#include <string> +#include <google/protobuf/stubs/port.h> + +namespace google { +namespace protobuf { +class DescriptorPool; +namespace util { +class TypeResolver; + +#include <google/protobuf/port_def.inc> + +// Creates a TypeResolver that serves type information in the given descriptor +// pool. Caller takes ownership of the returned TypeResolver. +PROTOBUF_EXPORT TypeResolver* NewTypeResolverForDescriptorPool( + const TProtoStringType& url_prefix, const DescriptorPool* pool); + +} // namespace util +} // namespace protobuf +} // namespace google + +#include <google/protobuf/port_undef.inc> + +#endif // GOOGLE_PROTOBUF_UTIL_TYPE_RESOLVER_UTIL_H__ diff --git a/contrib/libs/protobuf_old/src/google/protobuf/wire_format.cc b/contrib/libs/protobuf_old/src/google/protobuf/wire_format.cc new file mode 100644 index 0000000000..d7acf3da90 --- /dev/null +++ b/contrib/libs/protobuf_old/src/google/protobuf/wire_format.cc @@ -0,0 +1,1751 @@ +// 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: kenton@google.com (Kenton Varda) +// Based on original Protocol Buffers design by +// Sanjay Ghemawat, Jeff Dean, and others. + +#include <google/protobuf/wire_format.h> + +#include <stack> +#include <string> +#include <vector> + +#include <google/protobuf/stubs/logging.h> +#include <google/protobuf/stubs/common.h> +#include <google/protobuf/stubs/stringprintf.h> +#include <google/protobuf/descriptor.pb.h> +#include <google/protobuf/parse_context.h> +#include <google/protobuf/io/coded_stream.h> +#include <google/protobuf/io/zero_copy_stream.h> +#include <google/protobuf/io/zero_copy_stream_impl.h> +#include <google/protobuf/descriptor.h> +#include <google/protobuf/dynamic_message.h> +#include <google/protobuf/map_field.h> +#include <google/protobuf/map_field_inl.h> +#include <google/protobuf/message.h> +#include <google/protobuf/message_lite.h> +#include <google/protobuf/unknown_field_set.h> + + +#include <google/protobuf/port_def.inc> + +const size_t kMapEntryTagByteSize = 2; + +namespace google { +namespace protobuf { +namespace internal { + +// Forward declare static functions +static size_t MapValueRefDataOnlyByteSize(const FieldDescriptor* field, + const MapValueConstRef& value); + +// =================================================================== + +bool UnknownFieldSetFieldSkipper::SkipField(io::CodedInputStream* input, + arc_ui32 tag) { + return WireFormat::SkipField(input, tag, unknown_fields_); +} + +bool UnknownFieldSetFieldSkipper::SkipMessage(io::CodedInputStream* input) { + return WireFormat::SkipMessage(input, unknown_fields_); +} + +void UnknownFieldSetFieldSkipper::SkipUnknownEnum(int field_number, int value) { + unknown_fields_->AddVarint(field_number, value); +} + +bool WireFormat::SkipField(io::CodedInputStream* input, arc_ui32 tag, + UnknownFieldSet* unknown_fields) { + int number = WireFormatLite::GetTagFieldNumber(tag); + // Field number 0 is illegal. + if (number == 0) return false; + + switch (WireFormatLite::GetTagWireType(tag)) { + case WireFormatLite::WIRETYPE_VARINT: { + arc_ui64 value; + if (!input->ReadVarint64(&value)) return false; + if (unknown_fields != nullptr) unknown_fields->AddVarint(number, value); + return true; + } + case WireFormatLite::WIRETYPE_FIXED64: { + arc_ui64 value; + if (!input->ReadLittleEndian64(&value)) return false; + if (unknown_fields != nullptr) unknown_fields->AddFixed64(number, value); + return true; + } + case WireFormatLite::WIRETYPE_LENGTH_DELIMITED: { + arc_ui32 length; + if (!input->ReadVarint32(&length)) return false; + if (unknown_fields == nullptr) { + if (!input->Skip(length)) return false; + } else { + if (!input->ReadString(unknown_fields->AddLengthDelimited(number), + length)) { + return false; + } + } + return true; + } + case WireFormatLite::WIRETYPE_START_GROUP: { + if (!input->IncrementRecursionDepth()) return false; + if (!SkipMessage(input, (unknown_fields == nullptr) + ? nullptr + : unknown_fields->AddGroup(number))) { + return false; + } + input->DecrementRecursionDepth(); + // Check that the ending tag matched the starting tag. + if (!input->LastTagWas( + WireFormatLite::MakeTag(WireFormatLite::GetTagFieldNumber(tag), + WireFormatLite::WIRETYPE_END_GROUP))) { + return false; + } + return true; + } + case WireFormatLite::WIRETYPE_END_GROUP: { + return false; + } + case WireFormatLite::WIRETYPE_FIXED32: { + arc_ui32 value; + if (!input->ReadLittleEndian32(&value)) return false; + if (unknown_fields != nullptr) unknown_fields->AddFixed32(number, value); + return true; + } + default: { + return false; + } + } +} + +bool WireFormat::SkipMessage(io::CodedInputStream* input, + UnknownFieldSet* unknown_fields) { + while (true) { + arc_ui32 tag = input->ReadTag(); + if (tag == 0) { + // End of input. This is a valid place to end, so return true. + return true; + } + + WireFormatLite::WireType wire_type = WireFormatLite::GetTagWireType(tag); + + if (wire_type == WireFormatLite::WIRETYPE_END_GROUP) { + // Must be the end of the message. + return true; + } + + if (!SkipField(input, tag, unknown_fields)) return false; + } +} + +bool WireFormat::ReadPackedEnumPreserveUnknowns(io::CodedInputStream* input, + arc_ui32 field_number, + bool (*is_valid)(int), + UnknownFieldSet* unknown_fields, + RepeatedField<int>* values) { + arc_ui32 length; + if (!input->ReadVarint32(&length)) return false; + io::CodedInputStream::Limit limit = input->PushLimit(length); + while (input->BytesUntilLimit() > 0) { + int value; + if (!WireFormatLite::ReadPrimitive<int, WireFormatLite::TYPE_ENUM>( + input, &value)) { + return false; + } + if (is_valid == nullptr || is_valid(value)) { + values->Add(value); + } else { + unknown_fields->AddVarint(field_number, value); + } + } + input->PopLimit(limit); + return true; +} + +uint8_t* WireFormat::InternalSerializeUnknownFieldsToArray( + const UnknownFieldSet& unknown_fields, uint8_t* target, + io::EpsCopyOutputStream* stream) { + for (int i = 0; i < unknown_fields.field_count(); i++) { + const UnknownField& field = unknown_fields.field(i); + + target = stream->EnsureSpace(target); + switch (field.type()) { + case UnknownField::TYPE_VARINT: + target = WireFormatLite::WriteUInt64ToArray(field.number(), + field.varint(), target); + break; + case UnknownField::TYPE_FIXED32: + target = WireFormatLite::WriteFixed32ToArray(field.number(), + field.fixed32(), target); + break; + case UnknownField::TYPE_FIXED64: + target = WireFormatLite::WriteFixed64ToArray(field.number(), + field.fixed64(), target); + break; + case UnknownField::TYPE_LENGTH_DELIMITED: + target = stream->WriteString(field.number(), field.length_delimited(), + target); + break; + case UnknownField::TYPE_GROUP: + target = WireFormatLite::WriteTagToArray( + field.number(), WireFormatLite::WIRETYPE_START_GROUP, target); + target = InternalSerializeUnknownFieldsToArray(field.group(), target, + stream); + target = stream->EnsureSpace(target); + target = WireFormatLite::WriteTagToArray( + field.number(), WireFormatLite::WIRETYPE_END_GROUP, target); + break; + } + } + return target; +} + +uint8_t* WireFormat::InternalSerializeUnknownMessageSetItemsToArray( + const UnknownFieldSet& unknown_fields, uint8_t* target, + io::EpsCopyOutputStream* stream) { + for (int i = 0; i < unknown_fields.field_count(); i++) { + const UnknownField& field = unknown_fields.field(i); + + // The only unknown fields that are allowed to exist in a MessageSet are + // messages, which are length-delimited. + if (field.type() == UnknownField::TYPE_LENGTH_DELIMITED) { + target = stream->EnsureSpace(target); + // Start group. + target = io::CodedOutputStream::WriteTagToArray( + WireFormatLite::kMessageSetItemStartTag, target); + + // Write type ID. + target = io::CodedOutputStream::WriteTagToArray( + WireFormatLite::kMessageSetTypeIdTag, target); + target = + io::CodedOutputStream::WriteVarint32ToArray(field.number(), target); + + // Write message. + target = io::CodedOutputStream::WriteTagToArray( + WireFormatLite::kMessageSetMessageTag, target); + + target = field.InternalSerializeLengthDelimitedNoTag(target, stream); + + target = stream->EnsureSpace(target); + // End group. + target = io::CodedOutputStream::WriteTagToArray( + WireFormatLite::kMessageSetItemEndTag, target); + } + } + + return target; +} + +size_t WireFormat::ComputeUnknownFieldsSize( + const UnknownFieldSet& unknown_fields) { + size_t size = 0; + for (int i = 0; i < unknown_fields.field_count(); i++) { + const UnknownField& field = unknown_fields.field(i); + + switch (field.type()) { + case UnknownField::TYPE_VARINT: + size += io::CodedOutputStream::VarintSize32(WireFormatLite::MakeTag( + field.number(), WireFormatLite::WIRETYPE_VARINT)); + size += io::CodedOutputStream::VarintSize64(field.varint()); + break; + case UnknownField::TYPE_FIXED32: + size += io::CodedOutputStream::VarintSize32(WireFormatLite::MakeTag( + field.number(), WireFormatLite::WIRETYPE_FIXED32)); + size += sizeof(arc_i32); + break; + case UnknownField::TYPE_FIXED64: + size += io::CodedOutputStream::VarintSize32(WireFormatLite::MakeTag( + field.number(), WireFormatLite::WIRETYPE_FIXED64)); + size += sizeof(arc_i64); + break; + case UnknownField::TYPE_LENGTH_DELIMITED: + size += io::CodedOutputStream::VarintSize32(WireFormatLite::MakeTag( + field.number(), WireFormatLite::WIRETYPE_LENGTH_DELIMITED)); + size += io::CodedOutputStream::VarintSize32( + field.length_delimited().size()); + size += field.length_delimited().size(); + break; + case UnknownField::TYPE_GROUP: + size += io::CodedOutputStream::VarintSize32(WireFormatLite::MakeTag( + field.number(), WireFormatLite::WIRETYPE_START_GROUP)); + size += ComputeUnknownFieldsSize(field.group()); + size += io::CodedOutputStream::VarintSize32(WireFormatLite::MakeTag( + field.number(), WireFormatLite::WIRETYPE_END_GROUP)); + break; + } + } + + return size; +} + +size_t WireFormat::ComputeUnknownMessageSetItemsSize( + const UnknownFieldSet& unknown_fields) { + size_t size = 0; + for (int i = 0; i < unknown_fields.field_count(); i++) { + const UnknownField& field = unknown_fields.field(i); + + // The only unknown fields that are allowed to exist in a MessageSet are + // messages, which are length-delimited. + if (field.type() == UnknownField::TYPE_LENGTH_DELIMITED) { + size += WireFormatLite::kMessageSetItemTagsSize; + size += io::CodedOutputStream::VarintSize32(field.number()); + + int field_size = field.GetLengthDelimitedSize(); + size += io::CodedOutputStream::VarintSize32(field_size); + size += field_size; + } + } + + return size; +} + +// =================================================================== + +bool WireFormat::ParseAndMergePartial(io::CodedInputStream* input, + Message* message) { + const Descriptor* descriptor = message->GetDescriptor(); + const Reflection* message_reflection = message->GetReflection(); + + while (true) { + arc_ui32 tag = input->ReadTag(); + if (tag == 0) { + // End of input. This is a valid place to end, so return true. + return true; + } + + if (WireFormatLite::GetTagWireType(tag) == + WireFormatLite::WIRETYPE_END_GROUP) { + // Must be the end of the message. + return true; + } + + const FieldDescriptor* field = nullptr; + + if (descriptor != nullptr) { + int field_number = WireFormatLite::GetTagFieldNumber(tag); + field = descriptor->FindFieldByNumber(field_number); + + // If that failed, check if the field is an extension. + if (field == nullptr && descriptor->IsExtensionNumber(field_number)) { + if (input->GetExtensionPool() == nullptr) { + field = message_reflection->FindKnownExtensionByNumber(field_number); + } else { + field = input->GetExtensionPool()->FindExtensionByNumber( + descriptor, field_number); + } + } + + // If that failed, but we're a MessageSet, and this is the tag for a + // MessageSet item, then parse that. + if (field == nullptr && descriptor->options().message_set_wire_format() && + tag == WireFormatLite::kMessageSetItemStartTag) { + if (!ParseAndMergeMessageSetItem(input, message)) { + return false; + } + continue; // Skip ParseAndMergeField(); already taken care of. + } + } + + if (!ParseAndMergeField(tag, field, message, input)) { + return false; + } + } +} + +bool WireFormat::SkipMessageSetField(io::CodedInputStream* input, + arc_ui32 field_number, + UnknownFieldSet* unknown_fields) { + arc_ui32 length; + if (!input->ReadVarint32(&length)) return false; + return input->ReadString(unknown_fields->AddLengthDelimited(field_number), + length); +} + +bool WireFormat::ParseAndMergeMessageSetField(arc_ui32 field_number, + const FieldDescriptor* field, + Message* message, + io::CodedInputStream* input) { + const Reflection* message_reflection = message->GetReflection(); + if (field == nullptr) { + // We store unknown MessageSet extensions as groups. + return SkipMessageSetField( + input, field_number, message_reflection->MutableUnknownFields(message)); + } else if (field->is_repeated() || + field->type() != FieldDescriptor::TYPE_MESSAGE) { + // This shouldn't happen as we only allow optional message extensions to + // MessageSet. + GOOGLE_LOG(ERROR) << "Extensions of MessageSets must be optional messages."; + return false; + } else { + Message* sub_message = message_reflection->MutableMessage( + message, field, input->GetExtensionFactory()); + return WireFormatLite::ReadMessage(input, sub_message); + } +} + +static bool StrictUtf8Check(const FieldDescriptor* field) { + return field->file()->syntax() == FileDescriptor::SYNTAX_PROTO3; +} + +bool WireFormat::ParseAndMergeField( + arc_ui32 tag, + const FieldDescriptor* field, // May be nullptr for unknown + Message* message, io::CodedInputStream* input) { + const Reflection* message_reflection = message->GetReflection(); + + enum { UNKNOWN, NORMAL_FORMAT, PACKED_FORMAT } value_format; + + if (field == nullptr) { + value_format = UNKNOWN; + } else if (WireFormatLite::GetTagWireType(tag) == + WireTypeForFieldType(field->type())) { + value_format = NORMAL_FORMAT; + } else if (field->is_packable() && + WireFormatLite::GetTagWireType(tag) == + WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + value_format = PACKED_FORMAT; + } else { + // We don't recognize this field. Either the field number is unknown + // or the wire type doesn't match. Put it in our unknown field set. + value_format = UNKNOWN; + } + + if (value_format == UNKNOWN) { + return SkipField(input, tag, + message_reflection->MutableUnknownFields(message)); + } else if (value_format == PACKED_FORMAT) { + arc_ui32 length; + if (!input->ReadVarint32(&length)) return false; + io::CodedInputStream::Limit limit = input->PushLimit(length); + + switch (field->type()) { +#define HANDLE_PACKED_TYPE(TYPE, CPPTYPE, CPPTYPE_METHOD) \ + case FieldDescriptor::TYPE_##TYPE: { \ + while (input->BytesUntilLimit() > 0) { \ + CPPTYPE value; \ + if (!WireFormatLite::ReadPrimitive<CPPTYPE, \ + WireFormatLite::TYPE_##TYPE>(input, \ + &value)) \ + return false; \ + message_reflection->Add##CPPTYPE_METHOD(message, field, value); \ + } \ + break; \ + } + + HANDLE_PACKED_TYPE(INT32, arc_i32, Int32) + HANDLE_PACKED_TYPE(INT64, arc_i64, Int64) + HANDLE_PACKED_TYPE(SINT32, arc_i32, Int32) + HANDLE_PACKED_TYPE(SINT64, arc_i64, Int64) + HANDLE_PACKED_TYPE(UINT32, arc_ui32, UInt32) + HANDLE_PACKED_TYPE(UINT64, arc_ui64, UInt64) + + HANDLE_PACKED_TYPE(FIXED32, arc_ui32, UInt32) + HANDLE_PACKED_TYPE(FIXED64, arc_ui64, UInt64) + HANDLE_PACKED_TYPE(SFIXED32, arc_i32, Int32) + HANDLE_PACKED_TYPE(SFIXED64, arc_i64, Int64) + + HANDLE_PACKED_TYPE(FLOAT, float, Float) + HANDLE_PACKED_TYPE(DOUBLE, double, Double) + + HANDLE_PACKED_TYPE(BOOL, bool, Bool) +#undef HANDLE_PACKED_TYPE + + case FieldDescriptor::TYPE_ENUM: { + while (input->BytesUntilLimit() > 0) { + int value; + if (!WireFormatLite::ReadPrimitive<int, WireFormatLite::TYPE_ENUM>( + input, &value)) + return false; + if (message->GetDescriptor()->file()->syntax() == + FileDescriptor::SYNTAX_PROTO3) { + message_reflection->AddEnumValue(message, field, value); + } else { + const EnumValueDescriptor* enum_value = + field->enum_type()->FindValueByNumber(value); + if (enum_value != nullptr) { + message_reflection->AddEnum(message, field, enum_value); + } else { + // The enum value is not one of the known values. Add it to the + // UnknownFieldSet. + arc_i64 sign_extended_value = static_cast<arc_i64>(value); + message_reflection->MutableUnknownFields(message)->AddVarint( + WireFormatLite::GetTagFieldNumber(tag), sign_extended_value); + } + } + } + + break; + } + + case FieldDescriptor::TYPE_STRING: + case FieldDescriptor::TYPE_GROUP: + case FieldDescriptor::TYPE_MESSAGE: + case FieldDescriptor::TYPE_BYTES: + // Can't have packed fields of these types: these should be caught by + // the protocol compiler. + return false; + break; + } + + input->PopLimit(limit); + } else { + // Non-packed value (value_format == NORMAL_FORMAT) + switch (field->type()) { +#define HANDLE_TYPE(TYPE, CPPTYPE, CPPTYPE_METHOD) \ + case FieldDescriptor::TYPE_##TYPE: { \ + CPPTYPE value; \ + if (!WireFormatLite::ReadPrimitive<CPPTYPE, WireFormatLite::TYPE_##TYPE>( \ + input, &value)) \ + return false; \ + if (field->is_repeated()) { \ + message_reflection->Add##CPPTYPE_METHOD(message, field, value); \ + } else { \ + message_reflection->Set##CPPTYPE_METHOD(message, field, value); \ + } \ + break; \ + } + + HANDLE_TYPE(INT32, arc_i32, Int32) + HANDLE_TYPE(INT64, arc_i64, Int64) + HANDLE_TYPE(SINT32, arc_i32, Int32) + HANDLE_TYPE(SINT64, arc_i64, Int64) + HANDLE_TYPE(UINT32, arc_ui32, UInt32) + HANDLE_TYPE(UINT64, arc_ui64, UInt64) + + HANDLE_TYPE(FIXED32, arc_ui32, UInt32) + HANDLE_TYPE(FIXED64, arc_ui64, UInt64) + HANDLE_TYPE(SFIXED32, arc_i32, Int32) + HANDLE_TYPE(SFIXED64, arc_i64, Int64) + + HANDLE_TYPE(FLOAT, float, Float) + HANDLE_TYPE(DOUBLE, double, Double) + + HANDLE_TYPE(BOOL, bool, Bool) +#undef HANDLE_TYPE + + case FieldDescriptor::TYPE_ENUM: { + int value; + if (!WireFormatLite::ReadPrimitive<int, WireFormatLite::TYPE_ENUM>( + input, &value)) + return false; + if (field->is_repeated()) { + message_reflection->AddEnumValue(message, field, value); + } else { + message_reflection->SetEnumValue(message, field, value); + } + break; + } + + // Handle strings separately so that we can optimize the ctype=CORD case. + case FieldDescriptor::TYPE_STRING: { + bool strict_utf8_check = StrictUtf8Check(field); + TProtoStringType value; + if (!WireFormatLite::ReadString(input, &value)) return false; + if (strict_utf8_check) { + if (!WireFormatLite::VerifyUtf8String(value.data(), value.length(), + WireFormatLite::PARSE, + field->full_name().c_str())) { + return false; + } + } else { + VerifyUTF8StringNamedField(value.data(), value.length(), PARSE, + field->full_name().c_str()); + } + if (field->is_repeated()) { + message_reflection->AddString(message, field, value); + } else { + message_reflection->SetString(message, field, value); + } + break; + } + + case FieldDescriptor::TYPE_BYTES: { + TProtoStringType value; + if (!WireFormatLite::ReadBytes(input, &value)) return false; + if (field->is_repeated()) { + message_reflection->AddString(message, field, value); + } else { + message_reflection->SetString(message, field, value); + } + break; + } + + case FieldDescriptor::TYPE_GROUP: { + Message* sub_message; + if (field->is_repeated()) { + sub_message = message_reflection->AddMessage( + message, field, input->GetExtensionFactory()); + } else { + sub_message = message_reflection->MutableMessage( + message, field, input->GetExtensionFactory()); + } + + if (!WireFormatLite::ReadGroup(WireFormatLite::GetTagFieldNumber(tag), + input, sub_message)) + return false; + break; + } + + case FieldDescriptor::TYPE_MESSAGE: { + Message* sub_message; + if (field->is_repeated()) { + sub_message = message_reflection->AddMessage( + message, field, input->GetExtensionFactory()); + } else { + sub_message = message_reflection->MutableMessage( + message, field, input->GetExtensionFactory()); + } + + if (!WireFormatLite::ReadMessage(input, sub_message)) return false; + break; + } + } + } + + return true; +} + +bool WireFormat::ParseAndMergeMessageSetItem(io::CodedInputStream* input, + Message* message) { + struct MSReflective { + bool ParseField(int type_id, io::CodedInputStream* input) { + const FieldDescriptor* field = + message_reflection->FindKnownExtensionByNumber(type_id); + return ParseAndMergeMessageSetField(type_id, field, message, input); + } + + bool SkipField(arc_ui32 tag, io::CodedInputStream* input) { + return WireFormat::SkipField(input, tag, nullptr); + } + + const Reflection* message_reflection; + Message* message; + }; + + return ParseMessageSetItemImpl( + input, MSReflective{message->GetReflection(), message}); +} + +struct WireFormat::MessageSetParser { + const char* _InternalParse(const char* ptr, internal::ParseContext* ctx) { + // Parse a MessageSetItem + auto metadata = reflection->MutableInternalMetadata(msg); + TProtoStringType payload; + arc_ui32 type_id = 0; + bool payload_read = false; + while (!ctx->Done(&ptr)) { + // We use 64 bit tags in order to allow typeid's that span the whole + // range of 32 bit numbers. + arc_ui32 tag = static_cast<uint8_t>(*ptr++); + if (tag == WireFormatLite::kMessageSetTypeIdTag) { + arc_ui64 tmp; + ptr = ParseBigVarint(ptr, &tmp); + GOOGLE_PROTOBUF_PARSER_ASSERT(ptr); + type_id = tmp; + if (payload_read) { + const FieldDescriptor* field; + if (ctx->data().pool == nullptr) { + field = reflection->FindKnownExtensionByNumber(type_id); + } else { + field = + ctx->data().pool->FindExtensionByNumber(descriptor, type_id); + } + if (field == nullptr || field->message_type() == nullptr) { + WriteLengthDelimited( + type_id, payload, + metadata->mutable_unknown_fields<UnknownFieldSet>()); + } else { + Message* value = + field->is_repeated() + ? reflection->AddMessage(msg, field, ctx->data().factory) + : reflection->MutableMessage(msg, field, + ctx->data().factory); + const char* p; + // We can't use regular parse from string as we have to track + // proper recursion depth and descriptor pools. + ParseContext tmp_ctx(ctx->depth(), false, &p, payload); + tmp_ctx.data().pool = ctx->data().pool; + tmp_ctx.data().factory = ctx->data().factory; + GOOGLE_PROTOBUF_PARSER_ASSERT(value->_InternalParse(p, &tmp_ctx) && + tmp_ctx.EndedAtLimit()); + } + type_id = 0; + } + continue; + } else if (tag == WireFormatLite::kMessageSetMessageTag) { + if (type_id == 0) { + arc_i32 size = ReadSize(&ptr); + GOOGLE_PROTOBUF_PARSER_ASSERT(ptr); + ptr = ctx->ReadString(ptr, size, &payload); + GOOGLE_PROTOBUF_PARSER_ASSERT(ptr); + payload_read = true; + } else { + // We're now parsing the payload + const FieldDescriptor* field = nullptr; + if (descriptor->IsExtensionNumber(type_id)) { + if (ctx->data().pool == nullptr) { + field = reflection->FindKnownExtensionByNumber(type_id); + } else { + field = + ctx->data().pool->FindExtensionByNumber(descriptor, type_id); + } + } + ptr = WireFormat::_InternalParseAndMergeField( + msg, ptr, ctx, static_cast<arc_ui64>(type_id) * 8 + 2, reflection, + field); + type_id = 0; + } + } else { + // An unknown field in MessageSetItem. + ptr = ReadTag(ptr - 1, &tag); + if (tag == 0 || (tag & 7) == WireFormatLite::WIRETYPE_END_GROUP) { + ctx->SetLastTag(tag); + return ptr; + } + // Skip field. + ptr = internal::UnknownFieldParse( + tag, static_cast<TProtoStringType*>(nullptr), ptr, ctx); + } + GOOGLE_PROTOBUF_PARSER_ASSERT(ptr); + } + return ptr; + } + + const char* ParseMessageSet(const char* ptr, internal::ParseContext* ctx) { + while (!ctx->Done(&ptr)) { + arc_ui32 tag; + ptr = ReadTag(ptr, &tag); + if (PROTOBUF_PREDICT_FALSE(ptr == nullptr)) return nullptr; + if (tag == 0 || (tag & 7) == WireFormatLite::WIRETYPE_END_GROUP) { + ctx->SetLastTag(tag); + break; + } + if (tag == WireFormatLite::kMessageSetItemStartTag) { + // A message set item starts + ptr = ctx->ParseGroup(this, ptr, tag); + } else { + // Parse other fields as normal extensions. + int field_number = WireFormatLite::GetTagFieldNumber(tag); + const FieldDescriptor* field = nullptr; + if (descriptor->IsExtensionNumber(field_number)) { + if (ctx->data().pool == nullptr) { + field = reflection->FindKnownExtensionByNumber(field_number); + } else { + field = ctx->data().pool->FindExtensionByNumber(descriptor, + field_number); + } + } + ptr = WireFormat::_InternalParseAndMergeField(msg, ptr, ctx, tag, + reflection, field); + } + if (PROTOBUF_PREDICT_FALSE(ptr == nullptr)) return nullptr; + } + return ptr; + } + + Message* msg; + const Descriptor* descriptor; + const Reflection* reflection; +}; + +const char* WireFormat::_InternalParse(Message* msg, const char* ptr, + internal::ParseContext* ctx) { + const Descriptor* descriptor = msg->GetDescriptor(); + const Reflection* reflection = msg->GetReflection(); + GOOGLE_DCHECK(descriptor); + GOOGLE_DCHECK(reflection); + if (descriptor->options().message_set_wire_format()) { + MessageSetParser message_set{msg, descriptor, reflection}; + return message_set.ParseMessageSet(ptr, ctx); + } + while (!ctx->Done(&ptr)) { + arc_ui32 tag; + ptr = ReadTag(ptr, &tag); + if (PROTOBUF_PREDICT_FALSE(ptr == nullptr)) return nullptr; + if (tag == 0 || (tag & 7) == WireFormatLite::WIRETYPE_END_GROUP) { + ctx->SetLastTag(tag); + break; + } + const FieldDescriptor* field = nullptr; + + int field_number = WireFormatLite::GetTagFieldNumber(tag); + field = descriptor->FindFieldByNumber(field_number); + + // If that failed, check if the field is an extension. + if (field == nullptr && descriptor->IsExtensionNumber(field_number)) { + if (ctx->data().pool == nullptr) { + field = reflection->FindKnownExtensionByNumber(field_number); + } else { + field = + ctx->data().pool->FindExtensionByNumber(descriptor, field_number); + } + } + + ptr = _InternalParseAndMergeField(msg, ptr, ctx, tag, reflection, field); + if (PROTOBUF_PREDICT_FALSE(ptr == nullptr)) return nullptr; + } + return ptr; +} + +const char* WireFormat::_InternalParseAndMergeField( + Message* msg, const char* ptr, internal::ParseContext* ctx, arc_ui64 tag, + const Reflection* reflection, const FieldDescriptor* field) { + if (field == nullptr) { + // unknown field set parser takes 64bit tags, because message set type ids + // span the full 32 bit range making the tag span [0, 2^35) range. + return internal::UnknownFieldParse( + tag, reflection->MutableUnknownFields(msg), ptr, ctx); + } + if (WireFormatLite::GetTagWireType(tag) != + WireTypeForFieldType(field->type())) { + if (field->is_packable() && WireFormatLite::GetTagWireType(tag) == + WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + switch (field->type()) { +#define HANDLE_PACKED_TYPE(TYPE, CPPTYPE, CPPTYPE_METHOD) \ + case FieldDescriptor::TYPE_##TYPE: { \ + ptr = internal::Packed##CPPTYPE_METHOD##Parser( \ + reflection->MutableRepeatedFieldInternal<CPPTYPE>(msg, field), ptr, \ + ctx); \ + return ptr; \ + } + + HANDLE_PACKED_TYPE(INT32, arc_i32, Int32) + HANDLE_PACKED_TYPE(INT64, arc_i64, Int64) + HANDLE_PACKED_TYPE(SINT32, arc_i32, SInt32) + HANDLE_PACKED_TYPE(SINT64, arc_i64, SInt64) + HANDLE_PACKED_TYPE(UINT32, arc_ui32, UInt32) + HANDLE_PACKED_TYPE(UINT64, arc_ui64, UInt64) + + HANDLE_PACKED_TYPE(FIXED32, arc_ui32, Fixed32) + HANDLE_PACKED_TYPE(FIXED64, arc_ui64, Fixed64) + HANDLE_PACKED_TYPE(SFIXED32, arc_i32, SFixed32) + HANDLE_PACKED_TYPE(SFIXED64, arc_i64, SFixed64) + + HANDLE_PACKED_TYPE(FLOAT, float, Float) + HANDLE_PACKED_TYPE(DOUBLE, double, Double) + + HANDLE_PACKED_TYPE(BOOL, bool, Bool) +#undef HANDLE_PACKED_TYPE + + case FieldDescriptor::TYPE_ENUM: { + auto rep_enum = + reflection->MutableRepeatedFieldInternal<int>(msg, field); + bool open_enum = false; + if (field->file()->syntax() == FileDescriptor::SYNTAX_PROTO3 || + open_enum) { + ptr = internal::PackedEnumParser(rep_enum, ptr, ctx); + } else { + return ctx->ReadPackedVarint( + ptr, [rep_enum, field, reflection, msg](arc_ui64 val) { + if (field->enum_type()->FindValueByNumber(val) != nullptr) { + rep_enum->Add(val); + } else { + WriteVarint(field->number(), val, + reflection->MutableUnknownFields(msg)); + } + }); + } + return ptr; + } + + case FieldDescriptor::TYPE_STRING: + case FieldDescriptor::TYPE_GROUP: + case FieldDescriptor::TYPE_MESSAGE: + case FieldDescriptor::TYPE_BYTES: + GOOGLE_LOG(FATAL) << "Can't reach"; + return nullptr; + } + } else { + // mismatched wiretype; + return internal::UnknownFieldParse( + tag, reflection->MutableUnknownFields(msg), ptr, ctx); + } + } + + // Non-packed value + bool utf8_check = false; + bool strict_utf8_check = false; + switch (field->type()) { +#define HANDLE_TYPE(TYPE, CPPTYPE, CPPTYPE_METHOD) \ + case FieldDescriptor::TYPE_##TYPE: { \ + CPPTYPE value; \ + ptr = VarintParse(ptr, &value); \ + if (ptr == nullptr) return nullptr; \ + if (field->is_repeated()) { \ + reflection->Add##CPPTYPE_METHOD(msg, field, value); \ + } else { \ + reflection->Set##CPPTYPE_METHOD(msg, field, value); \ + } \ + return ptr; \ + } + + HANDLE_TYPE(BOOL, arc_ui64, Bool) + HANDLE_TYPE(INT32, arc_ui32, Int32) + HANDLE_TYPE(INT64, arc_ui64, Int64) + HANDLE_TYPE(UINT32, arc_ui32, UInt32) + HANDLE_TYPE(UINT64, arc_ui64, UInt64) + + case FieldDescriptor::TYPE_SINT32: { + arc_i32 value = ReadVarintZigZag32(&ptr); + if (ptr == nullptr) return nullptr; + if (field->is_repeated()) { + reflection->AddInt32(msg, field, value); + } else { + reflection->SetInt32(msg, field, value); + } + return ptr; + } + case FieldDescriptor::TYPE_SINT64: { + arc_i64 value = ReadVarintZigZag64(&ptr); + if (ptr == nullptr) return nullptr; + if (field->is_repeated()) { + reflection->AddInt64(msg, field, value); + } else { + reflection->SetInt64(msg, field, value); + } + return ptr; + } +#undef HANDLE_TYPE +#define HANDLE_TYPE(TYPE, CPPTYPE, CPPTYPE_METHOD) \ + case FieldDescriptor::TYPE_##TYPE: { \ + CPPTYPE value; \ + value = UnalignedLoad<CPPTYPE>(ptr); \ + ptr += sizeof(CPPTYPE); \ + if (field->is_repeated()) { \ + reflection->Add##CPPTYPE_METHOD(msg, field, value); \ + } else { \ + reflection->Set##CPPTYPE_METHOD(msg, field, value); \ + } \ + return ptr; \ + } + + HANDLE_TYPE(FIXED32, arc_ui32, UInt32) + HANDLE_TYPE(FIXED64, arc_ui64, UInt64) + HANDLE_TYPE(SFIXED32, arc_i32, Int32) + HANDLE_TYPE(SFIXED64, arc_i64, Int64) + + HANDLE_TYPE(FLOAT, float, Float) + HANDLE_TYPE(DOUBLE, double, Double) + +#undef HANDLE_TYPE + + case FieldDescriptor::TYPE_ENUM: { + arc_ui32 value; + ptr = VarintParse(ptr, &value); + if (ptr == nullptr) return nullptr; + if (field->is_repeated()) { + reflection->AddEnumValue(msg, field, value); + } else { + reflection->SetEnumValue(msg, field, value); + } + return ptr; + } + + // Handle strings separately so that we can optimize the ctype=CORD case. + case FieldDescriptor::TYPE_STRING: + utf8_check = true; + strict_utf8_check = StrictUtf8Check(field); + PROTOBUF_FALLTHROUGH_INTENDED; + case FieldDescriptor::TYPE_BYTES: { + int size = ReadSize(&ptr); + if (ptr == nullptr) return nullptr; + TProtoStringType value; + ptr = ctx->ReadString(ptr, size, &value); + if (ptr == nullptr) return nullptr; + if (utf8_check) { + if (strict_utf8_check) { + if (!WireFormatLite::VerifyUtf8String(value.data(), value.length(), + WireFormatLite::PARSE, + field->full_name().c_str())) { + return nullptr; + } + } else { + VerifyUTF8StringNamedField(value.data(), value.length(), PARSE, + field->full_name().c_str()); + } + } + if (field->is_repeated()) { + reflection->AddString(msg, field, std::move(value)); + } else { + reflection->SetString(msg, field, std::move(value)); + } + return ptr; + } + + case FieldDescriptor::TYPE_GROUP: { + Message* sub_message; + if (field->is_repeated()) { + sub_message = reflection->AddMessage(msg, field, ctx->data().factory); + } else { + sub_message = + reflection->MutableMessage(msg, field, ctx->data().factory); + } + + return ctx->ParseGroup(sub_message, ptr, tag); + } + + case FieldDescriptor::TYPE_MESSAGE: { + Message* sub_message; + if (field->is_repeated()) { + sub_message = reflection->AddMessage(msg, field, ctx->data().factory); + } else { + sub_message = + reflection->MutableMessage(msg, field, ctx->data().factory); + } + return ctx->ParseMessage(sub_message, ptr); + } + } + + // GCC 8 complains about control reaching end of non-void function here. + // Let's keep it happy by returning a nullptr. + return nullptr; +} + +// =================================================================== + +uint8_t* WireFormat::_InternalSerialize(const Message& message, uint8_t* target, + io::EpsCopyOutputStream* stream) { + const Descriptor* descriptor = message.GetDescriptor(); + const Reflection* message_reflection = message.GetReflection(); + + std::vector<const FieldDescriptor*> fields; + + // Fields of map entry should always be serialized. + if (descriptor->options().map_entry()) { + for (int i = 0; i < descriptor->field_count(); i++) { + fields.push_back(descriptor->field(i)); + } + } else { + message_reflection->ListFields(message, &fields); + } + + for (auto field : fields) { + target = InternalSerializeField(field, message, target, stream); + } + + if (descriptor->options().message_set_wire_format()) { + return InternalSerializeUnknownMessageSetItemsToArray( + message_reflection->GetUnknownFields(message), target, stream); + } else { + return InternalSerializeUnknownFieldsToArray( + message_reflection->GetUnknownFields(message), target, stream); + } +} + +uint8_t* SerializeMapKeyWithCachedSizes(const FieldDescriptor* field, + const MapKey& value, uint8_t* target, + io::EpsCopyOutputStream* stream) { + target = stream->EnsureSpace(target); + switch (field->type()) { + case FieldDescriptor::TYPE_DOUBLE: + case FieldDescriptor::TYPE_FLOAT: + case FieldDescriptor::TYPE_GROUP: + case FieldDescriptor::TYPE_MESSAGE: + case FieldDescriptor::TYPE_BYTES: + case FieldDescriptor::TYPE_ENUM: + GOOGLE_LOG(FATAL) << "Unsupported"; + break; +#define CASE_TYPE(FieldType, CamelFieldType, CamelCppType) \ + case FieldDescriptor::TYPE_##FieldType: \ + target = WireFormatLite::Write##CamelFieldType##ToArray( \ + 1, value.Get##CamelCppType##Value(), target); \ + break; + CASE_TYPE(INT64, Int64, Int64) + CASE_TYPE(UINT64, UInt64, UInt64) + CASE_TYPE(INT32, Int32, Int32) + CASE_TYPE(FIXED64, Fixed64, UInt64) + CASE_TYPE(FIXED32, Fixed32, UInt32) + CASE_TYPE(BOOL, Bool, Bool) + CASE_TYPE(UINT32, UInt32, UInt32) + CASE_TYPE(SFIXED32, SFixed32, Int32) + CASE_TYPE(SFIXED64, SFixed64, Int64) + CASE_TYPE(SINT32, SInt32, Int32) + CASE_TYPE(SINT64, SInt64, Int64) +#undef CASE_TYPE + case FieldDescriptor::TYPE_STRING: + target = stream->WriteString(1, value.GetStringValue(), target); + break; + } + return target; +} + +static uint8_t* SerializeMapValueRefWithCachedSizes( + const FieldDescriptor* field, const MapValueConstRef& value, + uint8_t* target, io::EpsCopyOutputStream* stream) { + target = stream->EnsureSpace(target); + switch (field->type()) { +#define CASE_TYPE(FieldType, CamelFieldType, CamelCppType) \ + case FieldDescriptor::TYPE_##FieldType: \ + target = WireFormatLite::Write##CamelFieldType##ToArray( \ + 2, value.Get##CamelCppType##Value(), target); \ + break; + CASE_TYPE(INT64, Int64, Int64) + CASE_TYPE(UINT64, UInt64, UInt64) + CASE_TYPE(INT32, Int32, Int32) + CASE_TYPE(FIXED64, Fixed64, UInt64) + CASE_TYPE(FIXED32, Fixed32, UInt32) + CASE_TYPE(BOOL, Bool, Bool) + CASE_TYPE(UINT32, UInt32, UInt32) + CASE_TYPE(SFIXED32, SFixed32, Int32) + CASE_TYPE(SFIXED64, SFixed64, Int64) + CASE_TYPE(SINT32, SInt32, Int32) + CASE_TYPE(SINT64, SInt64, Int64) + CASE_TYPE(ENUM, Enum, Enum) + CASE_TYPE(DOUBLE, Double, Double) + CASE_TYPE(FLOAT, Float, Float) +#undef CASE_TYPE + case FieldDescriptor::TYPE_STRING: + case FieldDescriptor::TYPE_BYTES: + target = stream->WriteString(2, value.GetStringValue(), target); + break; + case FieldDescriptor::TYPE_MESSAGE: + target = WireFormatLite::InternalWriteMessage(2, value.GetMessageValue(), + target, stream); + break; + case FieldDescriptor::TYPE_GROUP: + target = WireFormatLite::InternalWriteGroup(2, value.GetMessageValue(), + target, stream); + break; + } + return target; +} + +class MapKeySorter { + public: + static std::vector<MapKey> SortKey(const Message& message, + const Reflection* reflection, + const FieldDescriptor* field) { + std::vector<MapKey> sorted_key_list; + for (MapIterator it = + reflection->MapBegin(const_cast<Message*>(&message), field); + it != reflection->MapEnd(const_cast<Message*>(&message), field); + ++it) { + sorted_key_list.push_back(it.GetKey()); + } + MapKeyComparator comparator; + std::sort(sorted_key_list.begin(), sorted_key_list.end(), comparator); + return sorted_key_list; + } + + private: + class MapKeyComparator { + public: + bool operator()(const MapKey& a, const MapKey& b) const { + GOOGLE_DCHECK(a.type() == b.type()); + switch (a.type()) { +#define CASE_TYPE(CppType, CamelCppType) \ + case FieldDescriptor::CPPTYPE_##CppType: { \ + return a.Get##CamelCppType##Value() < b.Get##CamelCppType##Value(); \ + } + CASE_TYPE(STRING, String) + CASE_TYPE(INT64, Int64) + CASE_TYPE(INT32, Int32) + CASE_TYPE(UINT64, UInt64) + CASE_TYPE(UINT32, UInt32) + CASE_TYPE(BOOL, Bool) +#undef CASE_TYPE + + default: + GOOGLE_LOG(DFATAL) << "Invalid key for map field."; + return true; + } + } + }; +}; + +static uint8_t* InternalSerializeMapEntry(const FieldDescriptor* field, + const MapKey& key, + const MapValueConstRef& value, + uint8_t* target, + io::EpsCopyOutputStream* stream) { + const FieldDescriptor* key_field = field->message_type()->field(0); + const FieldDescriptor* value_field = field->message_type()->field(1); + + size_t size = kMapEntryTagByteSize; + size += MapKeyDataOnlyByteSize(key_field, key); + size += MapValueRefDataOnlyByteSize(value_field, value); + target = stream->EnsureSpace(target); + target = WireFormatLite::WriteTagToArray( + field->number(), WireFormatLite::WIRETYPE_LENGTH_DELIMITED, target); + target = io::CodedOutputStream::WriteVarint32ToArray(size, target); + target = SerializeMapKeyWithCachedSizes(key_field, key, target, stream); + target = + SerializeMapValueRefWithCachedSizes(value_field, value, target, stream); + return target; +} + +uint8_t* WireFormat::InternalSerializeField(const FieldDescriptor* field, + const Message& message, + uint8_t* target, + io::EpsCopyOutputStream* stream) { + const Reflection* message_reflection = message.GetReflection(); + + if (field->is_extension() && + field->containing_type()->options().message_set_wire_format() && + field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE && + !field->is_repeated()) { + return InternalSerializeMessageSetItem(field, message, target, stream); + } + + // For map fields, we can use either repeated field reflection or map + // reflection. Our choice has some subtle effects. If we use repeated field + // reflection here, then the repeated field representation becomes + // authoritative for this field: any existing references that came from map + // reflection remain valid for reading, but mutations to them are lost and + // will be overwritten next time we call map reflection! + // + // So far this mainly affects Python, which keeps long-term references to map + // values around, and always uses map reflection. See: b/35918691 + // + // Here we choose to use map reflection API as long as the internal + // map is valid. In this way, the serialization doesn't change map field's + // internal state and existing references that came from map reflection remain + // valid for both reading and writing. + if (field->is_map()) { + const MapFieldBase* map_field = + message_reflection->GetMapData(message, field); + if (map_field->IsMapValid()) { + if (stream->IsSerializationDeterministic()) { + std::vector<MapKey> sorted_key_list = + MapKeySorter::SortKey(message, message_reflection, field); + for (std::vector<MapKey>::iterator it = sorted_key_list.begin(); + it != sorted_key_list.end(); ++it) { + MapValueConstRef map_value; + message_reflection->LookupMapValue(message, field, *it, &map_value); + target = + InternalSerializeMapEntry(field, *it, map_value, target, stream); + } + } else { + for (MapIterator it = message_reflection->MapBegin( + const_cast<Message*>(&message), field); + it != + message_reflection->MapEnd(const_cast<Message*>(&message), field); + ++it) { + target = InternalSerializeMapEntry(field, it.GetKey(), + it.GetValueRef(), target, stream); + } + } + + return target; + } + } + int count = 0; + + if (field->is_repeated()) { + count = message_reflection->FieldSize(message, field); + } else if (field->containing_type()->options().map_entry()) { + // Map entry fields always need to be serialized. + count = 1; + } else if (message_reflection->HasField(message, field)) { + count = 1; + } + + // map_entries is for maps that'll be deterministically serialized. + std::vector<const Message*> map_entries; + if (count > 1 && field->is_map() && stream->IsSerializationDeterministic()) { + map_entries = + DynamicMapSorter::Sort(message, count, message_reflection, field); + } + + if (field->is_packed()) { + if (count == 0) return target; + target = stream->EnsureSpace(target); + switch (field->type()) { +#define HANDLE_PRIMITIVE_TYPE(TYPE, CPPTYPE, TYPE_METHOD, CPPTYPE_METHOD) \ + case FieldDescriptor::TYPE_##TYPE: { \ + auto r = \ + message_reflection->GetRepeatedFieldInternal<CPPTYPE>(message, field); \ + target = stream->Write##TYPE_METHOD##Packed( \ + field->number(), r, FieldDataOnlyByteSize(field, message), target); \ + break; \ + } + + HANDLE_PRIMITIVE_TYPE(INT32, arc_i32, Int32, Int32) + HANDLE_PRIMITIVE_TYPE(INT64, arc_i64, Int64, Int64) + HANDLE_PRIMITIVE_TYPE(SINT32, arc_i32, SInt32, Int32) + HANDLE_PRIMITIVE_TYPE(SINT64, arc_i64, SInt64, Int64) + HANDLE_PRIMITIVE_TYPE(UINT32, arc_ui32, UInt32, UInt32) + HANDLE_PRIMITIVE_TYPE(UINT64, arc_ui64, UInt64, UInt64) + HANDLE_PRIMITIVE_TYPE(ENUM, int, Enum, Enum) + +#undef HANDLE_PRIMITIVE_TYPE +#define HANDLE_PRIMITIVE_TYPE(TYPE, CPPTYPE, TYPE_METHOD, CPPTYPE_METHOD) \ + case FieldDescriptor::TYPE_##TYPE: { \ + auto r = \ + message_reflection->GetRepeatedFieldInternal<CPPTYPE>(message, field); \ + target = stream->WriteFixedPacked(field->number(), r, target); \ + break; \ + } + + HANDLE_PRIMITIVE_TYPE(FIXED32, arc_ui32, Fixed32, UInt32) + HANDLE_PRIMITIVE_TYPE(FIXED64, arc_ui64, Fixed64, UInt64) + HANDLE_PRIMITIVE_TYPE(SFIXED32, arc_i32, SFixed32, Int32) + HANDLE_PRIMITIVE_TYPE(SFIXED64, arc_i64, SFixed64, Int64) + + HANDLE_PRIMITIVE_TYPE(FLOAT, float, Float, Float) + HANDLE_PRIMITIVE_TYPE(DOUBLE, double, Double, Double) + + HANDLE_PRIMITIVE_TYPE(BOOL, bool, Bool, Bool) +#undef HANDLE_PRIMITIVE_TYPE + default: + GOOGLE_LOG(FATAL) << "Invalid descriptor"; + } + return target; + } + + for (int j = 0; j < count; j++) { + target = stream->EnsureSpace(target); + switch (field->type()) { +#define HANDLE_PRIMITIVE_TYPE(TYPE, CPPTYPE, TYPE_METHOD, CPPTYPE_METHOD) \ + case FieldDescriptor::TYPE_##TYPE: { \ + const CPPTYPE value = \ + field->is_repeated() \ + ? message_reflection->GetRepeated##CPPTYPE_METHOD(message, field, \ + j) \ + : message_reflection->Get##CPPTYPE_METHOD(message, field); \ + target = WireFormatLite::Write##TYPE_METHOD##ToArray(field->number(), \ + value, target); \ + break; \ + } + + HANDLE_PRIMITIVE_TYPE(INT32, arc_i32, Int32, Int32) + HANDLE_PRIMITIVE_TYPE(INT64, arc_i64, Int64, Int64) + HANDLE_PRIMITIVE_TYPE(SINT32, arc_i32, SInt32, Int32) + HANDLE_PRIMITIVE_TYPE(SINT64, arc_i64, SInt64, Int64) + HANDLE_PRIMITIVE_TYPE(UINT32, arc_ui32, UInt32, UInt32) + HANDLE_PRIMITIVE_TYPE(UINT64, arc_ui64, UInt64, UInt64) + + HANDLE_PRIMITIVE_TYPE(FIXED32, arc_ui32, Fixed32, UInt32) + HANDLE_PRIMITIVE_TYPE(FIXED64, arc_ui64, Fixed64, UInt64) + HANDLE_PRIMITIVE_TYPE(SFIXED32, arc_i32, SFixed32, Int32) + HANDLE_PRIMITIVE_TYPE(SFIXED64, arc_i64, SFixed64, Int64) + + HANDLE_PRIMITIVE_TYPE(FLOAT, float, Float, Float) + HANDLE_PRIMITIVE_TYPE(DOUBLE, double, Double, Double) + + HANDLE_PRIMITIVE_TYPE(BOOL, bool, Bool, Bool) +#undef HANDLE_PRIMITIVE_TYPE + +#define HANDLE_TYPE(TYPE, TYPE_METHOD, CPPTYPE_METHOD) \ + case FieldDescriptor::TYPE_##TYPE: \ + target = WireFormatLite::InternalWrite##TYPE_METHOD( \ + field->number(), \ + field->is_repeated() \ + ? (map_entries.empty() \ + ? message_reflection->GetRepeated##CPPTYPE_METHOD(message, \ + field, j) \ + : *map_entries[j]) \ + : message_reflection->Get##CPPTYPE_METHOD(message, field), \ + target, stream); \ + break; + + HANDLE_TYPE(GROUP, Group, Message) + HANDLE_TYPE(MESSAGE, Message, Message) +#undef HANDLE_TYPE + + case FieldDescriptor::TYPE_ENUM: { + const EnumValueDescriptor* value = + field->is_repeated() + ? message_reflection->GetRepeatedEnum(message, field, j) + : message_reflection->GetEnum(message, field); + target = WireFormatLite::WriteEnumToArray(field->number(), + value->number(), target); + break; + } + + // Handle strings separately so that we can get string references + // instead of copying. + case FieldDescriptor::TYPE_STRING: { + bool strict_utf8_check = StrictUtf8Check(field); + TProtoStringType scratch; + const TProtoStringType& value = + field->is_repeated() + ? message_reflection->GetRepeatedStringReference(message, field, + j, &scratch) + : message_reflection->GetStringReference(message, field, + &scratch); + if (strict_utf8_check) { + WireFormatLite::VerifyUtf8String(value.data(), value.length(), + WireFormatLite::SERIALIZE, + field->full_name().c_str()); + } else { + VerifyUTF8StringNamedField(value.data(), value.length(), SERIALIZE, + field->full_name().c_str()); + } + target = stream->WriteString(field->number(), value, target); + break; + } + + case FieldDescriptor::TYPE_BYTES: { + TProtoStringType scratch; + const TProtoStringType& value = + field->is_repeated() + ? message_reflection->GetRepeatedStringReference(message, field, + j, &scratch) + : message_reflection->GetStringReference(message, field, + &scratch); + target = stream->WriteString(field->number(), value, target); + break; + } + } + } + return target; +} + +uint8_t* WireFormat::InternalSerializeMessageSetItem( + const FieldDescriptor* field, const Message& message, uint8_t* target, + io::EpsCopyOutputStream* stream) { + const Reflection* message_reflection = message.GetReflection(); + + target = stream->EnsureSpace(target); + // Start group. + target = io::CodedOutputStream::WriteTagToArray( + WireFormatLite::kMessageSetItemStartTag, target); + // Write type ID. + target = WireFormatLite::WriteUInt32ToArray( + WireFormatLite::kMessageSetTypeIdNumber, field->number(), target); + // Write message. + target = WireFormatLite::InternalWriteMessage( + WireFormatLite::kMessageSetMessageNumber, + message_reflection->GetMessage(message, field), target, stream); + // End group. + target = stream->EnsureSpace(target); + target = io::CodedOutputStream::WriteTagToArray( + WireFormatLite::kMessageSetItemEndTag, target); + return target; +} + +// =================================================================== + +size_t WireFormat::ByteSize(const Message& message) { + const Descriptor* descriptor = message.GetDescriptor(); + const Reflection* message_reflection = message.GetReflection(); + + size_t our_size = 0; + + std::vector<const FieldDescriptor*> fields; + + // Fields of map entry should always be serialized. + if (descriptor->options().map_entry()) { + for (int i = 0; i < descriptor->field_count(); i++) { + fields.push_back(descriptor->field(i)); + } + } else { + message_reflection->ListFields(message, &fields); + } + + for (const FieldDescriptor* field : fields) { + our_size += FieldByteSize(field, message); + } + + if (descriptor->options().message_set_wire_format()) { + our_size += ComputeUnknownMessageSetItemsSize( + message_reflection->GetUnknownFields(message)); + } else { + our_size += + ComputeUnknownFieldsSize(message_reflection->GetUnknownFields(message)); + } + + return our_size; +} + +size_t WireFormat::FieldByteSize(const FieldDescriptor* field, + const Message& message) { + const Reflection* message_reflection = message.GetReflection(); + + if (field->is_extension() && + field->containing_type()->options().message_set_wire_format() && + field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE && + !field->is_repeated()) { + return MessageSetItemByteSize(field, message); + } + + size_t count = 0; + if (field->is_repeated()) { + if (field->is_map()) { + const MapFieldBase* map_field = + message_reflection->GetMapData(message, field); + if (map_field->IsMapValid()) { + count = FromIntSize(map_field->size()); + } else { + count = FromIntSize(message_reflection->FieldSize(message, field)); + } + } else { + count = FromIntSize(message_reflection->FieldSize(message, field)); + } + } else if (field->containing_type()->options().map_entry()) { + // Map entry fields always need to be serialized. + count = 1; + } else if (message_reflection->HasField(message, field)) { + count = 1; + } + + const size_t data_size = FieldDataOnlyByteSize(field, message); + size_t our_size = data_size; + if (field->is_packed()) { + if (data_size > 0) { + // Packed fields get serialized like a string, not their native type. + // Technically this doesn't really matter; the size only changes if it's + // a GROUP + our_size += TagSize(field->number(), FieldDescriptor::TYPE_STRING); + our_size += io::CodedOutputStream::VarintSize32(data_size); + } + } else { + our_size += count * TagSize(field->number(), field->type()); + } + return our_size; +} + +size_t MapKeyDataOnlyByteSize(const FieldDescriptor* field, + const MapKey& value) { + GOOGLE_DCHECK_EQ(FieldDescriptor::TypeToCppType(field->type()), value.type()); + switch (field->type()) { + case FieldDescriptor::TYPE_DOUBLE: + case FieldDescriptor::TYPE_FLOAT: + case FieldDescriptor::TYPE_GROUP: + case FieldDescriptor::TYPE_MESSAGE: + case FieldDescriptor::TYPE_BYTES: + case FieldDescriptor::TYPE_ENUM: + GOOGLE_LOG(FATAL) << "Unsupported"; + return 0; +#define CASE_TYPE(FieldType, CamelFieldType, CamelCppType) \ + case FieldDescriptor::TYPE_##FieldType: \ + return WireFormatLite::CamelFieldType##Size( \ + value.Get##CamelCppType##Value()); + +#define FIXED_CASE_TYPE(FieldType, CamelFieldType) \ + case FieldDescriptor::TYPE_##FieldType: \ + return WireFormatLite::k##CamelFieldType##Size; + + CASE_TYPE(INT32, Int32, Int32); + CASE_TYPE(INT64, Int64, Int64); + CASE_TYPE(UINT32, UInt32, UInt32); + CASE_TYPE(UINT64, UInt64, UInt64); + CASE_TYPE(SINT32, SInt32, Int32); + CASE_TYPE(SINT64, SInt64, Int64); + CASE_TYPE(STRING, String, String); + FIXED_CASE_TYPE(FIXED32, Fixed32); + FIXED_CASE_TYPE(FIXED64, Fixed64); + FIXED_CASE_TYPE(SFIXED32, SFixed32); + FIXED_CASE_TYPE(SFIXED64, SFixed64); + FIXED_CASE_TYPE(BOOL, Bool); + +#undef CASE_TYPE +#undef FIXED_CASE_TYPE + } + GOOGLE_LOG(FATAL) << "Cannot get here"; + return 0; +} + +static size_t MapValueRefDataOnlyByteSize(const FieldDescriptor* field, + const MapValueConstRef& value) { + switch (field->type()) { + case FieldDescriptor::TYPE_GROUP: + GOOGLE_LOG(FATAL) << "Unsupported"; + return 0; +#define CASE_TYPE(FieldType, CamelFieldType, CamelCppType) \ + case FieldDescriptor::TYPE_##FieldType: \ + return WireFormatLite::CamelFieldType##Size( \ + value.Get##CamelCppType##Value()); + +#define FIXED_CASE_TYPE(FieldType, CamelFieldType) \ + case FieldDescriptor::TYPE_##FieldType: \ + return WireFormatLite::k##CamelFieldType##Size; + + CASE_TYPE(INT32, Int32, Int32); + CASE_TYPE(INT64, Int64, Int64); + CASE_TYPE(UINT32, UInt32, UInt32); + CASE_TYPE(UINT64, UInt64, UInt64); + CASE_TYPE(SINT32, SInt32, Int32); + CASE_TYPE(SINT64, SInt64, Int64); + CASE_TYPE(STRING, String, String); + CASE_TYPE(BYTES, Bytes, String); + CASE_TYPE(ENUM, Enum, Enum); + CASE_TYPE(MESSAGE, Message, Message); + FIXED_CASE_TYPE(FIXED32, Fixed32); + FIXED_CASE_TYPE(FIXED64, Fixed64); + FIXED_CASE_TYPE(SFIXED32, SFixed32); + FIXED_CASE_TYPE(SFIXED64, SFixed64); + FIXED_CASE_TYPE(DOUBLE, Double); + FIXED_CASE_TYPE(FLOAT, Float); + FIXED_CASE_TYPE(BOOL, Bool); + +#undef CASE_TYPE +#undef FIXED_CASE_TYPE + } + GOOGLE_LOG(FATAL) << "Cannot get here"; + return 0; +} + +size_t WireFormat::FieldDataOnlyByteSize(const FieldDescriptor* field, + const Message& message) { + const Reflection* message_reflection = message.GetReflection(); + + size_t data_size = 0; + + if (field->is_map()) { + const MapFieldBase* map_field = + message_reflection->GetMapData(message, field); + if (map_field->IsMapValid()) { + MapIterator iter(const_cast<Message*>(&message), field); + MapIterator end(const_cast<Message*>(&message), field); + const FieldDescriptor* key_field = field->message_type()->field(0); + const FieldDescriptor* value_field = field->message_type()->field(1); + for (map_field->MapBegin(&iter), map_field->MapEnd(&end); iter != end; + ++iter) { + size_t size = kMapEntryTagByteSize; + size += MapKeyDataOnlyByteSize(key_field, iter.GetKey()); + size += MapValueRefDataOnlyByteSize(value_field, iter.GetValueRef()); + data_size += WireFormatLite::LengthDelimitedSize(size); + } + return data_size; + } + } + + size_t count = 0; + if (field->is_repeated()) { + count = + internal::FromIntSize(message_reflection->FieldSize(message, field)); + } else if (field->containing_type()->options().map_entry()) { + // Map entry fields always need to be serialized. + count = 1; + } else if (message_reflection->HasField(message, field)) { + count = 1; + } + + switch (field->type()) { +#define HANDLE_TYPE(TYPE, TYPE_METHOD, CPPTYPE_METHOD) \ + case FieldDescriptor::TYPE_##TYPE: \ + if (field->is_repeated()) { \ + for (size_t j = 0; j < count; j++) { \ + data_size += WireFormatLite::TYPE_METHOD##Size( \ + message_reflection->GetRepeated##CPPTYPE_METHOD(message, field, \ + j)); \ + } \ + } else { \ + data_size += WireFormatLite::TYPE_METHOD##Size( \ + message_reflection->Get##CPPTYPE_METHOD(message, field)); \ + } \ + break; + +#define HANDLE_FIXED_TYPE(TYPE, TYPE_METHOD) \ + case FieldDescriptor::TYPE_##TYPE: \ + data_size += count * WireFormatLite::k##TYPE_METHOD##Size; \ + break; + + HANDLE_TYPE(INT32, Int32, Int32) + HANDLE_TYPE(INT64, Int64, Int64) + HANDLE_TYPE(SINT32, SInt32, Int32) + HANDLE_TYPE(SINT64, SInt64, Int64) + HANDLE_TYPE(UINT32, UInt32, UInt32) + HANDLE_TYPE(UINT64, UInt64, UInt64) + + HANDLE_FIXED_TYPE(FIXED32, Fixed32) + HANDLE_FIXED_TYPE(FIXED64, Fixed64) + HANDLE_FIXED_TYPE(SFIXED32, SFixed32) + HANDLE_FIXED_TYPE(SFIXED64, SFixed64) + + HANDLE_FIXED_TYPE(FLOAT, Float) + HANDLE_FIXED_TYPE(DOUBLE, Double) + + HANDLE_FIXED_TYPE(BOOL, Bool) + + HANDLE_TYPE(GROUP, Group, Message) + HANDLE_TYPE(MESSAGE, Message, Message) +#undef HANDLE_TYPE +#undef HANDLE_FIXED_TYPE + + case FieldDescriptor::TYPE_ENUM: { + if (field->is_repeated()) { + for (size_t j = 0; j < count; j++) { + data_size += WireFormatLite::EnumSize( + message_reflection->GetRepeatedEnum(message, field, j)->number()); + } + } else { + data_size += WireFormatLite::EnumSize( + message_reflection->GetEnum(message, field)->number()); + } + break; + } + + // Handle strings separately so that we can get string references + // instead of copying. + case FieldDescriptor::TYPE_STRING: + case FieldDescriptor::TYPE_BYTES: { + for (size_t j = 0; j < count; j++) { + TProtoStringType scratch; + const TProtoStringType& value = + field->is_repeated() + ? message_reflection->GetRepeatedStringReference(message, field, + j, &scratch) + : message_reflection->GetStringReference(message, field, + &scratch); + data_size += WireFormatLite::StringSize(value); + } + break; + } + } + return data_size; +} + +size_t WireFormat::MessageSetItemByteSize(const FieldDescriptor* field, + const Message& message) { + const Reflection* message_reflection = message.GetReflection(); + + size_t our_size = WireFormatLite::kMessageSetItemTagsSize; + + // type_id + our_size += io::CodedOutputStream::VarintSize32(field->number()); + + // message + const Message& sub_message = message_reflection->GetMessage(message, field); + size_t message_size = sub_message.ByteSizeLong(); + + our_size += io::CodedOutputStream::VarintSize32(message_size); + our_size += message_size; + + return our_size; +} + +// Compute the size of the UnknownFieldSet on the wire. +size_t ComputeUnknownFieldsSize(const InternalMetadata& metadata, + size_t total_size, CachedSize* cached_size) { + total_size += WireFormat::ComputeUnknownFieldsSize( + metadata.unknown_fields<UnknownFieldSet>( + UnknownFieldSet::default_instance)); + cached_size->Set(ToCachedSize(total_size)); + return total_size; +} + +} // namespace internal +} // namespace protobuf +} // namespace google + +#include <google/protobuf/port_undef.inc> diff --git a/contrib/libs/protobuf_old/src/google/protobuf/wire_format.h b/contrib/libs/protobuf_old/src/google/protobuf/wire_format.h new file mode 100644 index 0000000000..2ff7eb3b45 --- /dev/null +++ b/contrib/libs/protobuf_old/src/google/protobuf/wire_format.h @@ -0,0 +1,414 @@ +// 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: kenton@google.com (Kenton Varda) +// atenasio@google.com (Chris Atenasio) (ZigZag transform) +// Based on original Protocol Buffers design by +// Sanjay Ghemawat, Jeff Dean, and others. +// +// This header is logically internal, but is made public because it is used +// from protocol-compiler-generated code, which may reside in other components. + +#ifndef GOOGLE_PROTOBUF_WIRE_FORMAT_H__ +#define GOOGLE_PROTOBUF_WIRE_FORMAT_H__ + +#include <string> + +#include <google/protobuf/stubs/common.h> +#include <google/protobuf/parse_context.h> +#include <google/protobuf/io/coded_stream.h> +#include <google/protobuf/descriptor.h> +#include <google/protobuf/generated_message_util.h> +#include <google/protobuf/message.h> +#include <google/protobuf/metadata_lite.h> +#include <google/protobuf/wire_format_lite.h> +#include <google/protobuf/stubs/casts.h> + +#ifdef SWIG +#error "You cannot SWIG proto headers" +#endif + +#include <google/protobuf/port_def.inc> + +namespace google { +namespace protobuf { +class MapKey; // map_field.h +class UnknownFieldSet; // unknown_field_set.h +} // namespace protobuf +} // namespace google + +namespace google { +namespace protobuf { +namespace internal { + +// This class is for internal use by the protocol buffer library and by +// protocol-compiler-generated message classes. It must not be called +// directly by clients. +// +// This class contains code for implementing the binary protocol buffer +// wire format via reflection. The WireFormatLite class implements the +// non-reflection based routines. +// +// This class is really a namespace that contains only static methods +class PROTOBUF_EXPORT WireFormat { + public: + // Given a field return its WireType + static inline WireFormatLite::WireType WireTypeForField( + const FieldDescriptor* field); + + // Given a FieldDescriptor::Type return its WireType + static inline WireFormatLite::WireType WireTypeForFieldType( + FieldDescriptor::Type type); + + // Compute the byte size of a tag. For groups, this includes both the start + // and end tags. + static inline size_t TagSize(int field_number, FieldDescriptor::Type type); + + // These procedures can be used to implement the methods of Message which + // handle parsing and serialization of the protocol buffer wire format + // using only the Reflection interface. When you ask the protocol + // compiler to optimize for code size rather than speed, it will implement + // those methods in terms of these procedures. Of course, these are much + // slower than the specialized implementations which the protocol compiler + // generates when told to optimize for speed. + + // Read a message in protocol buffer wire format. + // + // This procedure reads either to the end of the input stream or through + // a WIRETYPE_END_GROUP tag ending the message, whichever comes first. + // It returns false if the input is invalid. + // + // Required fields are NOT checked by this method. You must call + // IsInitialized() on the resulting message yourself. + static bool ParseAndMergePartial(io::CodedInputStream* input, + Message* message); + + // This is meant for internal protobuf use (WireFormat is an internal class). + // This is the reflective implementation of the _InternalParse functionality. + static const char* _InternalParse(Message* msg, const char* ptr, + internal::ParseContext* ctx); + + // Serialize a message in protocol buffer wire format. + // + // Any embedded messages within the message must have their correct sizes + // cached. However, the top-level message need not; its size is passed as + // a parameter to this procedure. + // + // These return false iff the underlying stream returns a write error. + static void SerializeWithCachedSizes(const Message& message, int size, + io::CodedOutputStream* output) { + int expected_endpoint = output->ByteCount() + size; + output->SetCur( + _InternalSerialize(message, output->Cur(), output->EpsCopy())); + GOOGLE_CHECK_EQ(output->ByteCount(), expected_endpoint) + << ": Protocol message serialized to a size different from what was " + "originally expected. Perhaps it was modified by another thread " + "during serialization?"; + } + static uint8_t* _InternalSerialize(const Message& message, uint8_t* target, + io::EpsCopyOutputStream* stream); + + // Implements Message::ByteSize() via reflection. WARNING: The result + // of this method is *not* cached anywhere. However, all embedded messages + // will have their ByteSize() methods called, so their sizes will be cached. + // Therefore, calling this method is sufficient to allow you to call + // WireFormat::SerializeWithCachedSizes() on the same object. + static size_t ByteSize(const Message& message); + + // ----------------------------------------------------------------- + // Helpers for dealing with unknown fields + + // Skips a field value of the given WireType. The input should start + // positioned immediately after the tag. If unknown_fields is non-nullptr, + // the contents of the field will be added to it. + static bool SkipField(io::CodedInputStream* input, arc_ui32 tag, + UnknownFieldSet* unknown_fields); + + // Reads and ignores a message from the input. If unknown_fields is + // non-nullptr, the contents will be added to it. + static bool SkipMessage(io::CodedInputStream* input, + UnknownFieldSet* unknown_fields); + + // Read a packed enum field. If the is_valid function is not nullptr, values + // for which is_valid(value) returns false are appended to + // unknown_fields_stream. + static bool ReadPackedEnumPreserveUnknowns(io::CodedInputStream* input, + arc_ui32 field_number, + bool (*is_valid)(int), + UnknownFieldSet* unknown_fields, + RepeatedField<int>* values); + + // Write the contents of an UnknownFieldSet to the output. + static void SerializeUnknownFields(const UnknownFieldSet& unknown_fields, + io::CodedOutputStream* output) { + output->SetCur(InternalSerializeUnknownFieldsToArray( + unknown_fields, output->Cur(), output->EpsCopy())); + } + // Same as above, except writing directly to the provided buffer. + // Requires that the buffer have sufficient capacity for + // ComputeUnknownFieldsSize(unknown_fields). + // + // Returns a pointer past the last written byte. + static uint8_t* SerializeUnknownFieldsToArray( + const UnknownFieldSet& unknown_fields, uint8_t* target) { + io::EpsCopyOutputStream stream( + target, static_cast<int>(ComputeUnknownFieldsSize(unknown_fields)), + io::CodedOutputStream::IsDefaultSerializationDeterministic()); + return InternalSerializeUnknownFieldsToArray(unknown_fields, target, + &stream); + } + static uint8_t* InternalSerializeUnknownFieldsToArray( + const UnknownFieldSet& unknown_fields, uint8_t* target, + io::EpsCopyOutputStream* stream); + + // Same thing except for messages that have the message_set_wire_format + // option. + static void SerializeUnknownMessageSetItems( + const UnknownFieldSet& unknown_fields, io::CodedOutputStream* output) { + output->SetCur(InternalSerializeUnknownMessageSetItemsToArray( + unknown_fields, output->Cur(), output->EpsCopy())); + } + // Same as above, except writing directly to the provided buffer. + // Requires that the buffer have sufficient capacity for + // ComputeUnknownMessageSetItemsSize(unknown_fields). + // + // Returns a pointer past the last written byte. + static uint8_t* SerializeUnknownMessageSetItemsToArray( + const UnknownFieldSet& unknown_fields, uint8_t* target); + static uint8_t* InternalSerializeUnknownMessageSetItemsToArray( + const UnknownFieldSet& unknown_fields, uint8_t* target, + io::EpsCopyOutputStream* stream); + + // Compute the size of the UnknownFieldSet on the wire. + static size_t ComputeUnknownFieldsSize(const UnknownFieldSet& unknown_fields); + + // Same thing except for messages that have the message_set_wire_format + // option. + static size_t ComputeUnknownMessageSetItemsSize( + const UnknownFieldSet& unknown_fields); + + // Helper functions for encoding and decoding tags. (Inlined below and in + // _inl.h) + // + // This is different from MakeTag(field->number(), field->type()) in the + // case of packed repeated fields. + static arc_ui32 MakeTag(const FieldDescriptor* field); + + // Parse a single field. The input should start out positioned immediately + // after the tag. + static bool ParseAndMergeField( + arc_ui32 tag, + const FieldDescriptor* field, // May be nullptr for unknown + Message* message, io::CodedInputStream* input); + + // Serialize a single field. + static void SerializeFieldWithCachedSizes( + const FieldDescriptor* field, // Cannot be nullptr + const Message& message, io::CodedOutputStream* output) { + output->SetCur(InternalSerializeField(field, message, output->Cur(), + output->EpsCopy())); + } + static uint8_t* InternalSerializeField( + const FieldDescriptor* field, // Cannot be nullptr + const Message& message, uint8_t* target, io::EpsCopyOutputStream* stream); + + // Compute size of a single field. If the field is a message type, this + // will call ByteSize() for the embedded message, insuring that it caches + // its size. + static size_t FieldByteSize(const FieldDescriptor* field, // Can't be nullptr + const Message& message); + + // Parse/serialize a MessageSet::Item group. Used with messages that use + // option message_set_wire_format = true. + static bool ParseAndMergeMessageSetItem(io::CodedInputStream* input, + Message* message); + static void SerializeMessageSetItemWithCachedSizes( + const FieldDescriptor* field, const Message& message, + io::CodedOutputStream* output) { + output->SetCur(InternalSerializeMessageSetItem( + field, message, output->Cur(), output->EpsCopy())); + } + static uint8_t* InternalSerializeMessageSetItem( + const FieldDescriptor* field, const Message& message, uint8_t* target, + io::EpsCopyOutputStream* stream); + static size_t MessageSetItemByteSize(const FieldDescriptor* field, + const Message& message); + + // Computes the byte size of a field, excluding tags. For packed fields, it + // only includes the size of the raw data, and not the size of the total + // length, but for other length-delimited types, the size of the length is + // included. + static size_t FieldDataOnlyByteSize( + const FieldDescriptor* field, // Cannot be nullptr + const Message& message); + + enum Operation { + PARSE = 0, + SERIALIZE = 1, + }; + + // Verifies that a string field is valid UTF8, logging an error if not. + // This function will not be called by newly generated protobuf code + // but remains present to support existing code. + static void VerifyUTF8String(const char* data, int size, Operation op); + // The NamedField variant takes a field name in order to produce an + // informative error message if verification fails. + static void VerifyUTF8StringNamedField(const char* data, int size, + Operation op, const char* field_name); + + private: + struct MessageSetParser; + // Skip a MessageSet field. + static bool SkipMessageSetField(io::CodedInputStream* input, + arc_ui32 field_number, + UnknownFieldSet* unknown_fields); + + // Parse a MessageSet field. + static bool ParseAndMergeMessageSetField(arc_ui32 field_number, + const FieldDescriptor* field, + Message* message, + io::CodedInputStream* input); + // Parses the value from the wire that belongs to tag. + static const char* _InternalParseAndMergeField(Message* msg, const char* ptr, + internal::ParseContext* ctx, + arc_ui64 tag, + const Reflection* reflection, + const FieldDescriptor* field); + + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(WireFormat); +}; + +// Subclass of FieldSkipper which saves skipped fields to an UnknownFieldSet. +class PROTOBUF_EXPORT UnknownFieldSetFieldSkipper : public FieldSkipper { + public: + UnknownFieldSetFieldSkipper(UnknownFieldSet* unknown_fields) + : unknown_fields_(unknown_fields) {} + ~UnknownFieldSetFieldSkipper() override {} + + // implements FieldSkipper ----------------------------------------- + bool SkipField(io::CodedInputStream* input, arc_ui32 tag) override; + bool SkipMessage(io::CodedInputStream* input) override; + void SkipUnknownEnum(int field_number, int value) override; + + protected: + UnknownFieldSet* unknown_fields_; +}; + +// inline methods ==================================================== + +inline WireFormatLite::WireType WireFormat::WireTypeForField( + const FieldDescriptor* field) { + if (field->is_packed()) { + return WireFormatLite::WIRETYPE_LENGTH_DELIMITED; + } else { + return WireTypeForFieldType(field->type()); + } +} + +inline WireFormatLite::WireType WireFormat::WireTypeForFieldType( + FieldDescriptor::Type type) { + // Some compilers don't like enum -> enum casts, so we implicit_cast to + // int first. + return WireFormatLite::WireTypeForFieldType( + static_cast<WireFormatLite::FieldType>(implicit_cast<int>(type))); +} + +inline arc_ui32 WireFormat::MakeTag(const FieldDescriptor* field) { + return WireFormatLite::MakeTag(field->number(), WireTypeForField(field)); +} + +inline size_t WireFormat::TagSize(int field_number, + FieldDescriptor::Type type) { + // Some compilers don't like enum -> enum casts, so we implicit_cast to + // int first. + return WireFormatLite::TagSize( + field_number, + static_cast<WireFormatLite::FieldType>(implicit_cast<int>(type))); +} + +inline void WireFormat::VerifyUTF8String(const char* data, int size, + WireFormat::Operation op) { +#ifdef GOOGLE_PROTOBUF_UTF8_VALIDATION_ENABLED + WireFormatLite::VerifyUtf8String( + data, size, static_cast<WireFormatLite::Operation>(op), nullptr); +#else + // Avoid the compiler warning about unused variables. + (void)data; + (void)size; + (void)op; +#endif +} + +inline void WireFormat::VerifyUTF8StringNamedField(const char* data, int size, + WireFormat::Operation op, + const char* field_name) { +#ifdef GOOGLE_PROTOBUF_UTF8_VALIDATION_ENABLED + WireFormatLite::VerifyUtf8String( + data, size, static_cast<WireFormatLite::Operation>(op), field_name); +#else + // Avoid the compiler warning about unused variables. + (void)data; + (void)size; + (void)op; + (void)field_name; +#endif +} + + +inline uint8_t* InternalSerializeUnknownMessageSetItemsToArray( + const UnknownFieldSet& unknown_fields, uint8_t* target, + io::EpsCopyOutputStream* stream) { + return WireFormat::InternalSerializeUnknownMessageSetItemsToArray( + unknown_fields, target, stream); +} + +inline size_t ComputeUnknownMessageSetItemsSize( + const UnknownFieldSet& unknown_fields) { + return WireFormat::ComputeUnknownMessageSetItemsSize(unknown_fields); +} + +// Compute the size of the UnknownFieldSet on the wire. +PROTOBUF_EXPORT +size_t ComputeUnknownFieldsSize(const InternalMetadata& metadata, size_t size, + CachedSize* cached_size); + +size_t MapKeyDataOnlyByteSize(const FieldDescriptor* field, + const MapKey& value); + +uint8_t* SerializeMapKeyWithCachedSizes(const FieldDescriptor* field, + const MapKey& value, uint8_t* target, + io::EpsCopyOutputStream* stream); +} // namespace internal +} // namespace protobuf +} // namespace google + +#include <google/protobuf/port_undef.inc> + +#endif // GOOGLE_PROTOBUF_WIRE_FORMAT_H__ diff --git a/contrib/libs/protobuf_old/src/google/protobuf/wire_format_lite.cc b/contrib/libs/protobuf_old/src/google/protobuf/wire_format_lite.cc new file mode 100644 index 0000000000..9089ff1a7e --- /dev/null +++ b/contrib/libs/protobuf_old/src/google/protobuf/wire_format_lite.cc @@ -0,0 +1,784 @@ +// 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: kenton@google.com (Kenton Varda) +// Based on original Protocol Buffers design by +// Sanjay Ghemawat, Jeff Dean, and others. + +#include <google/protobuf/wire_format_lite.h> + +#include <limits> +#include <stack> +#include <string> +#include <vector> + +#include <google/protobuf/stubs/logging.h> +#include <google/protobuf/stubs/common.h> +#include <google/protobuf/stubs/stringprintf.h> +#include <google/protobuf/io/coded_stream.h> +#include <google/protobuf/io/zero_copy_stream.h> +#include <google/protobuf/io/zero_copy_stream_impl_lite.h> + + +#include <google/protobuf/port_def.inc> + +namespace google { +namespace protobuf { +namespace internal { + +#if !defined(_MSC_VER) || (_MSC_VER >= 1900 && _MSC_VER < 1912) +// Old version of MSVC doesn't like definitions of inline constants, GCC +// requires them. +const int WireFormatLite::kMessageSetItemStartTag; +const int WireFormatLite::kMessageSetItemEndTag; +const int WireFormatLite::kMessageSetTypeIdTag; +const int WireFormatLite::kMessageSetMessageTag; + +#endif + +// IBM xlC requires prefixing constants with WireFormatLite:: +const size_t WireFormatLite::kMessageSetItemTagsSize = + io::CodedOutputStream::StaticVarintSize32< + WireFormatLite::kMessageSetItemStartTag>::value + + io::CodedOutputStream::StaticVarintSize32< + WireFormatLite::kMessageSetItemEndTag>::value + + io::CodedOutputStream::StaticVarintSize32< + WireFormatLite::kMessageSetTypeIdTag>::value + + io::CodedOutputStream::StaticVarintSize32< + WireFormatLite::kMessageSetMessageTag>::value; + +const WireFormatLite::CppType + WireFormatLite::kFieldTypeToCppTypeMap[MAX_FIELD_TYPE + 1] = { + static_cast<CppType>(0), // 0 is reserved for errors + + CPPTYPE_DOUBLE, // TYPE_DOUBLE + CPPTYPE_FLOAT, // TYPE_FLOAT + CPPTYPE_INT64, // TYPE_INT64 + CPPTYPE_UINT64, // TYPE_UINT64 + CPPTYPE_INT32, // TYPE_INT32 + CPPTYPE_UINT64, // TYPE_FIXED64 + CPPTYPE_UINT32, // TYPE_FIXED32 + CPPTYPE_BOOL, // TYPE_BOOL + CPPTYPE_STRING, // TYPE_STRING + CPPTYPE_MESSAGE, // TYPE_GROUP + CPPTYPE_MESSAGE, // TYPE_MESSAGE + CPPTYPE_STRING, // TYPE_BYTES + CPPTYPE_UINT32, // TYPE_UINT32 + CPPTYPE_ENUM, // TYPE_ENUM + CPPTYPE_INT32, // TYPE_SFIXED32 + CPPTYPE_INT64, // TYPE_SFIXED64 + CPPTYPE_INT32, // TYPE_SINT32 + CPPTYPE_INT64, // TYPE_SINT64 +}; + +const WireFormatLite::WireType + WireFormatLite::kWireTypeForFieldType[MAX_FIELD_TYPE + 1] = { + static_cast<WireFormatLite::WireType>(-1), // invalid + WireFormatLite::WIRETYPE_FIXED64, // TYPE_DOUBLE + WireFormatLite::WIRETYPE_FIXED32, // TYPE_FLOAT + WireFormatLite::WIRETYPE_VARINT, // TYPE_INT64 + WireFormatLite::WIRETYPE_VARINT, // TYPE_UINT64 + WireFormatLite::WIRETYPE_VARINT, // TYPE_INT32 + WireFormatLite::WIRETYPE_FIXED64, // TYPE_FIXED64 + WireFormatLite::WIRETYPE_FIXED32, // TYPE_FIXED32 + WireFormatLite::WIRETYPE_VARINT, // TYPE_BOOL + WireFormatLite::WIRETYPE_LENGTH_DELIMITED, // TYPE_STRING + WireFormatLite::WIRETYPE_START_GROUP, // TYPE_GROUP + WireFormatLite::WIRETYPE_LENGTH_DELIMITED, // TYPE_MESSAGE + WireFormatLite::WIRETYPE_LENGTH_DELIMITED, // TYPE_BYTES + WireFormatLite::WIRETYPE_VARINT, // TYPE_UINT32 + WireFormatLite::WIRETYPE_VARINT, // TYPE_ENUM + WireFormatLite::WIRETYPE_FIXED32, // TYPE_SFIXED32 + WireFormatLite::WIRETYPE_FIXED64, // TYPE_SFIXED64 + WireFormatLite::WIRETYPE_VARINT, // TYPE_SINT32 + WireFormatLite::WIRETYPE_VARINT, // TYPE_SINT64 +}; + +bool WireFormatLite::SkipField(io::CodedInputStream* input, arc_ui32 tag) { + // Field number 0 is illegal. + if (WireFormatLite::GetTagFieldNumber(tag) == 0) return false; + switch (WireFormatLite::GetTagWireType(tag)) { + case WireFormatLite::WIRETYPE_VARINT: { + arc_ui64 value; + if (!input->ReadVarint64(&value)) return false; + return true; + } + case WireFormatLite::WIRETYPE_FIXED64: { + arc_ui64 value; + if (!input->ReadLittleEndian64(&value)) return false; + return true; + } + case WireFormatLite::WIRETYPE_LENGTH_DELIMITED: { + arc_ui32 length; + if (!input->ReadVarint32(&length)) return false; + if (!input->Skip(length)) return false; + return true; + } + case WireFormatLite::WIRETYPE_START_GROUP: { + if (!input->IncrementRecursionDepth()) return false; + if (!SkipMessage(input)) return false; + input->DecrementRecursionDepth(); + // Check that the ending tag matched the starting tag. + if (!input->LastTagWas( + WireFormatLite::MakeTag(WireFormatLite::GetTagFieldNumber(tag), + WireFormatLite::WIRETYPE_END_GROUP))) { + return false; + } + return true; + } + case WireFormatLite::WIRETYPE_END_GROUP: { + return false; + } + case WireFormatLite::WIRETYPE_FIXED32: { + arc_ui32 value; + if (!input->ReadLittleEndian32(&value)) return false; + return true; + } + default: { + return false; + } + } +} + +bool WireFormatLite::SkipField(io::CodedInputStream* input, arc_ui32 tag, + io::CodedOutputStream* output) { + // Field number 0 is illegal. + if (WireFormatLite::GetTagFieldNumber(tag) == 0) return false; + switch (WireFormatLite::GetTagWireType(tag)) { + case WireFormatLite::WIRETYPE_VARINT: { + arc_ui64 value; + if (!input->ReadVarint64(&value)) return false; + output->WriteVarint32(tag); + output->WriteVarint64(value); + return true; + } + case WireFormatLite::WIRETYPE_FIXED64: { + arc_ui64 value; + if (!input->ReadLittleEndian64(&value)) return false; + output->WriteVarint32(tag); + output->WriteLittleEndian64(value); + return true; + } + case WireFormatLite::WIRETYPE_LENGTH_DELIMITED: { + arc_ui32 length; + if (!input->ReadVarint32(&length)) return false; + output->WriteVarint32(tag); + output->WriteVarint32(length); + // TODO(mkilavuz): Provide API to prevent extra string copying. + TProtoStringType temp; + if (!input->ReadString(&temp, length)) return false; + output->WriteString(temp); + return true; + } + case WireFormatLite::WIRETYPE_START_GROUP: { + output->WriteVarint32(tag); + if (!input->IncrementRecursionDepth()) return false; + if (!SkipMessage(input, output)) return false; + input->DecrementRecursionDepth(); + // Check that the ending tag matched the starting tag. + if (!input->LastTagWas( + WireFormatLite::MakeTag(WireFormatLite::GetTagFieldNumber(tag), + WireFormatLite::WIRETYPE_END_GROUP))) { + return false; + } + return true; + } + case WireFormatLite::WIRETYPE_END_GROUP: { + return false; + } + case WireFormatLite::WIRETYPE_FIXED32: { + arc_ui32 value; + if (!input->ReadLittleEndian32(&value)) return false; + output->WriteVarint32(tag); + output->WriteLittleEndian32(value); + return true; + } + default: { + return false; + } + } +} + +bool WireFormatLite::SkipMessage(io::CodedInputStream* input) { + while (true) { + arc_ui32 tag = input->ReadTag(); + if (tag == 0) { + // End of input. This is a valid place to end, so return true. + return true; + } + + WireFormatLite::WireType wire_type = WireFormatLite::GetTagWireType(tag); + + if (wire_type == WireFormatLite::WIRETYPE_END_GROUP) { + // Must be the end of the message. + return true; + } + + if (!SkipField(input, tag)) return false; + } +} + +bool WireFormatLite::SkipMessage(io::CodedInputStream* input, + io::CodedOutputStream* output) { + while (true) { + arc_ui32 tag = input->ReadTag(); + if (tag == 0) { + // End of input. This is a valid place to end, so return true. + return true; + } + + WireFormatLite::WireType wire_type = WireFormatLite::GetTagWireType(tag); + + if (wire_type == WireFormatLite::WIRETYPE_END_GROUP) { + output->WriteVarint32(tag); + // Must be the end of the message. + return true; + } + + if (!SkipField(input, tag, output)) return false; + } +} + +bool FieldSkipper::SkipField(io::CodedInputStream* input, arc_ui32 tag) { + return WireFormatLite::SkipField(input, tag); +} + +bool FieldSkipper::SkipMessage(io::CodedInputStream* input) { + return WireFormatLite::SkipMessage(input); +} + +void FieldSkipper::SkipUnknownEnum(int /* field_number */, int /* value */) { + // Nothing. +} + +bool CodedOutputStreamFieldSkipper::SkipField(io::CodedInputStream* input, + arc_ui32 tag) { + return WireFormatLite::SkipField(input, tag, unknown_fields_); +} + +bool CodedOutputStreamFieldSkipper::SkipMessage(io::CodedInputStream* input) { + return WireFormatLite::SkipMessage(input, unknown_fields_); +} + +void CodedOutputStreamFieldSkipper::SkipUnknownEnum(int field_number, + int value) { + unknown_fields_->WriteVarint32(field_number); + unknown_fields_->WriteVarint64(value); +} + +bool WireFormatLite::ReadPackedEnumPreserveUnknowns( + io::CodedInputStream* input, int field_number, bool (*is_valid)(int), + io::CodedOutputStream* unknown_fields_stream, RepeatedField<int>* values) { + arc_ui32 length; + if (!input->ReadVarint32(&length)) return false; + io::CodedInputStream::Limit limit = input->PushLimit(length); + while (input->BytesUntilLimit() > 0) { + int value; + if (!ReadPrimitive<int, WireFormatLite::TYPE_ENUM>(input, &value)) { + return false; + } + if (is_valid == nullptr || is_valid(value)) { + values->Add(value); + } else { + arc_ui32 tag = WireFormatLite::MakeTag(field_number, + WireFormatLite::WIRETYPE_VARINT); + unknown_fields_stream->WriteVarint32(tag); + unknown_fields_stream->WriteVarint32(value); + } + } + input->PopLimit(limit); + return true; +} + +#if !defined(PROTOBUF_LITTLE_ENDIAN) + +namespace { +void EncodeFixedSizeValue(float v, uint8_t* dest) { + WireFormatLite::WriteFloatNoTagToArray(v, dest); +} + +void EncodeFixedSizeValue(double v, uint8_t* dest) { + WireFormatLite::WriteDoubleNoTagToArray(v, dest); +} + +void EncodeFixedSizeValue(arc_ui32 v, uint8_t* dest) { + WireFormatLite::WriteFixed32NoTagToArray(v, dest); +} + +void EncodeFixedSizeValue(arc_ui64 v, uint8_t* dest) { + WireFormatLite::WriteFixed64NoTagToArray(v, dest); +} + +void EncodeFixedSizeValue(arc_i32 v, uint8_t* dest) { + WireFormatLite::WriteSFixed32NoTagToArray(v, dest); +} + +void EncodeFixedSizeValue(arc_i64 v, uint8_t* dest) { + WireFormatLite::WriteSFixed64NoTagToArray(v, dest); +} + +void EncodeFixedSizeValue(bool v, uint8_t* dest) { + WireFormatLite::WriteBoolNoTagToArray(v, dest); +} +} // anonymous namespace + +#endif // !defined(PROTOBUF_LITTLE_ENDIAN) + +template <typename CType> +static void WriteArray(const CType* a, int n, io::CodedOutputStream* output) { +#if defined(PROTOBUF_LITTLE_ENDIAN) + output->WriteRaw(reinterpret_cast<const char*>(a), n * sizeof(a[0])); +#else + const int kAtATime = 128; + uint8_t buf[sizeof(CType) * kAtATime]; + for (int i = 0; i < n; i += kAtATime) { + int to_do = std::min(kAtATime, n - i); + uint8_t* ptr = buf; + for (int j = 0; j < to_do; j++) { + EncodeFixedSizeValue(a[i + j], ptr); + ptr += sizeof(a[0]); + } + output->WriteRaw(buf, to_do * sizeof(a[0])); + } +#endif +} + +void WireFormatLite::WriteFloatArray(const float* a, int n, + io::CodedOutputStream* output) { + WriteArray<float>(a, n, output); +} + +void WireFormatLite::WriteDoubleArray(const double* a, int n, + io::CodedOutputStream* output) { + WriteArray<double>(a, n, output); +} + +void WireFormatLite::WriteFixed32Array(const arc_ui32* a, int n, + io::CodedOutputStream* output) { + WriteArray<arc_ui32>(a, n, output); +} + +void WireFormatLite::WriteFixed64Array(const arc_ui64* a, int n, + io::CodedOutputStream* output) { + WriteArray<arc_ui64>(a, n, output); +} + +void WireFormatLite::WriteSFixed32Array(const arc_i32* a, int n, + io::CodedOutputStream* output) { + WriteArray<arc_i32>(a, n, output); +} + +void WireFormatLite::WriteSFixed64Array(const arc_i64* a, int n, + io::CodedOutputStream* output) { + WriteArray<arc_i64>(a, n, output); +} + +void WireFormatLite::WriteBoolArray(const bool* a, int n, + io::CodedOutputStream* output) { + WriteArray<bool>(a, n, output); +} + +void WireFormatLite::WriteInt32(int field_number, arc_i32 value, + io::CodedOutputStream* output) { + WriteTag(field_number, WIRETYPE_VARINT, output); + WriteInt32NoTag(value, output); +} +void WireFormatLite::WriteInt64(int field_number, arc_i64 value, + io::CodedOutputStream* output) { + WriteTag(field_number, WIRETYPE_VARINT, output); + WriteInt64NoTag(value, output); +} +void WireFormatLite::WriteUInt32(int field_number, arc_ui32 value, + io::CodedOutputStream* output) { + WriteTag(field_number, WIRETYPE_VARINT, output); + WriteUInt32NoTag(value, output); +} +void WireFormatLite::WriteUInt64(int field_number, arc_ui64 value, + io::CodedOutputStream* output) { + WriteTag(field_number, WIRETYPE_VARINT, output); + WriteUInt64NoTag(value, output); +} +void WireFormatLite::WriteSInt32(int field_number, arc_i32 value, + io::CodedOutputStream* output) { + WriteTag(field_number, WIRETYPE_VARINT, output); + WriteSInt32NoTag(value, output); +} +void WireFormatLite::WriteSInt64(int field_number, arc_i64 value, + io::CodedOutputStream* output) { + WriteTag(field_number, WIRETYPE_VARINT, output); + WriteSInt64NoTag(value, output); +} +void WireFormatLite::WriteFixed32(int field_number, arc_ui32 value, + io::CodedOutputStream* output) { + WriteTag(field_number, WIRETYPE_FIXED32, output); + WriteFixed32NoTag(value, output); +} +void WireFormatLite::WriteFixed64(int field_number, arc_ui64 value, + io::CodedOutputStream* output) { + WriteTag(field_number, WIRETYPE_FIXED64, output); + WriteFixed64NoTag(value, output); +} +void WireFormatLite::WriteSFixed32(int field_number, arc_i32 value, + io::CodedOutputStream* output) { + WriteTag(field_number, WIRETYPE_FIXED32, output); + WriteSFixed32NoTag(value, output); +} +void WireFormatLite::WriteSFixed64(int field_number, arc_i64 value, + io::CodedOutputStream* output) { + WriteTag(field_number, WIRETYPE_FIXED64, output); + WriteSFixed64NoTag(value, output); +} +void WireFormatLite::WriteFloat(int field_number, float value, + io::CodedOutputStream* output) { + WriteTag(field_number, WIRETYPE_FIXED32, output); + WriteFloatNoTag(value, output); +} +void WireFormatLite::WriteDouble(int field_number, double value, + io::CodedOutputStream* output) { + WriteTag(field_number, WIRETYPE_FIXED64, output); + WriteDoubleNoTag(value, output); +} +void WireFormatLite::WriteBool(int field_number, bool value, + io::CodedOutputStream* output) { + WriteTag(field_number, WIRETYPE_VARINT, output); + WriteBoolNoTag(value, output); +} +void WireFormatLite::WriteEnum(int field_number, int value, + io::CodedOutputStream* output) { + WriteTag(field_number, WIRETYPE_VARINT, output); + WriteEnumNoTag(value, output); +} + +constexpr size_t kInt32MaxSize = std::numeric_limits<arc_i32>::max(); + +void WireFormatLite::WriteString(int field_number, const TProtoStringType& value, + io::CodedOutputStream* output) { + // String is for UTF-8 text only + WriteTag(field_number, WIRETYPE_LENGTH_DELIMITED, output); + GOOGLE_CHECK_LE(value.size(), kInt32MaxSize); + output->WriteVarint32(value.size()); + output->WriteString(value); +} +void WireFormatLite::WriteStringMaybeAliased(int field_number, + const TProtoStringType& value, + io::CodedOutputStream* output) { + // String is for UTF-8 text only + WriteTag(field_number, WIRETYPE_LENGTH_DELIMITED, output); + GOOGLE_CHECK_LE(value.size(), kInt32MaxSize); + output->WriteVarint32(value.size()); + output->WriteRawMaybeAliased(value.data(), value.size()); +} +void WireFormatLite::WriteBytes(int field_number, const TProtoStringType& value, + io::CodedOutputStream* output) { + WriteTag(field_number, WIRETYPE_LENGTH_DELIMITED, output); + GOOGLE_CHECK_LE(value.size(), kInt32MaxSize); + output->WriteVarint32(value.size()); + output->WriteString(value); +} +void WireFormatLite::WriteBytesMaybeAliased(int field_number, + const TProtoStringType& value, + io::CodedOutputStream* output) { + WriteTag(field_number, WIRETYPE_LENGTH_DELIMITED, output); + GOOGLE_CHECK_LE(value.size(), kInt32MaxSize); + output->WriteVarint32(value.size()); + output->WriteRawMaybeAliased(value.data(), value.size()); +} + + +void WireFormatLite::WriteGroup(int field_number, const MessageLite& value, + io::CodedOutputStream* output) { + WriteTag(field_number, WIRETYPE_START_GROUP, output); + value.SerializeWithCachedSizes(output); + WriteTag(field_number, WIRETYPE_END_GROUP, output); +} + +void WireFormatLite::WriteMessage(int field_number, const MessageLite& value, + io::CodedOutputStream* output) { + WriteTag(field_number, WIRETYPE_LENGTH_DELIMITED, output); + const int size = value.GetCachedSize(); + output->WriteVarint32(size); + value.SerializeWithCachedSizes(output); +} + +void WireFormatLite::WriteSubMessageMaybeToArray( + int /*size*/, const MessageLite& value, io::CodedOutputStream* output) { + output->SetCur(value._InternalSerialize(output->Cur(), output->EpsCopy())); +} + +void WireFormatLite::WriteGroupMaybeToArray(int field_number, + const MessageLite& value, + io::CodedOutputStream* output) { + WriteTag(field_number, WIRETYPE_START_GROUP, output); + const int size = value.GetCachedSize(); + WriteSubMessageMaybeToArray(size, value, output); + WriteTag(field_number, WIRETYPE_END_GROUP, output); +} + +void WireFormatLite::WriteMessageMaybeToArray(int field_number, + const MessageLite& value, + io::CodedOutputStream* output) { + WriteTag(field_number, WIRETYPE_LENGTH_DELIMITED, output); + const int size = value.GetCachedSize(); + output->WriteVarint32(size); + WriteSubMessageMaybeToArray(size, value, output); +} + +PROTOBUF_NDEBUG_INLINE static bool ReadBytesToString( + io::CodedInputStream* input, TProtoStringType* value); +inline static bool ReadBytesToString(io::CodedInputStream* input, + TProtoStringType* value) { + arc_ui32 length; + return input->ReadVarint32(&length) && input->ReadString(value, length); +} + +bool WireFormatLite::ReadBytes(io::CodedInputStream* input, + TProtoStringType* value) { + return ReadBytesToString(input, value); +} + +bool WireFormatLite::ReadBytes(io::CodedInputStream* input, TProtoStringType** p) { + if (*p == &GetEmptyStringAlreadyInited()) { + *p = new TProtoStringType(); + } + return ReadBytesToString(input, *p); +} + +void PrintUTF8ErrorLog(const char* field_name, const char* operation_str, + bool emit_stacktrace) { + TProtoStringType stacktrace; + (void)emit_stacktrace; // Parameter is used by Google-internal code. + TProtoStringType quoted_field_name = ""; + if (field_name != nullptr) { + quoted_field_name = StringPrintf(" '%s'", field_name); + } + GOOGLE_LOG(ERROR) << "String field" << quoted_field_name << " contains invalid " + << "UTF-8 data when " << operation_str << " a protocol " + << "buffer. Use the 'bytes' type if you intend to send raw " + << "bytes. " << stacktrace; +} + +bool WireFormatLite::VerifyUtf8String(const char* data, int size, Operation op, + const char* field_name) { + if (!IsStructurallyValidUTF8(data, size)) { + const char* operation_str = nullptr; + switch (op) { + case PARSE: + operation_str = "parsing"; + break; + case SERIALIZE: + operation_str = "serializing"; + break; + // no default case: have the compiler warn if a case is not covered. + } + PrintUTF8ErrorLog(field_name, operation_str, false); + return false; + } + return true; +} + +// this code is deliberately written such that clang makes it into really +// efficient SSE code. +template <bool ZigZag, bool SignExtended, typename T> +static size_t VarintSize(const T* data, const int n) { + static_assert(sizeof(T) == 4, "This routine only works for 32 bit integers"); + // is_unsigned<T> => !ZigZag + static_assert( + (std::is_unsigned<T>::value ^ ZigZag) || std::is_signed<T>::value, + "Cannot ZigZag encode unsigned types"); + // is_unsigned<T> => !SignExtended + static_assert( + (std::is_unsigned<T>::value ^ SignExtended) || std::is_signed<T>::value, + "Cannot SignExtended unsigned types"); + static_assert(!(SignExtended && ZigZag), + "Cannot SignExtended and ZigZag on the same type"); + arc_ui32 sum = n; + arc_ui32 msb_sum = 0; + for (int i = 0; i < n; i++) { + arc_ui32 x = data[i]; + if (ZigZag) { + x = WireFormatLite::ZigZagEncode32(x); + } else if (SignExtended) { + msb_sum += x >> 31; + } + // clang is so smart that it produces optimal SSE sequence unrolling + // the loop 8 ints at a time. With a sequence of 4 + // cmpres = cmpgt x, sizeclass ( -1 or 0) + // sum = sum - cmpres + if (x > 0x7F) sum++; + if (x > 0x3FFF) sum++; + if (x > 0x1FFFFF) sum++; + if (x > 0xFFFFFFF) sum++; + } + if (SignExtended) sum += msb_sum * 5; + return sum; +} + +template <bool ZigZag, typename T> +static size_t VarintSize64(const T* data, const int n) { + static_assert(sizeof(T) == 8, "This routine only works for 64 bit integers"); + // is_unsigned<T> => !ZigZag + static_assert(!ZigZag || !std::is_unsigned<T>::value, + "Cannot ZigZag encode unsigned types"); + arc_ui64 sum = n; + for (int i = 0; i < n; i++) { + arc_ui64 x = data[i]; + if (ZigZag) { + x = WireFormatLite::ZigZagEncode64(x); + } + // First step is a binary search, we can't branch in sse so we use the + // result of the compare to adjust sum and appropriately. This code is + // written to make clang recognize the vectorization. + arc_ui64 tmp = x >= (static_cast<arc_ui64>(1) << 35) ? -1 : 0; + sum += 5 & tmp; + x >>= 35 & tmp; + if (x > 0x7F) sum++; + if (x > 0x3FFF) sum++; + if (x > 0x1FFFFF) sum++; + if (x > 0xFFFFFFF) sum++; + } + return sum; +} + +// GCC does not recognize the vectorization opportunity +// and other platforms are untested, in those cases using the optimized +// varint size routine for each element is faster. +// Hence we enable it only for clang +#if defined(__SSE__) && defined(__clang__) +size_t WireFormatLite::Int32Size(const RepeatedField<arc_i32>& value) { + return VarintSize<false, true>(value.data(), value.size()); +} + +size_t WireFormatLite::UInt32Size(const RepeatedField<arc_ui32>& value) { + return VarintSize<false, false>(value.data(), value.size()); +} + +size_t WireFormatLite::SInt32Size(const RepeatedField<arc_i32>& value) { + return VarintSize<true, false>(value.data(), value.size()); +} + +size_t WireFormatLite::EnumSize(const RepeatedField<int>& value) { + // On ILP64, sizeof(int) == 8, which would require a different template. + return VarintSize<false, true>(value.data(), value.size()); +} + +#else // !(defined(__SSE4_1__) && defined(__clang__)) + +size_t WireFormatLite::Int32Size(const RepeatedField<arc_i32>& value) { + size_t out = 0; + const int n = value.size(); + for (int i = 0; i < n; i++) { + out += Int32Size(value.Get(i)); + } + return out; +} + +size_t WireFormatLite::UInt32Size(const RepeatedField<arc_ui32>& value) { + size_t out = 0; + const int n = value.size(); + for (int i = 0; i < n; i++) { + out += UInt32Size(value.Get(i)); + } + return out; +} + +size_t WireFormatLite::SInt32Size(const RepeatedField<arc_i32>& value) { + size_t out = 0; + const int n = value.size(); + for (int i = 0; i < n; i++) { + out += SInt32Size(value.Get(i)); + } + return out; +} + +size_t WireFormatLite::EnumSize(const RepeatedField<int>& value) { + size_t out = 0; + const int n = value.size(); + for (int i = 0; i < n; i++) { + out += EnumSize(value.Get(i)); + } + return out; +} + +#endif + +// Micro benchmarks show that the SSE improved loop only starts beating +// the normal loop on Haswell platforms and then only for >32 ints. We +// disable this for now. Some specialized users might find it worthwhile to +// enable this. +#define USE_SSE_FOR_64_BIT_INTEGER_ARRAYS 0 +#if USE_SSE_FOR_64_BIT_INTEGER_ARRAYS +size_t WireFormatLite::Int64Size(const RepeatedField<arc_i64>& value) { + return VarintSize64<false>(value.data(), value.size()); +} + +size_t WireFormatLite::UInt64Size(const RepeatedField<arc_ui64>& value) { + return VarintSize64<false>(value.data(), value.size()); +} + +size_t WireFormatLite::SInt64Size(const RepeatedField<arc_i64>& value) { + return VarintSize64<true>(value.data(), value.size()); +} + +#else + +size_t WireFormatLite::Int64Size(const RepeatedField<arc_i64>& value) { + size_t out = 0; + const int n = value.size(); + for (int i = 0; i < n; i++) { + out += Int64Size(value.Get(i)); + } + return out; +} + +size_t WireFormatLite::UInt64Size(const RepeatedField<arc_ui64>& value) { + size_t out = 0; + const int n = value.size(); + for (int i = 0; i < n; i++) { + out += UInt64Size(value.Get(i)); + } + return out; +} + +size_t WireFormatLite::SInt64Size(const RepeatedField<arc_i64>& value) { + size_t out = 0; + const int n = value.size(); + for (int i = 0; i < n; i++) { + out += SInt64Size(value.Get(i)); + } + return out; +} + +#endif + +} // namespace internal +} // namespace protobuf +} // namespace google + +#include <google/protobuf/port_undef.inc> diff --git a/contrib/libs/protobuf_old/src/google/protobuf/wire_format_lite.h b/contrib/libs/protobuf_old/src/google/protobuf/wire_format_lite.h new file mode 100644 index 0000000000..42d57bbd76 --- /dev/null +++ b/contrib/libs/protobuf_old/src/google/protobuf/wire_format_lite.h @@ -0,0 +1,1911 @@ +// 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: kenton@google.com (Kenton Varda) +// atenasio@google.com (Chris Atenasio) (ZigZag transform) +// wink@google.com (Wink Saville) (refactored from wire_format.h) +// Based on original Protocol Buffers design by +// Sanjay Ghemawat, Jeff Dean, and others. +// +// This header is logically internal, but is made public because it is used +// from protocol-compiler-generated code, which may reside in other components. + +#ifndef GOOGLE_PROTOBUF_WIRE_FORMAT_LITE_H__ +#define GOOGLE_PROTOBUF_WIRE_FORMAT_LITE_H__ + +#include <string> + +#include <google/protobuf/stubs/common.h> +#include <google/protobuf/stubs/logging.h> +#include <google/protobuf/io/coded_stream.h> +#include <google/protobuf/arenastring.h> +#include <google/protobuf/message_lite.h> +#include <google/protobuf/port.h> +#include <google/protobuf/repeated_field.h> +#include <google/protobuf/stubs/casts.h> + + +// Avoid conflict with iOS where <ConditionalMacros.h> #defines TYPE_BOOL. +// +// If some one needs the macro TYPE_BOOL in a file that includes this header, +// it's possible to bring it back using push/pop_macro as follows. +// +// #pragma push_macro("TYPE_BOOL") +// #include this header and/or all headers that need the macro to be undefined. +// #pragma pop_macro("TYPE_BOOL") +#undef TYPE_BOOL + + +#include <google/protobuf/port_def.inc> + +namespace google { +namespace protobuf { +namespace internal { + +// This class is for internal use by the protocol buffer library and by +// protocol-compiler-generated message classes. It must not be called +// directly by clients. +// +// This class contains helpers for implementing the binary protocol buffer +// wire format without the need for reflection. Use WireFormat when using +// reflection. +// +// This class is really a namespace that contains only static methods. +class PROTOBUF_EXPORT WireFormatLite { + public: + // ----------------------------------------------------------------- + // Helper constants and functions related to the format. These are + // mostly meant for internal and generated code to use. + + // The wire format is composed of a sequence of tag/value pairs, each + // of which contains the value of one field (or one element of a repeated + // field). Each tag is encoded as a varint. The lower bits of the tag + // identify its wire type, which specifies the format of the data to follow. + // The rest of the bits contain the field number. Each type of field (as + // declared by FieldDescriptor::Type, in descriptor.h) maps to one of + // these wire types. Immediately following each tag is the field's value, + // encoded in the format specified by the wire type. Because the tag + // identifies the encoding of this data, it is possible to skip + // unrecognized fields for forwards compatibility. + + enum WireType { + WIRETYPE_VARINT = 0, + WIRETYPE_FIXED64 = 1, + WIRETYPE_LENGTH_DELIMITED = 2, + WIRETYPE_START_GROUP = 3, + WIRETYPE_END_GROUP = 4, + WIRETYPE_FIXED32 = 5, + }; + + // Lite alternative to FieldDescriptor::Type. Must be kept in sync. + enum FieldType { + TYPE_DOUBLE = 1, + TYPE_FLOAT = 2, + TYPE_INT64 = 3, + TYPE_UINT64 = 4, + TYPE_INT32 = 5, + TYPE_FIXED64 = 6, + TYPE_FIXED32 = 7, + TYPE_BOOL = 8, + TYPE_STRING = 9, + TYPE_GROUP = 10, + TYPE_MESSAGE = 11, + TYPE_BYTES = 12, + TYPE_UINT32 = 13, + TYPE_ENUM = 14, + TYPE_SFIXED32 = 15, + TYPE_SFIXED64 = 16, + TYPE_SINT32 = 17, + TYPE_SINT64 = 18, + MAX_FIELD_TYPE = 18, + }; + + // Lite alternative to FieldDescriptor::CppType. Must be kept in sync. + enum CppType { + CPPTYPE_INT32 = 1, + CPPTYPE_INT64 = 2, + CPPTYPE_UINT32 = 3, + CPPTYPE_UINT64 = 4, + CPPTYPE_DOUBLE = 5, + CPPTYPE_FLOAT = 6, + CPPTYPE_BOOL = 7, + CPPTYPE_ENUM = 8, + CPPTYPE_STRING = 9, + CPPTYPE_MESSAGE = 10, + MAX_CPPTYPE = 10, + }; + + // Helper method to get the CppType for a particular Type. + static CppType FieldTypeToCppType(FieldType type); + + // Given a FieldDescriptor::Type return its WireType + static inline WireFormatLite::WireType WireTypeForFieldType( + WireFormatLite::FieldType type) { + return kWireTypeForFieldType[type]; + } + + // Number of bits in a tag which identify the wire type. + static constexpr int kTagTypeBits = 3; + // Mask for those bits. + static constexpr arc_ui32 kTagTypeMask = (1 << kTagTypeBits) - 1; + + // Helper functions for encoding and decoding tags. (Inlined below and in + // _inl.h) + // + // This is different from MakeTag(field->number(), field->type()) in the + // case of packed repeated fields. + constexpr static arc_ui32 MakeTag(int field_number, WireType type); + static WireType GetTagWireType(arc_ui32 tag); + static int GetTagFieldNumber(arc_ui32 tag); + + // Compute the byte size of a tag. For groups, this includes both the start + // and end tags. + static inline size_t TagSize(int field_number, + WireFormatLite::FieldType type); + + // Skips a field value with the given tag. The input should start + // positioned immediately after the tag. Skipped values are simply + // discarded, not recorded anywhere. See WireFormat::SkipField() for a + // version that records to an UnknownFieldSet. + static bool SkipField(io::CodedInputStream* input, arc_ui32 tag); + + // Skips a field value with the given tag. The input should start + // positioned immediately after the tag. Skipped values are recorded to a + // CodedOutputStream. + static bool SkipField(io::CodedInputStream* input, arc_ui32 tag, + io::CodedOutputStream* output); + + // Reads and ignores a message from the input. Skipped values are simply + // discarded, not recorded anywhere. See WireFormat::SkipMessage() for a + // version that records to an UnknownFieldSet. + static bool SkipMessage(io::CodedInputStream* input); + + // Reads and ignores a message from the input. Skipped values are recorded + // to a CodedOutputStream. + static bool SkipMessage(io::CodedInputStream* input, + io::CodedOutputStream* output); + + // This macro does the same thing as WireFormatLite::MakeTag(), but the + // result is usable as a compile-time constant, which makes it usable + // as a switch case or a template input. WireFormatLite::MakeTag() is more + // type-safe, though, so prefer it if possible. +#define GOOGLE_PROTOBUF_WIRE_FORMAT_MAKE_TAG(FIELD_NUMBER, TYPE) \ + static_cast<arc_ui32>((static_cast<arc_ui32>(FIELD_NUMBER) << 3) | (TYPE)) + + // These are the tags for the old MessageSet format, which was defined as: + // message MessageSet { + // repeated group Item = 1 { + // required int32 type_id = 2; + // required string message = 3; + // } + // } + static constexpr int kMessageSetItemNumber = 1; + static constexpr int kMessageSetTypeIdNumber = 2; + static constexpr int kMessageSetMessageNumber = 3; + static const int kMessageSetItemStartTag = GOOGLE_PROTOBUF_WIRE_FORMAT_MAKE_TAG( + kMessageSetItemNumber, WireFormatLite::WIRETYPE_START_GROUP); + static const int kMessageSetItemEndTag = GOOGLE_PROTOBUF_WIRE_FORMAT_MAKE_TAG( + kMessageSetItemNumber, WireFormatLite::WIRETYPE_END_GROUP); + static const int kMessageSetTypeIdTag = GOOGLE_PROTOBUF_WIRE_FORMAT_MAKE_TAG( + kMessageSetTypeIdNumber, WireFormatLite::WIRETYPE_VARINT); + static const int kMessageSetMessageTag = GOOGLE_PROTOBUF_WIRE_FORMAT_MAKE_TAG( + kMessageSetMessageNumber, WireFormatLite::WIRETYPE_LENGTH_DELIMITED); + + // Byte size of all tags of a MessageSet::Item combined. + static const size_t kMessageSetItemTagsSize; + + // Helper functions for converting between floats/doubles and IEEE-754 + // uint32s/uint64s so that they can be written. (Assumes your platform + // uses IEEE-754 floats.) + static arc_ui32 EncodeFloat(float value); + static float DecodeFloat(arc_ui32 value); + static arc_ui64 EncodeDouble(double value); + static double DecodeDouble(arc_ui64 value); + + // Helper functions for mapping signed integers to unsigned integers in + // such a way that numbers with small magnitudes will encode to smaller + // varints. If you simply static_cast a negative number to an unsigned + // number and varint-encode it, it will always take 10 bytes, defeating + // the purpose of varint. So, for the "sint32" and "sint64" field types, + // we ZigZag-encode the values. + static arc_ui32 ZigZagEncode32(arc_i32 n); + static arc_i32 ZigZagDecode32(arc_ui32 n); + static arc_ui64 ZigZagEncode64(arc_i64 n); + static arc_i64 ZigZagDecode64(arc_ui64 n); + + // ================================================================= + // Methods for reading/writing individual field. + + // Read fields, not including tags. The assumption is that you already + // read the tag to determine what field to read. + + // For primitive fields, we just use a templatized routine parameterized by + // the represented type and the FieldType. These are specialized with the + // appropriate definition for each declared type. + template <typename CType, enum FieldType DeclaredType> + PROTOBUF_NDEBUG_INLINE static bool ReadPrimitive(io::CodedInputStream* input, + CType* value); + + // Reads repeated primitive values, with optimizations for repeats. + // tag_size and tag should both be compile-time constants provided by the + // protocol compiler. + template <typename CType, enum FieldType DeclaredType> + PROTOBUF_NDEBUG_INLINE static bool ReadRepeatedPrimitive( + int tag_size, arc_ui32 tag, io::CodedInputStream* input, + RepeatedField<CType>* value); + + // Identical to ReadRepeatedPrimitive, except will not inline the + // implementation. + template <typename CType, enum FieldType DeclaredType> + static bool ReadRepeatedPrimitiveNoInline(int tag_size, arc_ui32 tag, + io::CodedInputStream* input, + RepeatedField<CType>* value); + + // Reads a primitive value directly from the provided buffer. It returns a + // pointer past the segment of data that was read. + // + // This is only implemented for the types with fixed wire size, e.g. + // float, double, and the (s)fixed* types. + template <typename CType, enum FieldType DeclaredType> + PROTOBUF_NDEBUG_INLINE static const uint8_t* ReadPrimitiveFromArray( + const uint8_t* buffer, CType* value); + + // Reads a primitive packed field. + // + // This is only implemented for packable types. + template <typename CType, enum FieldType DeclaredType> + PROTOBUF_NDEBUG_INLINE static bool ReadPackedPrimitive( + io::CodedInputStream* input, RepeatedField<CType>* value); + + // Identical to ReadPackedPrimitive, except will not inline the + // implementation. + template <typename CType, enum FieldType DeclaredType> + static bool ReadPackedPrimitiveNoInline(io::CodedInputStream* input, + RepeatedField<CType>* value); + + // Read a packed enum field. If the is_valid function is not nullptr, values + // for which is_valid(value) returns false are silently dropped. + static bool ReadPackedEnumNoInline(io::CodedInputStream* input, + bool (*is_valid)(int), + RepeatedField<int>* values); + + // Read a packed enum field. If the is_valid function is not nullptr, values + // for which is_valid(value) returns false are appended to + // unknown_fields_stream. + static bool ReadPackedEnumPreserveUnknowns( + io::CodedInputStream* input, int field_number, bool (*is_valid)(int), + io::CodedOutputStream* unknown_fields_stream, RepeatedField<int>* values); + + // Read a string. ReadString(..., TProtoStringType* value) requires an + // existing TProtoStringType. + static inline bool ReadString(io::CodedInputStream* input, + TProtoStringType* value); + // ReadString(..., TProtoStringType** p) is internal-only, and should only be + // called from generated code. It starts by setting *p to "new TProtoStringType" if + // *p == &GetEmptyStringAlreadyInited(). It then invokes + // ReadString(io::CodedInputStream* input, *p). This is useful for reducing + // code size. + static inline bool ReadString(io::CodedInputStream* input, TProtoStringType** p); + // Analogous to ReadString(). + static bool ReadBytes(io::CodedInputStream* input, TProtoStringType* value); + static bool ReadBytes(io::CodedInputStream* input, TProtoStringType** p); + + enum Operation { + PARSE = 0, + SERIALIZE = 1, + }; + + // Returns true if the data is valid UTF-8. + static bool VerifyUtf8String(const char* data, int size, Operation op, + const char* field_name); + + template <typename MessageType> + static inline bool ReadGroup(int field_number, io::CodedInputStream* input, + MessageType* value); + + template <typename MessageType> + static inline bool ReadMessage(io::CodedInputStream* input, + MessageType* value); + + template <typename MessageType> + static inline bool ReadMessageNoVirtual(io::CodedInputStream* input, + MessageType* value) { + return ReadMessage(input, value); + } + + // Write a tag. The Write*() functions typically include the tag, so + // normally there's no need to call this unless using the Write*NoTag() + // variants. + PROTOBUF_NDEBUG_INLINE static void WriteTag(int field_number, WireType type, + io::CodedOutputStream* output); + + // Write fields, without tags. + PROTOBUF_NDEBUG_INLINE static void WriteInt32NoTag( + arc_i32 value, io::CodedOutputStream* output); + PROTOBUF_NDEBUG_INLINE static void WriteInt64NoTag( + arc_i64 value, io::CodedOutputStream* output); + PROTOBUF_NDEBUG_INLINE static void WriteUInt32NoTag( + arc_ui32 value, io::CodedOutputStream* output); + PROTOBUF_NDEBUG_INLINE static void WriteUInt64NoTag( + arc_ui64 value, io::CodedOutputStream* output); + PROTOBUF_NDEBUG_INLINE static void WriteSInt32NoTag( + arc_i32 value, io::CodedOutputStream* output); + PROTOBUF_NDEBUG_INLINE static void WriteSInt64NoTag( + arc_i64 value, io::CodedOutputStream* output); + PROTOBUF_NDEBUG_INLINE static void WriteFixed32NoTag( + arc_ui32 value, io::CodedOutputStream* output); + PROTOBUF_NDEBUG_INLINE static void WriteFixed64NoTag( + arc_ui64 value, io::CodedOutputStream* output); + PROTOBUF_NDEBUG_INLINE static void WriteSFixed32NoTag( + arc_i32 value, io::CodedOutputStream* output); + PROTOBUF_NDEBUG_INLINE static void WriteSFixed64NoTag( + arc_i64 value, io::CodedOutputStream* output); + PROTOBUF_NDEBUG_INLINE static void WriteFloatNoTag( + float value, io::CodedOutputStream* output); + PROTOBUF_NDEBUG_INLINE static void WriteDoubleNoTag( + double value, io::CodedOutputStream* output); + PROTOBUF_NDEBUG_INLINE static void WriteBoolNoTag( + bool value, io::CodedOutputStream* output); + PROTOBUF_NDEBUG_INLINE static void WriteEnumNoTag( + int value, io::CodedOutputStream* output); + + // Write array of primitive fields, without tags + static void WriteFloatArray(const float* a, int n, + io::CodedOutputStream* output); + static void WriteDoubleArray(const double* a, int n, + io::CodedOutputStream* output); + static void WriteFixed32Array(const arc_ui32* a, int n, + io::CodedOutputStream* output); + static void WriteFixed64Array(const arc_ui64* a, int n, + io::CodedOutputStream* output); + static void WriteSFixed32Array(const arc_i32* a, int n, + io::CodedOutputStream* output); + static void WriteSFixed64Array(const arc_i64* a, int n, + io::CodedOutputStream* output); + static void WriteBoolArray(const bool* a, int n, + io::CodedOutputStream* output); + + // Write fields, including tags. + static void WriteInt32(int field_number, arc_i32 value, + io::CodedOutputStream* output); + static void WriteInt64(int field_number, arc_i64 value, + io::CodedOutputStream* output); + static void WriteUInt32(int field_number, arc_ui32 value, + io::CodedOutputStream* output); + static void WriteUInt64(int field_number, arc_ui64 value, + io::CodedOutputStream* output); + static void WriteSInt32(int field_number, arc_i32 value, + io::CodedOutputStream* output); + static void WriteSInt64(int field_number, arc_i64 value, + io::CodedOutputStream* output); + static void WriteFixed32(int field_number, arc_ui32 value, + io::CodedOutputStream* output); + static void WriteFixed64(int field_number, arc_ui64 value, + io::CodedOutputStream* output); + static void WriteSFixed32(int field_number, arc_i32 value, + io::CodedOutputStream* output); + static void WriteSFixed64(int field_number, arc_i64 value, + io::CodedOutputStream* output); + static void WriteFloat(int field_number, float value, + io::CodedOutputStream* output); + static void WriteDouble(int field_number, double value, + io::CodedOutputStream* output); + static void WriteBool(int field_number, bool value, + io::CodedOutputStream* output); + static void WriteEnum(int field_number, int value, + io::CodedOutputStream* output); + + static void WriteString(int field_number, const TProtoStringType& value, + io::CodedOutputStream* output); + static void WriteBytes(int field_number, const TProtoStringType& value, + io::CodedOutputStream* output); + static void WriteStringMaybeAliased(int field_number, + const TProtoStringType& value, + io::CodedOutputStream* output); + static void WriteBytesMaybeAliased(int field_number, const TProtoStringType& value, + io::CodedOutputStream* output); + + static void WriteGroup(int field_number, const MessageLite& value, + io::CodedOutputStream* output); + static void WriteMessage(int field_number, const MessageLite& value, + io::CodedOutputStream* output); + // Like above, but these will check if the output stream has enough + // space to write directly to a flat array. + static void WriteGroupMaybeToArray(int field_number, const MessageLite& value, + io::CodedOutputStream* output); + static void WriteMessageMaybeToArray(int field_number, + const MessageLite& value, + io::CodedOutputStream* output); + + // Like above, but de-virtualize the call to SerializeWithCachedSizes(). The + // pointer must point at an instance of MessageType, *not* a subclass (or + // the subclass must not override SerializeWithCachedSizes()). + template <typename MessageType> + static inline void WriteGroupNoVirtual(int field_number, + const MessageType& value, + io::CodedOutputStream* output); + template <typename MessageType> + static inline void WriteMessageNoVirtual(int field_number, + const MessageType& value, + io::CodedOutputStream* output); + + // Like above, but use only *ToArray methods of CodedOutputStream. + PROTOBUF_NDEBUG_INLINE static uint8_t* WriteTagToArray(int field_number, + WireType type, + uint8_t* target); + + // Write fields, without tags. + PROTOBUF_NDEBUG_INLINE static uint8_t* WriteInt32NoTagToArray( + arc_i32 value, uint8_t* target); + PROTOBUF_NDEBUG_INLINE static uint8_t* WriteInt64NoTagToArray( + arc_i64 value, uint8_t* target); + PROTOBUF_NDEBUG_INLINE static uint8_t* WriteUInt32NoTagToArray( + arc_ui32 value, uint8_t* target); + PROTOBUF_NDEBUG_INLINE static uint8_t* WriteUInt64NoTagToArray( + arc_ui64 value, uint8_t* target); + PROTOBUF_NDEBUG_INLINE static uint8_t* WriteSInt32NoTagToArray( + arc_i32 value, uint8_t* target); + PROTOBUF_NDEBUG_INLINE static uint8_t* WriteSInt64NoTagToArray( + arc_i64 value, uint8_t* target); + PROTOBUF_NDEBUG_INLINE static uint8_t* WriteFixed32NoTagToArray( + arc_ui32 value, uint8_t* target); + PROTOBUF_NDEBUG_INLINE static uint8_t* WriteFixed64NoTagToArray( + arc_ui64 value, uint8_t* target); + PROTOBUF_NDEBUG_INLINE static uint8_t* WriteSFixed32NoTagToArray( + arc_i32 value, uint8_t* target); + PROTOBUF_NDEBUG_INLINE static uint8_t* WriteSFixed64NoTagToArray( + arc_i64 value, uint8_t* target); + PROTOBUF_NDEBUG_INLINE static uint8_t* WriteFloatNoTagToArray( + float value, uint8_t* target); + PROTOBUF_NDEBUG_INLINE static uint8_t* WriteDoubleNoTagToArray( + double value, uint8_t* target); + PROTOBUF_NDEBUG_INLINE static uint8_t* WriteBoolNoTagToArray(bool value, + uint8_t* target); + PROTOBUF_NDEBUG_INLINE static uint8_t* WriteEnumNoTagToArray(int value, + uint8_t* target); + + // Write fields, without tags. These require that value.size() > 0. + template <typename T> + PROTOBUF_NDEBUG_INLINE static uint8_t* WritePrimitiveNoTagToArray( + const RepeatedField<T>& value, uint8_t* (*Writer)(T, uint8_t*), + uint8_t* target); + template <typename T> + PROTOBUF_NDEBUG_INLINE static uint8_t* WriteFixedNoTagToArray( + const RepeatedField<T>& value, uint8_t* (*Writer)(T, uint8_t*), + uint8_t* target); + + PROTOBUF_NDEBUG_INLINE static uint8_t* WriteInt32NoTagToArray( + const RepeatedField<arc_i32>& value, uint8_t* output); + PROTOBUF_NDEBUG_INLINE static uint8_t* WriteInt64NoTagToArray( + const RepeatedField<arc_i64>& value, uint8_t* output); + PROTOBUF_NDEBUG_INLINE static uint8_t* WriteUInt32NoTagToArray( + const RepeatedField<arc_ui32>& value, uint8_t* output); + PROTOBUF_NDEBUG_INLINE static uint8_t* WriteUInt64NoTagToArray( + const RepeatedField<arc_ui64>& value, uint8_t* output); + PROTOBUF_NDEBUG_INLINE static uint8_t* WriteSInt32NoTagToArray( + const RepeatedField<arc_i32>& value, uint8_t* output); + PROTOBUF_NDEBUG_INLINE static uint8_t* WriteSInt64NoTagToArray( + const RepeatedField<arc_i64>& value, uint8_t* output); + PROTOBUF_NDEBUG_INLINE static uint8_t* WriteFixed32NoTagToArray( + const RepeatedField<arc_ui32>& value, uint8_t* output); + PROTOBUF_NDEBUG_INLINE static uint8_t* WriteFixed64NoTagToArray( + const RepeatedField<arc_ui64>& value, uint8_t* output); + PROTOBUF_NDEBUG_INLINE static uint8_t* WriteSFixed32NoTagToArray( + const RepeatedField<arc_i32>& value, uint8_t* output); + PROTOBUF_NDEBUG_INLINE static uint8_t* WriteSFixed64NoTagToArray( + const RepeatedField<arc_i64>& value, uint8_t* output); + PROTOBUF_NDEBUG_INLINE static uint8_t* WriteFloatNoTagToArray( + const RepeatedField<float>& value, uint8_t* output); + PROTOBUF_NDEBUG_INLINE static uint8_t* WriteDoubleNoTagToArray( + const RepeatedField<double>& value, uint8_t* output); + PROTOBUF_NDEBUG_INLINE static uint8_t* WriteBoolNoTagToArray( + const RepeatedField<bool>& value, uint8_t* output); + PROTOBUF_NDEBUG_INLINE static uint8_t* WriteEnumNoTagToArray( + const RepeatedField<int>& value, uint8_t* output); + + // Write fields, including tags. + PROTOBUF_NDEBUG_INLINE static uint8_t* WriteInt32ToArray(int field_number, + arc_i32 value, + uint8_t* target); + PROTOBUF_NDEBUG_INLINE static uint8_t* WriteInt64ToArray(int field_number, + arc_i64 value, + uint8_t* target); + PROTOBUF_NDEBUG_INLINE static uint8_t* WriteUInt32ToArray(int field_number, + arc_ui32 value, + uint8_t* target); + PROTOBUF_NDEBUG_INLINE static uint8_t* WriteUInt64ToArray(int field_number, + arc_ui64 value, + uint8_t* target); + PROTOBUF_NDEBUG_INLINE static uint8_t* WriteSInt32ToArray(int field_number, + arc_i32 value, + uint8_t* target); + PROTOBUF_NDEBUG_INLINE static uint8_t* WriteSInt64ToArray(int field_number, + arc_i64 value, + uint8_t* target); + PROTOBUF_NDEBUG_INLINE static uint8_t* WriteFixed32ToArray(int field_number, + arc_ui32 value, + uint8_t* target); + PROTOBUF_NDEBUG_INLINE static uint8_t* WriteFixed64ToArray(int field_number, + arc_ui64 value, + uint8_t* target); + PROTOBUF_NDEBUG_INLINE static uint8_t* WriteSFixed32ToArray(int field_number, + arc_i32 value, + uint8_t* target); + PROTOBUF_NDEBUG_INLINE static uint8_t* WriteSFixed64ToArray(int field_number, + arc_i64 value, + uint8_t* target); + PROTOBUF_NDEBUG_INLINE static uint8_t* WriteFloatToArray(int field_number, + float value, + uint8_t* target); + PROTOBUF_NDEBUG_INLINE static uint8_t* WriteDoubleToArray(int field_number, + double value, + uint8_t* target); + PROTOBUF_NDEBUG_INLINE static uint8_t* WriteBoolToArray(int field_number, + bool value, + uint8_t* target); + PROTOBUF_NDEBUG_INLINE static uint8_t* WriteEnumToArray(int field_number, + int value, + uint8_t* target); + + template <typename T> + PROTOBUF_NDEBUG_INLINE static uint8_t* WritePrimitiveToArray( + int field_number, const RepeatedField<T>& value, + uint8_t* (*Writer)(int, T, uint8_t*), uint8_t* target); + + PROTOBUF_NDEBUG_INLINE static uint8_t* WriteInt32ToArray( + int field_number, const RepeatedField<arc_i32>& value, uint8_t* output); + PROTOBUF_NDEBUG_INLINE static uint8_t* WriteInt64ToArray( + int field_number, const RepeatedField<arc_i64>& value, uint8_t* output); + PROTOBUF_NDEBUG_INLINE static uint8_t* WriteUInt32ToArray( + int field_number, const RepeatedField<arc_ui32>& value, uint8_t* output); + PROTOBUF_NDEBUG_INLINE static uint8_t* WriteUInt64ToArray( + int field_number, const RepeatedField<arc_ui64>& value, uint8_t* output); + PROTOBUF_NDEBUG_INLINE static uint8_t* WriteSInt32ToArray( + int field_number, const RepeatedField<arc_i32>& value, uint8_t* output); + PROTOBUF_NDEBUG_INLINE static uint8_t* WriteSInt64ToArray( + int field_number, const RepeatedField<arc_i64>& value, uint8_t* output); + PROTOBUF_NDEBUG_INLINE static uint8_t* WriteFixed32ToArray( + int field_number, const RepeatedField<arc_ui32>& value, uint8_t* output); + PROTOBUF_NDEBUG_INLINE static uint8_t* WriteFixed64ToArray( + int field_number, const RepeatedField<arc_ui64>& value, uint8_t* output); + PROTOBUF_NDEBUG_INLINE static uint8_t* WriteSFixed32ToArray( + int field_number, const RepeatedField<arc_i32>& value, uint8_t* output); + PROTOBUF_NDEBUG_INLINE static uint8_t* WriteSFixed64ToArray( + int field_number, const RepeatedField<arc_i64>& value, uint8_t* output); + PROTOBUF_NDEBUG_INLINE static uint8_t* WriteFloatToArray( + int field_number, const RepeatedField<float>& value, uint8_t* output); + PROTOBUF_NDEBUG_INLINE static uint8_t* WriteDoubleToArray( + int field_number, const RepeatedField<double>& value, uint8_t* output); + PROTOBUF_NDEBUG_INLINE static uint8_t* WriteBoolToArray( + int field_number, const RepeatedField<bool>& value, uint8_t* output); + PROTOBUF_NDEBUG_INLINE static uint8_t* WriteEnumToArray( + int field_number, const RepeatedField<int>& value, uint8_t* output); + + PROTOBUF_NDEBUG_INLINE static uint8_t* WriteStringToArray( + int field_number, const TProtoStringType& value, uint8_t* target); + PROTOBUF_NDEBUG_INLINE static uint8_t* WriteBytesToArray( + int field_number, const TProtoStringType& value, uint8_t* target); + + // Whether to serialize deterministically (e.g., map keys are + // sorted) is a property of a CodedOutputStream, and in the process + // of serialization, the "ToArray" variants may be invoked. But they don't + // have a CodedOutputStream available, so they get an additional parameter + // telling them whether to serialize deterministically. + template <typename MessageType> + PROTOBUF_NDEBUG_INLINE static uint8_t* InternalWriteGroup( + int field_number, const MessageType& value, uint8_t* target, + io::EpsCopyOutputStream* stream); + template <typename MessageType> + PROTOBUF_NDEBUG_INLINE static uint8_t* InternalWriteMessage( + int field_number, const MessageType& value, uint8_t* target, + io::EpsCopyOutputStream* stream); + + // Like above, but de-virtualize the call to SerializeWithCachedSizes(). The + // pointer must point at an instance of MessageType, *not* a subclass (or + // the subclass must not override SerializeWithCachedSizes()). + template <typename MessageType> + PROTOBUF_NDEBUG_INLINE static uint8_t* InternalWriteGroupNoVirtualToArray( + int field_number, const MessageType& value, uint8_t* target); + template <typename MessageType> + PROTOBUF_NDEBUG_INLINE static uint8_t* InternalWriteMessageNoVirtualToArray( + int field_number, const MessageType& value, uint8_t* target); + + // For backward-compatibility, the last four methods also have versions + // that are non-deterministic always. + PROTOBUF_NDEBUG_INLINE static uint8_t* WriteGroupToArray( + int field_number, const MessageLite& value, uint8_t* target) { + io::EpsCopyOutputStream stream( + target, + value.GetCachedSize() + + static_cast<int>(2 * io::CodedOutputStream::VarintSize32( + static_cast<arc_ui32>(field_number) << 3)), + io::CodedOutputStream::IsDefaultSerializationDeterministic()); + return InternalWriteGroup(field_number, value, target, &stream); + } + PROTOBUF_NDEBUG_INLINE static uint8_t* WriteMessageToArray( + int field_number, const MessageLite& value, uint8_t* target) { + int size = value.GetCachedSize(); + io::EpsCopyOutputStream stream( + target, + size + static_cast<int>(io::CodedOutputStream::VarintSize32( + static_cast<arc_ui32>(field_number) << 3) + + io::CodedOutputStream::VarintSize32(size)), + io::CodedOutputStream::IsDefaultSerializationDeterministic()); + return InternalWriteMessage(field_number, value, target, &stream); + } + + // Compute the byte size of a field. The XxSize() functions do NOT include + // the tag, so you must also call TagSize(). (This is because, for repeated + // fields, you should only call TagSize() once and multiply it by the element + // count, but you may have to call XxSize() for each individual element.) + static inline size_t Int32Size(arc_i32 value); + static inline size_t Int64Size(arc_i64 value); + static inline size_t UInt32Size(arc_ui32 value); + static inline size_t UInt64Size(arc_ui64 value); + static inline size_t SInt32Size(arc_i32 value); + static inline size_t SInt64Size(arc_i64 value); + static inline size_t EnumSize(int value); + static inline size_t Int32SizePlusOne(arc_i32 value); + static inline size_t Int64SizePlusOne(arc_i64 value); + static inline size_t UInt32SizePlusOne(arc_ui32 value); + static inline size_t UInt64SizePlusOne(arc_ui64 value); + static inline size_t SInt32SizePlusOne(arc_i32 value); + static inline size_t SInt64SizePlusOne(arc_i64 value); + static inline size_t EnumSizePlusOne(int value); + + static size_t Int32Size(const RepeatedField<arc_i32>& value); + static size_t Int64Size(const RepeatedField<arc_i64>& value); + static size_t UInt32Size(const RepeatedField<arc_ui32>& value); + static size_t UInt64Size(const RepeatedField<arc_ui64>& value); + static size_t SInt32Size(const RepeatedField<arc_i32>& value); + static size_t SInt64Size(const RepeatedField<arc_i64>& value); + static size_t EnumSize(const RepeatedField<int>& value); + + // These types always have the same size. + static constexpr size_t kFixed32Size = 4; + static constexpr size_t kFixed64Size = 8; + static constexpr size_t kSFixed32Size = 4; + static constexpr size_t kSFixed64Size = 8; + static constexpr size_t kFloatSize = 4; + static constexpr size_t kDoubleSize = 8; + static constexpr size_t kBoolSize = 1; + + static inline size_t StringSize(const TProtoStringType& value); + static inline size_t BytesSize(const TProtoStringType& value); + + template <typename MessageType> + static inline size_t GroupSize(const MessageType& value); + template <typename MessageType> + static inline size_t MessageSize(const MessageType& value); + + // Like above, but de-virtualize the call to ByteSize(). The + // pointer must point at an instance of MessageType, *not* a subclass (or + // the subclass must not override ByteSize()). + template <typename MessageType> + static inline size_t GroupSizeNoVirtual(const MessageType& value); + template <typename MessageType> + static inline size_t MessageSizeNoVirtual(const MessageType& value); + + // Given the length of data, calculate the byte size of the data on the + // wire if we encode the data as a length delimited field. + static inline size_t LengthDelimitedSize(size_t length); + + private: + // A helper method for the repeated primitive reader. This method has + // optimizations for primitive types that have fixed size on the wire, and + // can be read using potentially faster paths. + template <typename CType, enum FieldType DeclaredType> + PROTOBUF_NDEBUG_INLINE static bool ReadRepeatedFixedSizePrimitive( + int tag_size, arc_ui32 tag, io::CodedInputStream* input, + RepeatedField<CType>* value); + + // Like ReadRepeatedFixedSizePrimitive but for packed primitive fields. + template <typename CType, enum FieldType DeclaredType> + PROTOBUF_NDEBUG_INLINE static bool ReadPackedFixedSizePrimitive( + io::CodedInputStream* input, RepeatedField<CType>* value); + + static const CppType kFieldTypeToCppTypeMap[]; + static const WireFormatLite::WireType kWireTypeForFieldType[]; + static void WriteSubMessageMaybeToArray(int size, const MessageLite& value, + io::CodedOutputStream* output); + + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(WireFormatLite); +}; + +// A class which deals with unknown values. The default implementation just +// discards them. WireFormat defines a subclass which writes to an +// UnknownFieldSet. This class is used by ExtensionSet::ParseField(), since +// ExtensionSet is part of the lite library but UnknownFieldSet is not. +class PROTOBUF_EXPORT FieldSkipper { + public: + FieldSkipper() {} + virtual ~FieldSkipper() {} + + // Skip a field whose tag has already been consumed. + virtual bool SkipField(io::CodedInputStream* input, arc_ui32 tag); + + // Skip an entire message or group, up to an end-group tag (which is consumed) + // or end-of-stream. + virtual bool SkipMessage(io::CodedInputStream* input); + + // Deal with an already-parsed unrecognized enum value. The default + // implementation does nothing, but the UnknownFieldSet-based implementation + // saves it as an unknown varint. + virtual void SkipUnknownEnum(int field_number, int value); +}; + +// Subclass of FieldSkipper which saves skipped fields to a CodedOutputStream. + +class PROTOBUF_EXPORT CodedOutputStreamFieldSkipper : public FieldSkipper { + public: + explicit CodedOutputStreamFieldSkipper(io::CodedOutputStream* unknown_fields) + : unknown_fields_(unknown_fields) {} + ~CodedOutputStreamFieldSkipper() override {} + + // implements FieldSkipper ----------------------------------------- + bool SkipField(io::CodedInputStream* input, arc_ui32 tag) override; + bool SkipMessage(io::CodedInputStream* input) override; + void SkipUnknownEnum(int field_number, int value) override; + + protected: + io::CodedOutputStream* unknown_fields_; +}; + +// inline methods ==================================================== + +inline WireFormatLite::CppType WireFormatLite::FieldTypeToCppType( + FieldType type) { + return kFieldTypeToCppTypeMap[type]; +} + +constexpr inline arc_ui32 WireFormatLite::MakeTag(int field_number, + WireType type) { + return GOOGLE_PROTOBUF_WIRE_FORMAT_MAKE_TAG(field_number, type); +} + +inline WireFormatLite::WireType WireFormatLite::GetTagWireType(arc_ui32 tag) { + return static_cast<WireType>(tag & kTagTypeMask); +} + +inline int WireFormatLite::GetTagFieldNumber(arc_ui32 tag) { + return static_cast<int>(tag >> kTagTypeBits); +} + +inline size_t WireFormatLite::TagSize(int field_number, + WireFormatLite::FieldType type) { + size_t result = io::CodedOutputStream::VarintSize32( + static_cast<arc_ui32>(field_number << kTagTypeBits)); + if (type == TYPE_GROUP) { + // Groups have both a start and an end tag. + return result * 2; + } else { + return result; + } +} + +inline arc_ui32 WireFormatLite::EncodeFloat(float value) { + return bit_cast<arc_ui32>(value); +} + +inline float WireFormatLite::DecodeFloat(arc_ui32 value) { + return bit_cast<float>(value); +} + +inline arc_ui64 WireFormatLite::EncodeDouble(double value) { + return bit_cast<arc_ui64>(value); +} + +inline double WireFormatLite::DecodeDouble(arc_ui64 value) { + return bit_cast<double>(value); +} + +// ZigZag Transform: Encodes signed integers so that they can be +// effectively used with varint encoding. +// +// varint operates on unsigned integers, encoding smaller numbers into +// fewer bytes. If you try to use it on a signed integer, it will treat +// this number as a very large unsigned integer, which means that even +// small signed numbers like -1 will take the maximum number of bytes +// (10) to encode. ZigZagEncode() maps signed integers to unsigned +// in such a way that those with a small absolute value will have smaller +// encoded values, making them appropriate for encoding using varint. +// +// arc_i32 -> arc_ui32 +// ------------------------- +// 0 -> 0 +// -1 -> 1 +// 1 -> 2 +// -2 -> 3 +// ... -> ... +// 2147483647 -> 4294967294 +// -2147483648 -> 4294967295 +// +// >> encode >> +// << decode << + +inline arc_ui32 WireFormatLite::ZigZagEncode32(arc_i32 n) { + // Note: the right-shift must be arithmetic + // Note: left shift must be unsigned because of overflow + return (static_cast<arc_ui32>(n) << 1) ^ static_cast<arc_ui32>(n >> 31); +} + +inline arc_i32 WireFormatLite::ZigZagDecode32(arc_ui32 n) { + // Note: Using unsigned types prevent undefined behavior + return static_cast<arc_i32>((n >> 1) ^ (~(n & 1) + 1)); +} + +inline arc_ui64 WireFormatLite::ZigZagEncode64(arc_i64 n) { + // Note: the right-shift must be arithmetic + // Note: left shift must be unsigned because of overflow + return (static_cast<arc_ui64>(n) << 1) ^ static_cast<arc_ui64>(n >> 63); +} + +inline arc_i64 WireFormatLite::ZigZagDecode64(arc_ui64 n) { + // Note: Using unsigned types prevent undefined behavior + return static_cast<arc_i64>((n >> 1) ^ (~(n & 1) + 1)); +} + +// String is for UTF-8 text only, but, even so, ReadString() can simply +// call ReadBytes(). + +inline bool WireFormatLite::ReadString(io::CodedInputStream* input, + TProtoStringType* value) { + return ReadBytes(input, value); +} + +inline bool WireFormatLite::ReadString(io::CodedInputStream* input, + TProtoStringType** p) { + return ReadBytes(input, p); +} + +inline uint8_t* InternalSerializeUnknownMessageSetItemsToArray( + const TProtoStringType& unknown_fields, uint8_t* target, + io::EpsCopyOutputStream* stream) { + return stream->WriteRaw(unknown_fields.data(), + static_cast<int>(unknown_fields.size()), target); +} + +inline size_t ComputeUnknownMessageSetItemsSize( + const TProtoStringType& unknown_fields) { + return unknown_fields.size(); +} + +// Implementation details of ReadPrimitive. + +template <> +inline bool WireFormatLite::ReadPrimitive<arc_i32, WireFormatLite::TYPE_INT32>( + io::CodedInputStream* input, arc_i32* value) { + arc_ui32 temp; + if (!input->ReadVarint32(&temp)) return false; + *value = static_cast<arc_i32>(temp); + return true; +} +template <> +inline bool WireFormatLite::ReadPrimitive<arc_i64, WireFormatLite::TYPE_INT64>( + io::CodedInputStream* input, arc_i64* value) { + arc_ui64 temp; + if (!input->ReadVarint64(&temp)) return false; + *value = static_cast<arc_i64>(temp); + return true; +} +template <> +inline bool +WireFormatLite::ReadPrimitive<arc_ui32, WireFormatLite::TYPE_UINT32>( + io::CodedInputStream* input, arc_ui32* value) { + return input->ReadVarint32(value); +} +template <> +inline bool +WireFormatLite::ReadPrimitive<arc_ui64, WireFormatLite::TYPE_UINT64>( + io::CodedInputStream* input, arc_ui64* value) { + return input->ReadVarint64(value); +} +template <> +inline bool WireFormatLite::ReadPrimitive<arc_i32, WireFormatLite::TYPE_SINT32>( + io::CodedInputStream* input, arc_i32* value) { + arc_ui32 temp; + if (!input->ReadVarint32(&temp)) return false; + *value = ZigZagDecode32(temp); + return true; +} +template <> +inline bool WireFormatLite::ReadPrimitive<arc_i64, WireFormatLite::TYPE_SINT64>( + io::CodedInputStream* input, arc_i64* value) { + arc_ui64 temp; + if (!input->ReadVarint64(&temp)) return false; + *value = ZigZagDecode64(temp); + return true; +} +template <> +inline bool +WireFormatLite::ReadPrimitive<arc_ui32, WireFormatLite::TYPE_FIXED32>( + io::CodedInputStream* input, arc_ui32* value) { + return input->ReadLittleEndian32(value); +} +template <> +inline bool +WireFormatLite::ReadPrimitive<arc_ui64, WireFormatLite::TYPE_FIXED64>( + io::CodedInputStream* input, arc_ui64* value) { + return input->ReadLittleEndian64(value); +} +template <> +inline bool +WireFormatLite::ReadPrimitive<arc_i32, WireFormatLite::TYPE_SFIXED32>( + io::CodedInputStream* input, arc_i32* value) { + arc_ui32 temp; + if (!input->ReadLittleEndian32(&temp)) return false; + *value = static_cast<arc_i32>(temp); + return true; +} +template <> +inline bool +WireFormatLite::ReadPrimitive<arc_i64, WireFormatLite::TYPE_SFIXED64>( + io::CodedInputStream* input, arc_i64* value) { + arc_ui64 temp; + if (!input->ReadLittleEndian64(&temp)) return false; + *value = static_cast<arc_i64>(temp); + return true; +} +template <> +inline bool WireFormatLite::ReadPrimitive<float, WireFormatLite::TYPE_FLOAT>( + io::CodedInputStream* input, float* value) { + arc_ui32 temp; + if (!input->ReadLittleEndian32(&temp)) return false; + *value = DecodeFloat(temp); + return true; +} +template <> +inline bool WireFormatLite::ReadPrimitive<double, WireFormatLite::TYPE_DOUBLE>( + io::CodedInputStream* input, double* value) { + arc_ui64 temp; + if (!input->ReadLittleEndian64(&temp)) return false; + *value = DecodeDouble(temp); + return true; +} +template <> +inline bool WireFormatLite::ReadPrimitive<bool, WireFormatLite::TYPE_BOOL>( + io::CodedInputStream* input, bool* value) { + arc_ui64 temp; + if (!input->ReadVarint64(&temp)) return false; + *value = temp != 0; + return true; +} +template <> +inline bool WireFormatLite::ReadPrimitive<int, WireFormatLite::TYPE_ENUM>( + io::CodedInputStream* input, int* value) { + arc_ui32 temp; + if (!input->ReadVarint32(&temp)) return false; + *value = static_cast<int>(temp); + return true; +} + +template <> +inline const uint8_t* +WireFormatLite::ReadPrimitiveFromArray<arc_ui32, WireFormatLite::TYPE_FIXED32>( + const uint8_t* buffer, arc_ui32* value) { + return io::CodedInputStream::ReadLittleEndian32FromArray(buffer, value); +} +template <> +inline const uint8_t* +WireFormatLite::ReadPrimitiveFromArray<arc_ui64, WireFormatLite::TYPE_FIXED64>( + const uint8_t* buffer, arc_ui64* value) { + return io::CodedInputStream::ReadLittleEndian64FromArray(buffer, value); +} +template <> +inline const uint8_t* +WireFormatLite::ReadPrimitiveFromArray<arc_i32, WireFormatLite::TYPE_SFIXED32>( + const uint8_t* buffer, arc_i32* value) { + arc_ui32 temp; + buffer = io::CodedInputStream::ReadLittleEndian32FromArray(buffer, &temp); + *value = static_cast<arc_i32>(temp); + return buffer; +} +template <> +inline const uint8_t* +WireFormatLite::ReadPrimitiveFromArray<arc_i64, WireFormatLite::TYPE_SFIXED64>( + const uint8_t* buffer, arc_i64* value) { + arc_ui64 temp; + buffer = io::CodedInputStream::ReadLittleEndian64FromArray(buffer, &temp); + *value = static_cast<arc_i64>(temp); + return buffer; +} +template <> +inline const uint8_t* +WireFormatLite::ReadPrimitiveFromArray<float, WireFormatLite::TYPE_FLOAT>( + const uint8_t* buffer, float* value) { + arc_ui32 temp; + buffer = io::CodedInputStream::ReadLittleEndian32FromArray(buffer, &temp); + *value = DecodeFloat(temp); + return buffer; +} +template <> +inline const uint8_t* +WireFormatLite::ReadPrimitiveFromArray<double, WireFormatLite::TYPE_DOUBLE>( + const uint8_t* buffer, double* value) { + arc_ui64 temp; + buffer = io::CodedInputStream::ReadLittleEndian64FromArray(buffer, &temp); + *value = DecodeDouble(temp); + return buffer; +} + +template <typename CType, enum WireFormatLite::FieldType DeclaredType> +inline bool WireFormatLite::ReadRepeatedPrimitive( + int, // tag_size, unused. + arc_ui32 tag, io::CodedInputStream* input, RepeatedField<CType>* values) { + CType value; + if (!ReadPrimitive<CType, DeclaredType>(input, &value)) return false; + values->Add(value); + int elements_already_reserved = values->Capacity() - values->size(); + while (elements_already_reserved > 0 && input->ExpectTag(tag)) { + if (!ReadPrimitive<CType, DeclaredType>(input, &value)) return false; + values->AddAlreadyReserved(value); + elements_already_reserved--; + } + return true; +} + +template <typename CType, enum WireFormatLite::FieldType DeclaredType> +inline bool WireFormatLite::ReadRepeatedFixedSizePrimitive( + int tag_size, arc_ui32 tag, io::CodedInputStream* input, + RepeatedField<CType>* values) { + GOOGLE_DCHECK_EQ(UInt32Size(tag), static_cast<size_t>(tag_size)); + CType value; + if (!ReadPrimitive<CType, DeclaredType>(input, &value)) return false; + values->Add(value); + + // For fixed size values, repeated values can be read more quickly by + // reading directly from a raw array. + // + // We can get a tight loop by only reading as many elements as can be + // added to the RepeatedField without having to do any resizing. Additionally, + // we only try to read as many elements as are available from the current + // buffer space. Doing so avoids having to perform boundary checks when + // reading the value: the maximum number of elements that can be read is + // known outside of the loop. + const void* void_pointer; + int size; + input->GetDirectBufferPointerInline(&void_pointer, &size); + if (size > 0) { + const uint8_t* buffer = reinterpret_cast<const uint8_t*>(void_pointer); + // The number of bytes each type occupies on the wire. + const int per_value_size = tag_size + static_cast<int>(sizeof(value)); + + // parentheses around (std::min) prevents macro expansion of min(...) + int elements_available = + (std::min)(values->Capacity() - values->size(), size / per_value_size); + int num_read = 0; + while (num_read < elements_available && + (buffer = io::CodedInputStream::ExpectTagFromArray(buffer, tag)) != + nullptr) { + buffer = ReadPrimitiveFromArray<CType, DeclaredType>(buffer, &value); + values->AddAlreadyReserved(value); + ++num_read; + } + const int read_bytes = num_read * per_value_size; + if (read_bytes > 0) { + input->Skip(read_bytes); + } + } + return true; +} + +// Specializations of ReadRepeatedPrimitive for the fixed size types, which use +// the optimized code path. +#define READ_REPEATED_FIXED_SIZE_PRIMITIVE(CPPTYPE, DECLARED_TYPE) \ + template <> \ + inline bool WireFormatLite::ReadRepeatedPrimitive< \ + CPPTYPE, WireFormatLite::DECLARED_TYPE>( \ + int tag_size, arc_ui32 tag, io::CodedInputStream* input, \ + RepeatedField<CPPTYPE>* values) { \ + return ReadRepeatedFixedSizePrimitive<CPPTYPE, \ + WireFormatLite::DECLARED_TYPE>( \ + tag_size, tag, input, values); \ + } + +READ_REPEATED_FIXED_SIZE_PRIMITIVE(arc_ui32, TYPE_FIXED32) +READ_REPEATED_FIXED_SIZE_PRIMITIVE(arc_ui64, TYPE_FIXED64) +READ_REPEATED_FIXED_SIZE_PRIMITIVE(arc_i32, TYPE_SFIXED32) +READ_REPEATED_FIXED_SIZE_PRIMITIVE(arc_i64, TYPE_SFIXED64) +READ_REPEATED_FIXED_SIZE_PRIMITIVE(float, TYPE_FLOAT) +READ_REPEATED_FIXED_SIZE_PRIMITIVE(double, TYPE_DOUBLE) + +#undef READ_REPEATED_FIXED_SIZE_PRIMITIVE + +template <typename CType, enum WireFormatLite::FieldType DeclaredType> +bool WireFormatLite::ReadRepeatedPrimitiveNoInline( + int tag_size, arc_ui32 tag, io::CodedInputStream* input, + RepeatedField<CType>* value) { + return ReadRepeatedPrimitive<CType, DeclaredType>(tag_size, tag, input, + value); +} + +template <typename CType, enum WireFormatLite::FieldType DeclaredType> +inline bool WireFormatLite::ReadPackedPrimitive(io::CodedInputStream* input, + RepeatedField<CType>* values) { + int length; + if (!input->ReadVarintSizeAsInt(&length)) return false; + io::CodedInputStream::Limit limit = input->PushLimit(length); + while (input->BytesUntilLimit() > 0) { + CType value; + if (!ReadPrimitive<CType, DeclaredType>(input, &value)) return false; + values->Add(value); + } + input->PopLimit(limit); + return true; +} + +template <typename CType, enum WireFormatLite::FieldType DeclaredType> +inline bool WireFormatLite::ReadPackedFixedSizePrimitive( + io::CodedInputStream* input, RepeatedField<CType>* values) { + int length; + if (!input->ReadVarintSizeAsInt(&length)) return false; + const int old_entries = values->size(); + const int new_entries = length / static_cast<int>(sizeof(CType)); + const int new_bytes = new_entries * static_cast<int>(sizeof(CType)); + if (new_bytes != length) return false; + // We would *like* to pre-allocate the buffer to write into (for + // speed), but *must* avoid performing a very large allocation due + // to a malicious user-supplied "length" above. So we have a fast + // path that pre-allocates when the "length" is less than a bound. + // We determine the bound by calling BytesUntilTotalBytesLimit() and + // BytesUntilLimit(). These return -1 to mean "no limit set". + // There are four cases: + // TotalBytesLimit Limit + // -1 -1 Use slow path. + // -1 >= 0 Use fast path if length <= Limit. + // >= 0 -1 Use slow path. + // >= 0 >= 0 Use fast path if length <= min(both limits). + arc_i64 bytes_limit = input->BytesUntilTotalBytesLimit(); + if (bytes_limit == -1) { + bytes_limit = input->BytesUntilLimit(); + } else { + // parentheses around (std::min) prevents macro expansion of min(...) + bytes_limit = + (std::min)(bytes_limit, static_cast<arc_i64>(input->BytesUntilLimit())); + } + if (bytes_limit >= new_bytes) { + // Fast-path that pre-allocates *values to the final size. +#if defined(PROTOBUF_LITTLE_ENDIAN) + values->Resize(old_entries + new_entries, 0); + // values->mutable_data() may change after Resize(), so do this after: + void* dest = reinterpret_cast<void*>(values->mutable_data() + old_entries); + if (!input->ReadRaw(dest, new_bytes)) { + values->Truncate(old_entries); + return false; + } +#else + values->Reserve(old_entries + new_entries); + CType value; + for (int i = 0; i < new_entries; ++i) { + if (!ReadPrimitive<CType, DeclaredType>(input, &value)) return false; + values->AddAlreadyReserved(value); + } +#endif + } else { + // This is the slow-path case where "length" may be too large to + // safely allocate. We read as much as we can into *values + // without pre-allocating "length" bytes. + CType value; + for (int i = 0; i < new_entries; ++i) { + if (!ReadPrimitive<CType, DeclaredType>(input, &value)) return false; + values->Add(value); + } + } + return true; +} + +// Specializations of ReadPackedPrimitive for the fixed size types, which use +// an optimized code path. +#define READ_REPEATED_PACKED_FIXED_SIZE_PRIMITIVE(CPPTYPE, DECLARED_TYPE) \ + template <> \ + inline bool \ + WireFormatLite::ReadPackedPrimitive<CPPTYPE, WireFormatLite::DECLARED_TYPE>( \ + io::CodedInputStream * input, RepeatedField<CPPTYPE> * values) { \ + return ReadPackedFixedSizePrimitive<CPPTYPE, \ + WireFormatLite::DECLARED_TYPE>( \ + input, values); \ + } + +READ_REPEATED_PACKED_FIXED_SIZE_PRIMITIVE(arc_ui32, TYPE_FIXED32) +READ_REPEATED_PACKED_FIXED_SIZE_PRIMITIVE(arc_ui64, TYPE_FIXED64) +READ_REPEATED_PACKED_FIXED_SIZE_PRIMITIVE(arc_i32, TYPE_SFIXED32) +READ_REPEATED_PACKED_FIXED_SIZE_PRIMITIVE(arc_i64, TYPE_SFIXED64) +READ_REPEATED_PACKED_FIXED_SIZE_PRIMITIVE(float, TYPE_FLOAT) +READ_REPEATED_PACKED_FIXED_SIZE_PRIMITIVE(double, TYPE_DOUBLE) + +#undef READ_REPEATED_PACKED_FIXED_SIZE_PRIMITIVE + +template <typename CType, enum WireFormatLite::FieldType DeclaredType> +bool WireFormatLite::ReadPackedPrimitiveNoInline(io::CodedInputStream* input, + RepeatedField<CType>* values) { + return ReadPackedPrimitive<CType, DeclaredType>(input, values); +} + + +template <typename MessageType> +inline bool WireFormatLite::ReadGroup(int field_number, + io::CodedInputStream* input, + MessageType* value) { + if (!input->IncrementRecursionDepth()) return false; + if (!value->MergePartialFromCodedStream(input)) return false; + input->UnsafeDecrementRecursionDepth(); + // Make sure the last thing read was an end tag for this group. + if (!input->LastTagWas(MakeTag(field_number, WIRETYPE_END_GROUP))) { + return false; + } + return true; +} +template <typename MessageType> +inline bool WireFormatLite::ReadMessage(io::CodedInputStream* input, + MessageType* value) { + int length; + if (!input->ReadVarintSizeAsInt(&length)) return false; + std::pair<io::CodedInputStream::Limit, int> p = + input->IncrementRecursionDepthAndPushLimit(length); + if (p.second < 0 || !value->MergePartialFromCodedStream(input)) return false; + // Make sure that parsing stopped when the limit was hit, not at an endgroup + // tag. + return input->DecrementRecursionDepthAndPopLimit(p.first); +} + +// =================================================================== + +inline void WireFormatLite::WriteTag(int field_number, WireType type, + io::CodedOutputStream* output) { + output->WriteTag(MakeTag(field_number, type)); +} + +inline void WireFormatLite::WriteInt32NoTag(arc_i32 value, + io::CodedOutputStream* output) { + output->WriteVarint32SignExtended(value); +} +inline void WireFormatLite::WriteInt64NoTag(arc_i64 value, + io::CodedOutputStream* output) { + output->WriteVarint64(static_cast<arc_ui64>(value)); +} +inline void WireFormatLite::WriteUInt32NoTag(arc_ui32 value, + io::CodedOutputStream* output) { + output->WriteVarint32(value); +} +inline void WireFormatLite::WriteUInt64NoTag(arc_ui64 value, + io::CodedOutputStream* output) { + output->WriteVarint64(value); +} +inline void WireFormatLite::WriteSInt32NoTag(arc_i32 value, + io::CodedOutputStream* output) { + output->WriteVarint32(ZigZagEncode32(value)); +} +inline void WireFormatLite::WriteSInt64NoTag(arc_i64 value, + io::CodedOutputStream* output) { + output->WriteVarint64(ZigZagEncode64(value)); +} +inline void WireFormatLite::WriteFixed32NoTag(arc_ui32 value, + io::CodedOutputStream* output) { + output->WriteLittleEndian32(value); +} +inline void WireFormatLite::WriteFixed64NoTag(arc_ui64 value, + io::CodedOutputStream* output) { + output->WriteLittleEndian64(value); +} +inline void WireFormatLite::WriteSFixed32NoTag(arc_i32 value, + io::CodedOutputStream* output) { + output->WriteLittleEndian32(static_cast<arc_ui32>(value)); +} +inline void WireFormatLite::WriteSFixed64NoTag(arc_i64 value, + io::CodedOutputStream* output) { + output->WriteLittleEndian64(static_cast<arc_ui64>(value)); +} +inline void WireFormatLite::WriteFloatNoTag(float value, + io::CodedOutputStream* output) { + output->WriteLittleEndian32(EncodeFloat(value)); +} +inline void WireFormatLite::WriteDoubleNoTag(double value, + io::CodedOutputStream* output) { + output->WriteLittleEndian64(EncodeDouble(value)); +} +inline void WireFormatLite::WriteBoolNoTag(bool value, + io::CodedOutputStream* output) { + output->WriteVarint32(value ? 1 : 0); +} +inline void WireFormatLite::WriteEnumNoTag(int value, + io::CodedOutputStream* output) { + output->WriteVarint32SignExtended(value); +} + +// See comment on ReadGroupNoVirtual to understand the need for this template +// parameter name. +template <typename MessageType_WorkAroundCppLookupDefect> +inline void WireFormatLite::WriteGroupNoVirtual( + int field_number, const MessageType_WorkAroundCppLookupDefect& value, + io::CodedOutputStream* output) { + WriteTag(field_number, WIRETYPE_START_GROUP, output); + value.MessageType_WorkAroundCppLookupDefect::SerializeWithCachedSizes(output); + WriteTag(field_number, WIRETYPE_END_GROUP, output); +} +template <typename MessageType_WorkAroundCppLookupDefect> +inline void WireFormatLite::WriteMessageNoVirtual( + int field_number, const MessageType_WorkAroundCppLookupDefect& value, + io::CodedOutputStream* output) { + WriteTag(field_number, WIRETYPE_LENGTH_DELIMITED, output); + output->WriteVarint32( + value.MessageType_WorkAroundCppLookupDefect::GetCachedSize()); + value.MessageType_WorkAroundCppLookupDefect::SerializeWithCachedSizes(output); +} + +// =================================================================== + +inline uint8_t* WireFormatLite::WriteTagToArray(int field_number, WireType type, + uint8_t* target) { + return io::CodedOutputStream::WriteTagToArray(MakeTag(field_number, type), + target); +} + +inline uint8_t* WireFormatLite::WriteInt32NoTagToArray(arc_i32 value, + uint8_t* target) { + return io::CodedOutputStream::WriteVarint32SignExtendedToArray(value, target); +} +inline uint8_t* WireFormatLite::WriteInt64NoTagToArray(arc_i64 value, + uint8_t* target) { + return io::CodedOutputStream::WriteVarint64ToArray( + static_cast<arc_ui64>(value), target); +} +inline uint8_t* WireFormatLite::WriteUInt32NoTagToArray(arc_ui32 value, + uint8_t* target) { + return io::CodedOutputStream::WriteVarint32ToArray(value, target); +} +inline uint8_t* WireFormatLite::WriteUInt64NoTagToArray(arc_ui64 value, + uint8_t* target) { + return io::CodedOutputStream::WriteVarint64ToArray(value, target); +} +inline uint8_t* WireFormatLite::WriteSInt32NoTagToArray(arc_i32 value, + uint8_t* target) { + return io::CodedOutputStream::WriteVarint32ToArray(ZigZagEncode32(value), + target); +} +inline uint8_t* WireFormatLite::WriteSInt64NoTagToArray(arc_i64 value, + uint8_t* target) { + return io::CodedOutputStream::WriteVarint64ToArray(ZigZagEncode64(value), + target); +} +inline uint8_t* WireFormatLite::WriteFixed32NoTagToArray(arc_ui32 value, + uint8_t* target) { + return io::CodedOutputStream::WriteLittleEndian32ToArray(value, target); +} +inline uint8_t* WireFormatLite::WriteFixed64NoTagToArray(arc_ui64 value, + uint8_t* target) { + return io::CodedOutputStream::WriteLittleEndian64ToArray(value, target); +} +inline uint8_t* WireFormatLite::WriteSFixed32NoTagToArray(arc_i32 value, + uint8_t* target) { + return io::CodedOutputStream::WriteLittleEndian32ToArray( + static_cast<arc_ui32>(value), target); +} +inline uint8_t* WireFormatLite::WriteSFixed64NoTagToArray(arc_i64 value, + uint8_t* target) { + return io::CodedOutputStream::WriteLittleEndian64ToArray( + static_cast<arc_ui64>(value), target); +} +inline uint8_t* WireFormatLite::WriteFloatNoTagToArray(float value, + uint8_t* target) { + return io::CodedOutputStream::WriteLittleEndian32ToArray(EncodeFloat(value), + target); +} +inline uint8_t* WireFormatLite::WriteDoubleNoTagToArray(double value, + uint8_t* target) { + return io::CodedOutputStream::WriteLittleEndian64ToArray(EncodeDouble(value), + target); +} +inline uint8_t* WireFormatLite::WriteBoolNoTagToArray(bool value, + uint8_t* target) { + return io::CodedOutputStream::WriteVarint32ToArray(value ? 1 : 0, target); +} +inline uint8_t* WireFormatLite::WriteEnumNoTagToArray(int value, + uint8_t* target) { + return io::CodedOutputStream::WriteVarint32SignExtendedToArray(value, target); +} + +template <typename T> +inline uint8_t* WireFormatLite::WritePrimitiveNoTagToArray( + const RepeatedField<T>& value, uint8_t* (*Writer)(T, uint8_t*), + uint8_t* target) { + const int n = value.size(); + GOOGLE_DCHECK_GT(n, 0); + + const T* ii = value.data(); + int i = 0; + do { + target = Writer(ii[i], target); + } while (++i < n); + + return target; +} + +template <typename T> +inline uint8_t* WireFormatLite::WriteFixedNoTagToArray( + const RepeatedField<T>& value, uint8_t* (*Writer)(T, uint8_t*), + uint8_t* target) { +#if defined(PROTOBUF_LITTLE_ENDIAN) + (void)Writer; + + const int n = value.size(); + GOOGLE_DCHECK_GT(n, 0); + + const T* ii = value.data(); + const int bytes = n * static_cast<int>(sizeof(ii[0])); + memcpy(target, ii, static_cast<size_t>(bytes)); + return target + bytes; +#else + return WritePrimitiveNoTagToArray(value, Writer, target); +#endif +} + +inline uint8_t* WireFormatLite::WriteInt32NoTagToArray( + const RepeatedField<arc_i32>& value, uint8_t* target) { + return WritePrimitiveNoTagToArray(value, WriteInt32NoTagToArray, target); +} +inline uint8_t* WireFormatLite::WriteInt64NoTagToArray( + const RepeatedField<arc_i64>& value, uint8_t* target) { + return WritePrimitiveNoTagToArray(value, WriteInt64NoTagToArray, target); +} +inline uint8_t* WireFormatLite::WriteUInt32NoTagToArray( + const RepeatedField<arc_ui32>& value, uint8_t* target) { + return WritePrimitiveNoTagToArray(value, WriteUInt32NoTagToArray, target); +} +inline uint8_t* WireFormatLite::WriteUInt64NoTagToArray( + const RepeatedField<arc_ui64>& value, uint8_t* target) { + return WritePrimitiveNoTagToArray(value, WriteUInt64NoTagToArray, target); +} +inline uint8_t* WireFormatLite::WriteSInt32NoTagToArray( + const RepeatedField<arc_i32>& value, uint8_t* target) { + return WritePrimitiveNoTagToArray(value, WriteSInt32NoTagToArray, target); +} +inline uint8_t* WireFormatLite::WriteSInt64NoTagToArray( + const RepeatedField<arc_i64>& value, uint8_t* target) { + return WritePrimitiveNoTagToArray(value, WriteSInt64NoTagToArray, target); +} +inline uint8_t* WireFormatLite::WriteFixed32NoTagToArray( + const RepeatedField<arc_ui32>& value, uint8_t* target) { + return WriteFixedNoTagToArray(value, WriteFixed32NoTagToArray, target); +} +inline uint8_t* WireFormatLite::WriteFixed64NoTagToArray( + const RepeatedField<arc_ui64>& value, uint8_t* target) { + return WriteFixedNoTagToArray(value, WriteFixed64NoTagToArray, target); +} +inline uint8_t* WireFormatLite::WriteSFixed32NoTagToArray( + const RepeatedField<arc_i32>& value, uint8_t* target) { + return WriteFixedNoTagToArray(value, WriteSFixed32NoTagToArray, target); +} +inline uint8_t* WireFormatLite::WriteSFixed64NoTagToArray( + const RepeatedField<arc_i64>& value, uint8_t* target) { + return WriteFixedNoTagToArray(value, WriteSFixed64NoTagToArray, target); +} +inline uint8_t* WireFormatLite::WriteFloatNoTagToArray( + const RepeatedField<float>& value, uint8_t* target) { + return WriteFixedNoTagToArray(value, WriteFloatNoTagToArray, target); +} +inline uint8_t* WireFormatLite::WriteDoubleNoTagToArray( + const RepeatedField<double>& value, uint8_t* target) { + return WriteFixedNoTagToArray(value, WriteDoubleNoTagToArray, target); +} +inline uint8_t* WireFormatLite::WriteBoolNoTagToArray( + const RepeatedField<bool>& value, uint8_t* target) { + return WritePrimitiveNoTagToArray(value, WriteBoolNoTagToArray, target); +} +inline uint8_t* WireFormatLite::WriteEnumNoTagToArray( + const RepeatedField<int>& value, uint8_t* target) { + return WritePrimitiveNoTagToArray(value, WriteEnumNoTagToArray, target); +} + +inline uint8_t* WireFormatLite::WriteInt32ToArray(int field_number, + arc_i32 value, + uint8_t* target) { + target = WriteTagToArray(field_number, WIRETYPE_VARINT, target); + return WriteInt32NoTagToArray(value, target); +} +inline uint8_t* WireFormatLite::WriteInt64ToArray(int field_number, + arc_i64 value, + uint8_t* target) { + target = WriteTagToArray(field_number, WIRETYPE_VARINT, target); + return WriteInt64NoTagToArray(value, target); +} +inline uint8_t* WireFormatLite::WriteUInt32ToArray(int field_number, + arc_ui32 value, + uint8_t* target) { + target = WriteTagToArray(field_number, WIRETYPE_VARINT, target); + return WriteUInt32NoTagToArray(value, target); +} +inline uint8_t* WireFormatLite::WriteUInt64ToArray(int field_number, + arc_ui64 value, + uint8_t* target) { + target = WriteTagToArray(field_number, WIRETYPE_VARINT, target); + return WriteUInt64NoTagToArray(value, target); +} +inline uint8_t* WireFormatLite::WriteSInt32ToArray(int field_number, + arc_i32 value, + uint8_t* target) { + target = WriteTagToArray(field_number, WIRETYPE_VARINT, target); + return WriteSInt32NoTagToArray(value, target); +} +inline uint8_t* WireFormatLite::WriteSInt64ToArray(int field_number, + arc_i64 value, + uint8_t* target) { + target = WriteTagToArray(field_number, WIRETYPE_VARINT, target); + return WriteSInt64NoTagToArray(value, target); +} +inline uint8_t* WireFormatLite::WriteFixed32ToArray(int field_number, + arc_ui32 value, + uint8_t* target) { + target = WriteTagToArray(field_number, WIRETYPE_FIXED32, target); + return WriteFixed32NoTagToArray(value, target); +} +inline uint8_t* WireFormatLite::WriteFixed64ToArray(int field_number, + arc_ui64 value, + uint8_t* target) { + target = WriteTagToArray(field_number, WIRETYPE_FIXED64, target); + return WriteFixed64NoTagToArray(value, target); +} +inline uint8_t* WireFormatLite::WriteSFixed32ToArray(int field_number, + arc_i32 value, + uint8_t* target) { + target = WriteTagToArray(field_number, WIRETYPE_FIXED32, target); + return WriteSFixed32NoTagToArray(value, target); +} +inline uint8_t* WireFormatLite::WriteSFixed64ToArray(int field_number, + arc_i64 value, + uint8_t* target) { + target = WriteTagToArray(field_number, WIRETYPE_FIXED64, target); + return WriteSFixed64NoTagToArray(value, target); +} +inline uint8_t* WireFormatLite::WriteFloatToArray(int field_number, float value, + uint8_t* target) { + target = WriteTagToArray(field_number, WIRETYPE_FIXED32, target); + return WriteFloatNoTagToArray(value, target); +} +inline uint8_t* WireFormatLite::WriteDoubleToArray(int field_number, + double value, + uint8_t* target) { + target = WriteTagToArray(field_number, WIRETYPE_FIXED64, target); + return WriteDoubleNoTagToArray(value, target); +} +inline uint8_t* WireFormatLite::WriteBoolToArray(int field_number, bool value, + uint8_t* target) { + target = WriteTagToArray(field_number, WIRETYPE_VARINT, target); + return WriteBoolNoTagToArray(value, target); +} +inline uint8_t* WireFormatLite::WriteEnumToArray(int field_number, int value, + uint8_t* target) { + target = WriteTagToArray(field_number, WIRETYPE_VARINT, target); + return WriteEnumNoTagToArray(value, target); +} + +template <typename T> +inline uint8_t* WireFormatLite::WritePrimitiveToArray( + int field_number, const RepeatedField<T>& value, + uint8_t* (*Writer)(int, T, uint8_t*), uint8_t* target) { + const int n = value.size(); + if (n == 0) { + return target; + } + + const T* ii = value.data(); + int i = 0; + do { + target = Writer(field_number, ii[i], target); + } while (++i < n); + + return target; +} + +inline uint8_t* WireFormatLite::WriteInt32ToArray( + int field_number, const RepeatedField<arc_i32>& value, uint8_t* target) { + return WritePrimitiveToArray(field_number, value, WriteInt32ToArray, target); +} +inline uint8_t* WireFormatLite::WriteInt64ToArray( + int field_number, const RepeatedField<arc_i64>& value, uint8_t* target) { + return WritePrimitiveToArray(field_number, value, WriteInt64ToArray, target); +} +inline uint8_t* WireFormatLite::WriteUInt32ToArray( + int field_number, const RepeatedField<arc_ui32>& value, uint8_t* target) { + return WritePrimitiveToArray(field_number, value, WriteUInt32ToArray, target); +} +inline uint8_t* WireFormatLite::WriteUInt64ToArray( + int field_number, const RepeatedField<arc_ui64>& value, uint8_t* target) { + return WritePrimitiveToArray(field_number, value, WriteUInt64ToArray, target); +} +inline uint8_t* WireFormatLite::WriteSInt32ToArray( + int field_number, const RepeatedField<arc_i32>& value, uint8_t* target) { + return WritePrimitiveToArray(field_number, value, WriteSInt32ToArray, target); +} +inline uint8_t* WireFormatLite::WriteSInt64ToArray( + int field_number, const RepeatedField<arc_i64>& value, uint8_t* target) { + return WritePrimitiveToArray(field_number, value, WriteSInt64ToArray, target); +} +inline uint8_t* WireFormatLite::WriteFixed32ToArray( + int field_number, const RepeatedField<arc_ui32>& value, uint8_t* target) { + return WritePrimitiveToArray(field_number, value, WriteFixed32ToArray, + target); +} +inline uint8_t* WireFormatLite::WriteFixed64ToArray( + int field_number, const RepeatedField<arc_ui64>& value, uint8_t* target) { + return WritePrimitiveToArray(field_number, value, WriteFixed64ToArray, + target); +} +inline uint8_t* WireFormatLite::WriteSFixed32ToArray( + int field_number, const RepeatedField<arc_i32>& value, uint8_t* target) { + return WritePrimitiveToArray(field_number, value, WriteSFixed32ToArray, + target); +} +inline uint8_t* WireFormatLite::WriteSFixed64ToArray( + int field_number, const RepeatedField<arc_i64>& value, uint8_t* target) { + return WritePrimitiveToArray(field_number, value, WriteSFixed64ToArray, + target); +} +inline uint8_t* WireFormatLite::WriteFloatToArray( + int field_number, const RepeatedField<float>& value, uint8_t* target) { + return WritePrimitiveToArray(field_number, value, WriteFloatToArray, target); +} +inline uint8_t* WireFormatLite::WriteDoubleToArray( + int field_number, const RepeatedField<double>& value, uint8_t* target) { + return WritePrimitiveToArray(field_number, value, WriteDoubleToArray, target); +} +inline uint8_t* WireFormatLite::WriteBoolToArray( + int field_number, const RepeatedField<bool>& value, uint8_t* target) { + return WritePrimitiveToArray(field_number, value, WriteBoolToArray, target); +} +inline uint8_t* WireFormatLite::WriteEnumToArray( + int field_number, const RepeatedField<int>& value, uint8_t* target) { + return WritePrimitiveToArray(field_number, value, WriteEnumToArray, target); +} +inline uint8_t* WireFormatLite::WriteStringToArray(int field_number, + const TProtoStringType& value, + uint8_t* target) { + // String is for UTF-8 text only + // WARNING: In wire_format.cc, both strings and bytes are handled by + // WriteString() to avoid code duplication. If the implementations become + // different, you will need to update that usage. + target = WriteTagToArray(field_number, WIRETYPE_LENGTH_DELIMITED, target); + return io::CodedOutputStream::WriteStringWithSizeToArray(value, target); +} +inline uint8_t* WireFormatLite::WriteBytesToArray(int field_number, + const TProtoStringType& value, + uint8_t* target) { + target = WriteTagToArray(field_number, WIRETYPE_LENGTH_DELIMITED, target); + return io::CodedOutputStream::WriteStringWithSizeToArray(value, target); +} + + +template <typename MessageType> +inline uint8_t* WireFormatLite::InternalWriteGroup( + int field_number, const MessageType& value, uint8_t* target, + io::EpsCopyOutputStream* stream) { + target = WriteTagToArray(field_number, WIRETYPE_START_GROUP, target); + target = value._InternalSerialize(target, stream); + target = stream->EnsureSpace(target); + return WriteTagToArray(field_number, WIRETYPE_END_GROUP, target); +} +template <typename MessageType> +inline uint8_t* WireFormatLite::InternalWriteMessage( + int field_number, const MessageType& value, uint8_t* target, + io::EpsCopyOutputStream* stream) { + target = WriteTagToArray(field_number, WIRETYPE_LENGTH_DELIMITED, target); + target = io::CodedOutputStream::WriteVarint32ToArrayOutOfLine( + static_cast<arc_ui32>(value.GetCachedSize()), target); + return value._InternalSerialize(target, stream); +} + +// See comment on ReadGroupNoVirtual to understand the need for this template +// parameter name. +template <typename MessageType_WorkAroundCppLookupDefect> +inline uint8_t* WireFormatLite::InternalWriteGroupNoVirtualToArray( + int field_number, const MessageType_WorkAroundCppLookupDefect& value, + uint8_t* target) { + target = WriteTagToArray(field_number, WIRETYPE_START_GROUP, target); + target = value.MessageType_WorkAroundCppLookupDefect:: + SerializeWithCachedSizesToArray(target); + return WriteTagToArray(field_number, WIRETYPE_END_GROUP, target); +} +template <typename MessageType_WorkAroundCppLookupDefect> +inline uint8_t* WireFormatLite::InternalWriteMessageNoVirtualToArray( + int field_number, const MessageType_WorkAroundCppLookupDefect& value, + uint8_t* target) { + target = WriteTagToArray(field_number, WIRETYPE_LENGTH_DELIMITED, target); + target = io::CodedOutputStream::WriteVarint32ToArray( + static_cast<arc_ui32>( + value.MessageType_WorkAroundCppLookupDefect::GetCachedSize()), + target); + return value + .MessageType_WorkAroundCppLookupDefect::SerializeWithCachedSizesToArray( + target); +} + +// =================================================================== + +inline size_t WireFormatLite::Int32Size(arc_i32 value) { + return io::CodedOutputStream::VarintSize32SignExtended(value); +} +inline size_t WireFormatLite::Int64Size(arc_i64 value) { + return io::CodedOutputStream::VarintSize64(static_cast<arc_ui64>(value)); +} +inline size_t WireFormatLite::UInt32Size(arc_ui32 value) { + return io::CodedOutputStream::VarintSize32(value); +} +inline size_t WireFormatLite::UInt64Size(arc_ui64 value) { + return io::CodedOutputStream::VarintSize64(value); +} +inline size_t WireFormatLite::SInt32Size(arc_i32 value) { + return io::CodedOutputStream::VarintSize32(ZigZagEncode32(value)); +} +inline size_t WireFormatLite::SInt64Size(arc_i64 value) { + return io::CodedOutputStream::VarintSize64(ZigZagEncode64(value)); +} +inline size_t WireFormatLite::EnumSize(int value) { + return io::CodedOutputStream::VarintSize32SignExtended(value); +} +inline size_t WireFormatLite::Int32SizePlusOne(arc_i32 value) { + return io::CodedOutputStream::VarintSize32SignExtendedPlusOne(value); +} +inline size_t WireFormatLite::Int64SizePlusOne(arc_i64 value) { + return io::CodedOutputStream::VarintSize64PlusOne( + static_cast<arc_ui64>(value)); +} +inline size_t WireFormatLite::UInt32SizePlusOne(arc_ui32 value) { + return io::CodedOutputStream::VarintSize32PlusOne(value); +} +inline size_t WireFormatLite::UInt64SizePlusOne(arc_ui64 value) { + return io::CodedOutputStream::VarintSize64PlusOne(value); +} +inline size_t WireFormatLite::SInt32SizePlusOne(arc_i32 value) { + return io::CodedOutputStream::VarintSize32PlusOne(ZigZagEncode32(value)); +} +inline size_t WireFormatLite::SInt64SizePlusOne(arc_i64 value) { + return io::CodedOutputStream::VarintSize64PlusOne(ZigZagEncode64(value)); +} +inline size_t WireFormatLite::EnumSizePlusOne(int value) { + return io::CodedOutputStream::VarintSize32SignExtendedPlusOne(value); +} + +inline size_t WireFormatLite::StringSize(const TProtoStringType& value) { + return LengthDelimitedSize(value.size()); +} +inline size_t WireFormatLite::BytesSize(const TProtoStringType& value) { + return LengthDelimitedSize(value.size()); +} + + +template <typename MessageType> +inline size_t WireFormatLite::GroupSize(const MessageType& value) { + return value.ByteSizeLong(); +} +template <typename MessageType> +inline size_t WireFormatLite::MessageSize(const MessageType& value) { + return LengthDelimitedSize(value.ByteSizeLong()); +} + +// See comment on ReadGroupNoVirtual to understand the need for this template +// parameter name. +template <typename MessageType_WorkAroundCppLookupDefect> +inline size_t WireFormatLite::GroupSizeNoVirtual( + const MessageType_WorkAroundCppLookupDefect& value) { + return value.MessageType_WorkAroundCppLookupDefect::ByteSizeLong(); +} +template <typename MessageType_WorkAroundCppLookupDefect> +inline size_t WireFormatLite::MessageSizeNoVirtual( + const MessageType_WorkAroundCppLookupDefect& value) { + return LengthDelimitedSize( + value.MessageType_WorkAroundCppLookupDefect::ByteSizeLong()); +} + +inline size_t WireFormatLite::LengthDelimitedSize(size_t length) { + // The static_cast here prevents an error in certain compiler configurations + // but is not technically correct--if length is too large to fit in a arc_ui32 + // then it will be silently truncated. We will need to fix this if we ever + // decide to start supporting serialized messages greater than 2 GiB in size. + return length + + io::CodedOutputStream::VarintSize32(static_cast<arc_ui32>(length)); +} + +template <typename MS> +bool ParseMessageSetItemImpl(io::CodedInputStream* input, MS ms) { + // This method parses a group which should contain two fields: + // required int32 type_id = 2; + // required data message = 3; + + arc_ui32 last_type_id = 0; + + // If we see message data before the type_id, we'll append it to this so + // we can parse it later. + TProtoStringType message_data; + + while (true) { + const arc_ui32 tag = input->ReadTagNoLastTag(); + if (tag == 0) return false; + + switch (tag) { + case WireFormatLite::kMessageSetTypeIdTag: { + arc_ui32 type_id; + if (!input->ReadVarint32(&type_id)) return false; + last_type_id = type_id; + + if (!message_data.empty()) { + // We saw some message data before the type_id. Have to parse it + // now. + io::CodedInputStream sub_input( + reinterpret_cast<const uint8_t*>(message_data.data()), + static_cast<int>(message_data.size())); + sub_input.SetRecursionLimit(input->RecursionBudget()); + if (!ms.ParseField(last_type_id, &sub_input)) { + return false; + } + message_data.clear(); + } + + break; + } + + case WireFormatLite::kMessageSetMessageTag: { + if (last_type_id == 0) { + // We haven't seen a type_id yet. Append this data to message_data. + arc_ui32 length; + if (!input->ReadVarint32(&length)) return false; + if (static_cast<arc_i32>(length) < 0) return false; + arc_ui32 size = static_cast<arc_ui32>( + length + io::CodedOutputStream::VarintSize32(length)); + message_data.resize(size); + auto ptr = reinterpret_cast<uint8_t*>(&message_data[0]); + ptr = io::CodedOutputStream::WriteVarint32ToArray(length, ptr); + if (!input->ReadRaw(ptr, length)) return false; + } else { + // Already saw type_id, so we can parse this directly. + if (!ms.ParseField(last_type_id, input)) { + return false; + } + } + + break; + } + + case WireFormatLite::kMessageSetItemEndTag: { + return true; + } + + default: { + if (!ms.SkipField(tag, input)) return false; + } + } + } +} + +} // namespace internal +} // namespace protobuf +} // namespace google + +#include <google/protobuf/port_undef.inc> + +#endif // GOOGLE_PROTOBUF_WIRE_FORMAT_LITE_H__ diff --git a/contrib/libs/protobuf_old/src/google/protobuf/wrappers.pb.cc b/contrib/libs/protobuf_old/src/google/protobuf/wrappers.pb.cc new file mode 100644 index 0000000000..eee38e9b8a --- /dev/null +++ b/contrib/libs/protobuf_old/src/google/protobuf/wrappers.pb.cc @@ -0,0 +1,1955 @@ +// Generated by the protocol buffer compiler. DO NOT EDIT! +// source: google/protobuf/wrappers.proto + +#include <google/protobuf/wrappers.pb.h> + +#include <algorithm> + +#include <google/protobuf/io/coded_stream.h> +#include <google/protobuf/extension_set.h> +#include <google/protobuf/wire_format_lite.h> +#include <google/protobuf/descriptor.h> +#include <google/protobuf/generated_message_reflection.h> +#include <google/protobuf/reflection_ops.h> +#include <google/protobuf/wire_format.h> +// @@protoc_insertion_point(includes) +#include <google/protobuf/port_def.inc> + +PROTOBUF_PRAGMA_INIT_SEG +PROTOBUF_NAMESPACE_OPEN +constexpr DoubleValue::DoubleValue( + ::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized) + : value_(0){} +struct DoubleValueDefaultTypeInternal { + constexpr DoubleValueDefaultTypeInternal() + : _instance(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized{}) {} + ~DoubleValueDefaultTypeInternal() {} + union { + DoubleValue _instance; + }; +}; +PROTOBUF_ATTRIBUTE_NO_DESTROY PROTOBUF_CONSTINIT DoubleValueDefaultTypeInternal _DoubleValue_default_instance_; +constexpr FloatValue::FloatValue( + ::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized) + : value_(0){} +struct FloatValueDefaultTypeInternal { + constexpr FloatValueDefaultTypeInternal() + : _instance(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized{}) {} + ~FloatValueDefaultTypeInternal() {} + union { + FloatValue _instance; + }; +}; +PROTOBUF_ATTRIBUTE_NO_DESTROY PROTOBUF_CONSTINIT FloatValueDefaultTypeInternal _FloatValue_default_instance_; +constexpr Int64Value::Int64Value( + ::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized) + : value_(arc_i64{0}){} +struct Int64ValueDefaultTypeInternal { + constexpr Int64ValueDefaultTypeInternal() + : _instance(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized{}) {} + ~Int64ValueDefaultTypeInternal() {} + union { + Int64Value _instance; + }; +}; +PROTOBUF_ATTRIBUTE_NO_DESTROY PROTOBUF_CONSTINIT Int64ValueDefaultTypeInternal _Int64Value_default_instance_; +constexpr UInt64Value::UInt64Value( + ::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized) + : value_(arc_ui64{0u}){} +struct UInt64ValueDefaultTypeInternal { + constexpr UInt64ValueDefaultTypeInternal() + : _instance(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized{}) {} + ~UInt64ValueDefaultTypeInternal() {} + union { + UInt64Value _instance; + }; +}; +PROTOBUF_ATTRIBUTE_NO_DESTROY PROTOBUF_CONSTINIT UInt64ValueDefaultTypeInternal _UInt64Value_default_instance_; +constexpr Int32Value::Int32Value( + ::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized) + : value_(0){} +struct Int32ValueDefaultTypeInternal { + constexpr Int32ValueDefaultTypeInternal() + : _instance(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized{}) {} + ~Int32ValueDefaultTypeInternal() {} + union { + Int32Value _instance; + }; +}; +PROTOBUF_ATTRIBUTE_NO_DESTROY PROTOBUF_CONSTINIT Int32ValueDefaultTypeInternal _Int32Value_default_instance_; +constexpr UInt32Value::UInt32Value( + ::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized) + : value_(0u){} +struct UInt32ValueDefaultTypeInternal { + constexpr UInt32ValueDefaultTypeInternal() + : _instance(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized{}) {} + ~UInt32ValueDefaultTypeInternal() {} + union { + UInt32Value _instance; + }; +}; +PROTOBUF_ATTRIBUTE_NO_DESTROY PROTOBUF_CONSTINIT UInt32ValueDefaultTypeInternal _UInt32Value_default_instance_; +constexpr BoolValue::BoolValue( + ::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized) + : value_(false){} +struct BoolValueDefaultTypeInternal { + constexpr BoolValueDefaultTypeInternal() + : _instance(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized{}) {} + ~BoolValueDefaultTypeInternal() {} + union { + BoolValue _instance; + }; +}; +PROTOBUF_ATTRIBUTE_NO_DESTROY PROTOBUF_CONSTINIT BoolValueDefaultTypeInternal _BoolValue_default_instance_; +constexpr StringValue::StringValue( + ::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized) + : value_(&::PROTOBUF_NAMESPACE_ID::internal::fixed_address_empty_string){} +struct StringValueDefaultTypeInternal { + constexpr StringValueDefaultTypeInternal() + : _instance(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized{}) {} + ~StringValueDefaultTypeInternal() {} + union { + StringValue _instance; + }; +}; +PROTOBUF_ATTRIBUTE_NO_DESTROY PROTOBUF_CONSTINIT StringValueDefaultTypeInternal _StringValue_default_instance_; +constexpr BytesValue::BytesValue( + ::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized) + : value_(&::PROTOBUF_NAMESPACE_ID::internal::fixed_address_empty_string){} +struct BytesValueDefaultTypeInternal { + constexpr BytesValueDefaultTypeInternal() + : _instance(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized{}) {} + ~BytesValueDefaultTypeInternal() {} + union { + BytesValue _instance; + }; +}; +PROTOBUF_ATTRIBUTE_NO_DESTROY PROTOBUF_CONSTINIT BytesValueDefaultTypeInternal _BytesValue_default_instance_; +PROTOBUF_NAMESPACE_CLOSE +static ::PROTOBUF_NAMESPACE_ID::Metadata file_level_metadata_google_2fprotobuf_2fwrappers_2eproto[9]; +static constexpr ::PROTOBUF_NAMESPACE_ID::EnumDescriptor const** file_level_enum_descriptors_google_2fprotobuf_2fwrappers_2eproto = nullptr; +static constexpr ::PROTOBUF_NAMESPACE_ID::ServiceDescriptor const** file_level_service_descriptors_google_2fprotobuf_2fwrappers_2eproto = nullptr; + +const arc_ui32 TableStruct_google_2fprotobuf_2fwrappers_2eproto::offsets[] PROTOBUF_SECTION_VARIABLE(protodesc_cold) = { + ~0u, // no _has_bits_ + PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::DoubleValue, _internal_metadata_), + ~0u, // no _extensions_ + ~0u, // no _oneof_case_ + ~0u, // no _weak_field_map_ + ~0u, // no _inlined_string_donated_ + PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::DoubleValue, value_), + ~0u, // no _has_bits_ + PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::FloatValue, _internal_metadata_), + ~0u, // no _extensions_ + ~0u, // no _oneof_case_ + ~0u, // no _weak_field_map_ + ~0u, // no _inlined_string_donated_ + PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::FloatValue, value_), + ~0u, // no _has_bits_ + PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::Int64Value, _internal_metadata_), + ~0u, // no _extensions_ + ~0u, // no _oneof_case_ + ~0u, // no _weak_field_map_ + ~0u, // no _inlined_string_donated_ + PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::Int64Value, value_), + ~0u, // no _has_bits_ + PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::UInt64Value, _internal_metadata_), + ~0u, // no _extensions_ + ~0u, // no _oneof_case_ + ~0u, // no _weak_field_map_ + ~0u, // no _inlined_string_donated_ + PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::UInt64Value, value_), + ~0u, // no _has_bits_ + PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::Int32Value, _internal_metadata_), + ~0u, // no _extensions_ + ~0u, // no _oneof_case_ + ~0u, // no _weak_field_map_ + ~0u, // no _inlined_string_donated_ + PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::Int32Value, value_), + ~0u, // no _has_bits_ + PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::UInt32Value, _internal_metadata_), + ~0u, // no _extensions_ + ~0u, // no _oneof_case_ + ~0u, // no _weak_field_map_ + ~0u, // no _inlined_string_donated_ + PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::UInt32Value, value_), + ~0u, // no _has_bits_ + PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::BoolValue, _internal_metadata_), + ~0u, // no _extensions_ + ~0u, // no _oneof_case_ + ~0u, // no _weak_field_map_ + ~0u, // no _inlined_string_donated_ + PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::BoolValue, value_), + ~0u, // no _has_bits_ + PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::StringValue, _internal_metadata_), + ~0u, // no _extensions_ + ~0u, // no _oneof_case_ + ~0u, // no _weak_field_map_ + ~0u, // no _inlined_string_donated_ + PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::StringValue, value_), + ~0u, // no _has_bits_ + PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::BytesValue, _internal_metadata_), + ~0u, // no _extensions_ + ~0u, // no _oneof_case_ + ~0u, // no _weak_field_map_ + ~0u, // no _inlined_string_donated_ + PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::BytesValue, value_), +}; +static const ::PROTOBUF_NAMESPACE_ID::internal::MigrationSchema schemas[] PROTOBUF_SECTION_VARIABLE(protodesc_cold) = { + { 0, -1, -1, sizeof(::PROTOBUF_NAMESPACE_ID::DoubleValue)}, + { 7, -1, -1, sizeof(::PROTOBUF_NAMESPACE_ID::FloatValue)}, + { 14, -1, -1, sizeof(::PROTOBUF_NAMESPACE_ID::Int64Value)}, + { 21, -1, -1, sizeof(::PROTOBUF_NAMESPACE_ID::UInt64Value)}, + { 28, -1, -1, sizeof(::PROTOBUF_NAMESPACE_ID::Int32Value)}, + { 35, -1, -1, sizeof(::PROTOBUF_NAMESPACE_ID::UInt32Value)}, + { 42, -1, -1, sizeof(::PROTOBUF_NAMESPACE_ID::BoolValue)}, + { 49, -1, -1, sizeof(::PROTOBUF_NAMESPACE_ID::StringValue)}, + { 56, -1, -1, sizeof(::PROTOBUF_NAMESPACE_ID::BytesValue)}, +}; + +static ::PROTOBUF_NAMESPACE_ID::Message const * const file_default_instances[] = { + reinterpret_cast<const ::PROTOBUF_NAMESPACE_ID::Message*>(&::PROTOBUF_NAMESPACE_ID::_DoubleValue_default_instance_), + reinterpret_cast<const ::PROTOBUF_NAMESPACE_ID::Message*>(&::PROTOBUF_NAMESPACE_ID::_FloatValue_default_instance_), + reinterpret_cast<const ::PROTOBUF_NAMESPACE_ID::Message*>(&::PROTOBUF_NAMESPACE_ID::_Int64Value_default_instance_), + reinterpret_cast<const ::PROTOBUF_NAMESPACE_ID::Message*>(&::PROTOBUF_NAMESPACE_ID::_UInt64Value_default_instance_), + reinterpret_cast<const ::PROTOBUF_NAMESPACE_ID::Message*>(&::PROTOBUF_NAMESPACE_ID::_Int32Value_default_instance_), + reinterpret_cast<const ::PROTOBUF_NAMESPACE_ID::Message*>(&::PROTOBUF_NAMESPACE_ID::_UInt32Value_default_instance_), + reinterpret_cast<const ::PROTOBUF_NAMESPACE_ID::Message*>(&::PROTOBUF_NAMESPACE_ID::_BoolValue_default_instance_), + reinterpret_cast<const ::PROTOBUF_NAMESPACE_ID::Message*>(&::PROTOBUF_NAMESPACE_ID::_StringValue_default_instance_), + reinterpret_cast<const ::PROTOBUF_NAMESPACE_ID::Message*>(&::PROTOBUF_NAMESPACE_ID::_BytesValue_default_instance_), +}; + +const char descriptor_table_protodef_google_2fprotobuf_2fwrappers_2eproto[] PROTOBUF_SECTION_VARIABLE(protodesc_cold) = + "\n\036google/protobuf/wrappers.proto\022\017google" + ".protobuf\"\034\n\013DoubleValue\022\r\n\005value\030\001 \001(\001\"" + "\033\n\nFloatValue\022\r\n\005value\030\001 \001(\002\"\033\n\nInt64Val" + "ue\022\r\n\005value\030\001 \001(\003\"\034\n\013UInt64Value\022\r\n\005valu" + "e\030\001 \001(\004\"\033\n\nInt32Value\022\r\n\005value\030\001 \001(\005\"\034\n\013" + "UInt32Value\022\r\n\005value\030\001 \001(\r\"\032\n\tBoolValue\022" + "\r\n\005value\030\001 \001(\010\"\034\n\013StringValue\022\r\n\005value\030\001" + " \001(\t\"\033\n\nBytesValue\022\r\n\005value\030\001 \001(\014B\203\001\n\023co" + "m.google.protobufB\rWrappersProtoP\001Z1goog" + "le.golang.org/protobuf/types/known/wrapp" + "erspb\370\001\001\242\002\003GPB\252\002\036Google.Protobuf.WellKno" + "wnTypesb\006proto3" + ; +static ::PROTOBUF_NAMESPACE_ID::internal::once_flag descriptor_table_google_2fprotobuf_2fwrappers_2eproto_once; +const ::PROTOBUF_NAMESPACE_ID::internal::DescriptorTable descriptor_table_google_2fprotobuf_2fwrappers_2eproto = { + false, false, 455, descriptor_table_protodef_google_2fprotobuf_2fwrappers_2eproto, "google/protobuf/wrappers.proto", + &descriptor_table_google_2fprotobuf_2fwrappers_2eproto_once, nullptr, 0, 9, + schemas, file_default_instances, TableStruct_google_2fprotobuf_2fwrappers_2eproto::offsets, + file_level_metadata_google_2fprotobuf_2fwrappers_2eproto, file_level_enum_descriptors_google_2fprotobuf_2fwrappers_2eproto, file_level_service_descriptors_google_2fprotobuf_2fwrappers_2eproto, +}; +PROTOBUF_ATTRIBUTE_WEAK const ::PROTOBUF_NAMESPACE_ID::internal::DescriptorTable* descriptor_table_google_2fprotobuf_2fwrappers_2eproto_getter() { + return &descriptor_table_google_2fprotobuf_2fwrappers_2eproto; +} + +// Force running AddDescriptors() at dynamic initialization time. +PROTOBUF_ATTRIBUTE_INIT_PRIORITY static ::PROTOBUF_NAMESPACE_ID::internal::AddDescriptorsRunner dynamic_init_dummy_google_2fprotobuf_2fwrappers_2eproto(&descriptor_table_google_2fprotobuf_2fwrappers_2eproto); +PROTOBUF_NAMESPACE_OPEN + +// =================================================================== + +class DoubleValue::_Internal { + public: +}; + +DoubleValue::DoubleValue(::PROTOBUF_NAMESPACE_ID::Arena* arena, + bool is_message_owned) + : ::PROTOBUF_NAMESPACE_ID::Message(arena, is_message_owned) { + SharedCtor(); + if (!is_message_owned) { + RegisterArenaDtor(arena); + } + // @@protoc_insertion_point(arena_constructor:google.protobuf.DoubleValue) +} +DoubleValue::DoubleValue(const DoubleValue& from) + : ::PROTOBUF_NAMESPACE_ID::Message() { + _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_); + value_ = from.value_; + // @@protoc_insertion_point(copy_constructor:google.protobuf.DoubleValue) +} + +inline void DoubleValue::SharedCtor() { +value_ = 0; +} + +DoubleValue::~DoubleValue() { + // @@protoc_insertion_point(destructor:google.protobuf.DoubleValue) + if (GetArenaForAllocation() != nullptr) return; + SharedDtor(); + _internal_metadata_.Delete<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(); +} + +inline void DoubleValue::SharedDtor() { + GOOGLE_DCHECK(GetArenaForAllocation() == nullptr); +} + +void DoubleValue::ArenaDtor(void* object) { + DoubleValue* _this = reinterpret_cast< DoubleValue* >(object); + (void)_this; +} +void DoubleValue::RegisterArenaDtor(::PROTOBUF_NAMESPACE_ID::Arena*) { +} +void DoubleValue::SetCachedSize(int size) const { + _cached_size_.Set(size); +} + +void DoubleValue::Clear() { +// @@protoc_insertion_point(message_clear_start:google.protobuf.DoubleValue) + arc_ui32 cached_has_bits = 0; + // Prevent compiler warnings about cached_has_bits being unused + (void) cached_has_bits; + + value_ = 0; + _internal_metadata_.Clear<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(); +} + +const char* DoubleValue::_InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) { +#define CHK_(x) if (PROTOBUF_PREDICT_FALSE(!(x))) goto failure + while (!ctx->Done(&ptr)) { + arc_ui32 tag; + ptr = ::PROTOBUF_NAMESPACE_ID::internal::ReadTag(ptr, &tag); + switch (tag >> 3) { + // double value = 1; + case 1: + if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 9)) { + value_ = ::PROTOBUF_NAMESPACE_ID::internal::UnalignedLoad<double>(ptr); + ptr += sizeof(double); + } else + goto handle_unusual; + continue; + default: + goto handle_unusual; + } // switch + handle_unusual: + if ((tag == 0) || ((tag & 7) == 4)) { + CHK_(ptr); + ctx->SetLastTag(tag); + goto message_done; + } + ptr = UnknownFieldParse( + tag, + _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(), + ptr, ctx); + CHK_(ptr != nullptr); + } // while +message_done: + return ptr; +failure: + ptr = nullptr; + goto message_done; +#undef CHK_ +} + +uint8_t* DoubleValue::_InternalSerialize( + uint8_t* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const { + // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.DoubleValue) + arc_ui32 cached_has_bits = 0; + (void) cached_has_bits; + + // double value = 1; + static_assert(sizeof(arc_ui64) == sizeof(double), "Code assumes arc_ui64 and double are the same size."); + double tmp_value = this->_internal_value(); + arc_ui64 raw_value; + memcpy(&raw_value, &tmp_value, sizeof(tmp_value)); + if (raw_value != 0) { + target = stream->EnsureSpace(target); + target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteDoubleToArray(1, this->_internal_value(), target); + } + + if (PROTOBUF_PREDICT_FALSE(_internal_metadata_.have_unknown_fields())) { + target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::InternalSerializeUnknownFieldsToArray( + _internal_metadata_.unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(::PROTOBUF_NAMESPACE_ID::UnknownFieldSet::default_instance), target, stream); + } + // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.DoubleValue) + return target; +} + +size_t DoubleValue::ByteSizeLong() const { +// @@protoc_insertion_point(message_byte_size_start:google.protobuf.DoubleValue) + size_t total_size = 0; + + arc_ui32 cached_has_bits = 0; + // Prevent compiler warnings about cached_has_bits being unused + (void) cached_has_bits; + + // double value = 1; + static_assert(sizeof(arc_ui64) == sizeof(double), "Code assumes arc_ui64 and double are the same size."); + double tmp_value = this->_internal_value(); + arc_ui64 raw_value; + memcpy(&raw_value, &tmp_value, sizeof(tmp_value)); + if (raw_value != 0) { + total_size += 1 + 8; + } + + return MaybeComputeUnknownFieldsSize(total_size, &_cached_size_); +} + +const ::PROTOBUF_NAMESPACE_ID::Message::ClassData DoubleValue::_class_data_ = { + ::PROTOBUF_NAMESPACE_ID::Message::CopyWithSizeCheck, + DoubleValue::MergeImpl +}; +const ::PROTOBUF_NAMESPACE_ID::Message::ClassData*DoubleValue::GetClassData() const { return &_class_data_; } + +void DoubleValue::MergeImpl(::PROTOBUF_NAMESPACE_ID::Message* to, + const ::PROTOBUF_NAMESPACE_ID::Message& from) { + static_cast<DoubleValue *>(to)->MergeFrom( + static_cast<const DoubleValue &>(from)); +} + + +void DoubleValue::MergeFrom(const DoubleValue& from) { +// @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.DoubleValue) + GOOGLE_DCHECK_NE(&from, this); + arc_ui32 cached_has_bits = 0; + (void) cached_has_bits; + + static_assert(sizeof(arc_ui64) == sizeof(double), "Code assumes arc_ui64 and double are the same size."); + double tmp_value = from._internal_value(); + arc_ui64 raw_value; + memcpy(&raw_value, &tmp_value, sizeof(tmp_value)); + if (raw_value != 0) { + _internal_set_value(from._internal_value()); + } + _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_); +} + +void DoubleValue::CopyFrom(const DoubleValue& from) { +// @@protoc_insertion_point(class_specific_copy_from_start:google.protobuf.DoubleValue) + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool DoubleValue::IsInitialized() const { + return true; +} + +void DoubleValue::InternalSwap(DoubleValue* other) { + using std::swap; + _internal_metadata_.InternalSwap(&other->_internal_metadata_); + swap(value_, other->value_); +} + +::PROTOBUF_NAMESPACE_ID::Metadata DoubleValue::GetMetadata() const { + return ::PROTOBUF_NAMESPACE_ID::internal::AssignDescriptors( + &descriptor_table_google_2fprotobuf_2fwrappers_2eproto_getter, &descriptor_table_google_2fprotobuf_2fwrappers_2eproto_once, + file_level_metadata_google_2fprotobuf_2fwrappers_2eproto[0]); +} + +// =================================================================== + +class FloatValue::_Internal { + public: +}; + +FloatValue::FloatValue(::PROTOBUF_NAMESPACE_ID::Arena* arena, + bool is_message_owned) + : ::PROTOBUF_NAMESPACE_ID::Message(arena, is_message_owned) { + SharedCtor(); + if (!is_message_owned) { + RegisterArenaDtor(arena); + } + // @@protoc_insertion_point(arena_constructor:google.protobuf.FloatValue) +} +FloatValue::FloatValue(const FloatValue& from) + : ::PROTOBUF_NAMESPACE_ID::Message() { + _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_); + value_ = from.value_; + // @@protoc_insertion_point(copy_constructor:google.protobuf.FloatValue) +} + +inline void FloatValue::SharedCtor() { +value_ = 0; +} + +FloatValue::~FloatValue() { + // @@protoc_insertion_point(destructor:google.protobuf.FloatValue) + if (GetArenaForAllocation() != nullptr) return; + SharedDtor(); + _internal_metadata_.Delete<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(); +} + +inline void FloatValue::SharedDtor() { + GOOGLE_DCHECK(GetArenaForAllocation() == nullptr); +} + +void FloatValue::ArenaDtor(void* object) { + FloatValue* _this = reinterpret_cast< FloatValue* >(object); + (void)_this; +} +void FloatValue::RegisterArenaDtor(::PROTOBUF_NAMESPACE_ID::Arena*) { +} +void FloatValue::SetCachedSize(int size) const { + _cached_size_.Set(size); +} + +void FloatValue::Clear() { +// @@protoc_insertion_point(message_clear_start:google.protobuf.FloatValue) + arc_ui32 cached_has_bits = 0; + // Prevent compiler warnings about cached_has_bits being unused + (void) cached_has_bits; + + value_ = 0; + _internal_metadata_.Clear<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(); +} + +const char* FloatValue::_InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) { +#define CHK_(x) if (PROTOBUF_PREDICT_FALSE(!(x))) goto failure + while (!ctx->Done(&ptr)) { + arc_ui32 tag; + ptr = ::PROTOBUF_NAMESPACE_ID::internal::ReadTag(ptr, &tag); + switch (tag >> 3) { + // float value = 1; + case 1: + if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 13)) { + value_ = ::PROTOBUF_NAMESPACE_ID::internal::UnalignedLoad<float>(ptr); + ptr += sizeof(float); + } else + goto handle_unusual; + continue; + default: + goto handle_unusual; + } // switch + handle_unusual: + if ((tag == 0) || ((tag & 7) == 4)) { + CHK_(ptr); + ctx->SetLastTag(tag); + goto message_done; + } + ptr = UnknownFieldParse( + tag, + _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(), + ptr, ctx); + CHK_(ptr != nullptr); + } // while +message_done: + return ptr; +failure: + ptr = nullptr; + goto message_done; +#undef CHK_ +} + +uint8_t* FloatValue::_InternalSerialize( + uint8_t* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const { + // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.FloatValue) + arc_ui32 cached_has_bits = 0; + (void) cached_has_bits; + + // float value = 1; + static_assert(sizeof(arc_ui32) == sizeof(float), "Code assumes arc_ui32 and float are the same size."); + float tmp_value = this->_internal_value(); + arc_ui32 raw_value; + memcpy(&raw_value, &tmp_value, sizeof(tmp_value)); + if (raw_value != 0) { + target = stream->EnsureSpace(target); + target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteFloatToArray(1, this->_internal_value(), target); + } + + if (PROTOBUF_PREDICT_FALSE(_internal_metadata_.have_unknown_fields())) { + target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::InternalSerializeUnknownFieldsToArray( + _internal_metadata_.unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(::PROTOBUF_NAMESPACE_ID::UnknownFieldSet::default_instance), target, stream); + } + // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.FloatValue) + return target; +} + +size_t FloatValue::ByteSizeLong() const { +// @@protoc_insertion_point(message_byte_size_start:google.protobuf.FloatValue) + size_t total_size = 0; + + arc_ui32 cached_has_bits = 0; + // Prevent compiler warnings about cached_has_bits being unused + (void) cached_has_bits; + + // float value = 1; + static_assert(sizeof(arc_ui32) == sizeof(float), "Code assumes arc_ui32 and float are the same size."); + float tmp_value = this->_internal_value(); + arc_ui32 raw_value; + memcpy(&raw_value, &tmp_value, sizeof(tmp_value)); + if (raw_value != 0) { + total_size += 1 + 4; + } + + return MaybeComputeUnknownFieldsSize(total_size, &_cached_size_); +} + +const ::PROTOBUF_NAMESPACE_ID::Message::ClassData FloatValue::_class_data_ = { + ::PROTOBUF_NAMESPACE_ID::Message::CopyWithSizeCheck, + FloatValue::MergeImpl +}; +const ::PROTOBUF_NAMESPACE_ID::Message::ClassData*FloatValue::GetClassData() const { return &_class_data_; } + +void FloatValue::MergeImpl(::PROTOBUF_NAMESPACE_ID::Message* to, + const ::PROTOBUF_NAMESPACE_ID::Message& from) { + static_cast<FloatValue *>(to)->MergeFrom( + static_cast<const FloatValue &>(from)); +} + + +void FloatValue::MergeFrom(const FloatValue& from) { +// @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.FloatValue) + GOOGLE_DCHECK_NE(&from, this); + arc_ui32 cached_has_bits = 0; + (void) cached_has_bits; + + static_assert(sizeof(arc_ui32) == sizeof(float), "Code assumes arc_ui32 and float are the same size."); + float tmp_value = from._internal_value(); + arc_ui32 raw_value; + memcpy(&raw_value, &tmp_value, sizeof(tmp_value)); + if (raw_value != 0) { + _internal_set_value(from._internal_value()); + } + _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_); +} + +void FloatValue::CopyFrom(const FloatValue& from) { +// @@protoc_insertion_point(class_specific_copy_from_start:google.protobuf.FloatValue) + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool FloatValue::IsInitialized() const { + return true; +} + +void FloatValue::InternalSwap(FloatValue* other) { + using std::swap; + _internal_metadata_.InternalSwap(&other->_internal_metadata_); + swap(value_, other->value_); +} + +::PROTOBUF_NAMESPACE_ID::Metadata FloatValue::GetMetadata() const { + return ::PROTOBUF_NAMESPACE_ID::internal::AssignDescriptors( + &descriptor_table_google_2fprotobuf_2fwrappers_2eproto_getter, &descriptor_table_google_2fprotobuf_2fwrappers_2eproto_once, + file_level_metadata_google_2fprotobuf_2fwrappers_2eproto[1]); +} + +// =================================================================== + +class Int64Value::_Internal { + public: +}; + +Int64Value::Int64Value(::PROTOBUF_NAMESPACE_ID::Arena* arena, + bool is_message_owned) + : ::PROTOBUF_NAMESPACE_ID::Message(arena, is_message_owned) { + SharedCtor(); + if (!is_message_owned) { + RegisterArenaDtor(arena); + } + // @@protoc_insertion_point(arena_constructor:google.protobuf.Int64Value) +} +Int64Value::Int64Value(const Int64Value& from) + : ::PROTOBUF_NAMESPACE_ID::Message() { + _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_); + value_ = from.value_; + // @@protoc_insertion_point(copy_constructor:google.protobuf.Int64Value) +} + +inline void Int64Value::SharedCtor() { +value_ = arc_i64{0}; +} + +Int64Value::~Int64Value() { + // @@protoc_insertion_point(destructor:google.protobuf.Int64Value) + if (GetArenaForAllocation() != nullptr) return; + SharedDtor(); + _internal_metadata_.Delete<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(); +} + +inline void Int64Value::SharedDtor() { + GOOGLE_DCHECK(GetArenaForAllocation() == nullptr); +} + +void Int64Value::ArenaDtor(void* object) { + Int64Value* _this = reinterpret_cast< Int64Value* >(object); + (void)_this; +} +void Int64Value::RegisterArenaDtor(::PROTOBUF_NAMESPACE_ID::Arena*) { +} +void Int64Value::SetCachedSize(int size) const { + _cached_size_.Set(size); +} + +void Int64Value::Clear() { +// @@protoc_insertion_point(message_clear_start:google.protobuf.Int64Value) + arc_ui32 cached_has_bits = 0; + // Prevent compiler warnings about cached_has_bits being unused + (void) cached_has_bits; + + value_ = arc_i64{0}; + _internal_metadata_.Clear<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(); +} + +const char* Int64Value::_InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) { +#define CHK_(x) if (PROTOBUF_PREDICT_FALSE(!(x))) goto failure + while (!ctx->Done(&ptr)) { + arc_ui32 tag; + ptr = ::PROTOBUF_NAMESPACE_ID::internal::ReadTag(ptr, &tag); + switch (tag >> 3) { + // int64 value = 1; + case 1: + if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 8)) { + value_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint64(&ptr); + CHK_(ptr); + } else + goto handle_unusual; + continue; + default: + goto handle_unusual; + } // switch + handle_unusual: + if ((tag == 0) || ((tag & 7) == 4)) { + CHK_(ptr); + ctx->SetLastTag(tag); + goto message_done; + } + ptr = UnknownFieldParse( + tag, + _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(), + ptr, ctx); + CHK_(ptr != nullptr); + } // while +message_done: + return ptr; +failure: + ptr = nullptr; + goto message_done; +#undef CHK_ +} + +uint8_t* Int64Value::_InternalSerialize( + uint8_t* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const { + // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.Int64Value) + arc_ui32 cached_has_bits = 0; + (void) cached_has_bits; + + // int64 value = 1; + if (this->_internal_value() != 0) { + target = stream->EnsureSpace(target); + target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteInt64ToArray(1, this->_internal_value(), target); + } + + if (PROTOBUF_PREDICT_FALSE(_internal_metadata_.have_unknown_fields())) { + target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::InternalSerializeUnknownFieldsToArray( + _internal_metadata_.unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(::PROTOBUF_NAMESPACE_ID::UnknownFieldSet::default_instance), target, stream); + } + // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.Int64Value) + return target; +} + +size_t Int64Value::ByteSizeLong() const { +// @@protoc_insertion_point(message_byte_size_start:google.protobuf.Int64Value) + size_t total_size = 0; + + arc_ui32 cached_has_bits = 0; + // Prevent compiler warnings about cached_has_bits being unused + (void) cached_has_bits; + + // int64 value = 1; + if (this->_internal_value() != 0) { + total_size += ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::Int64SizePlusOne(this->_internal_value()); + } + + return MaybeComputeUnknownFieldsSize(total_size, &_cached_size_); +} + +const ::PROTOBUF_NAMESPACE_ID::Message::ClassData Int64Value::_class_data_ = { + ::PROTOBUF_NAMESPACE_ID::Message::CopyWithSizeCheck, + Int64Value::MergeImpl +}; +const ::PROTOBUF_NAMESPACE_ID::Message::ClassData*Int64Value::GetClassData() const { return &_class_data_; } + +void Int64Value::MergeImpl(::PROTOBUF_NAMESPACE_ID::Message* to, + const ::PROTOBUF_NAMESPACE_ID::Message& from) { + static_cast<Int64Value *>(to)->MergeFrom( + static_cast<const Int64Value &>(from)); +} + + +void Int64Value::MergeFrom(const Int64Value& from) { +// @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.Int64Value) + GOOGLE_DCHECK_NE(&from, this); + arc_ui32 cached_has_bits = 0; + (void) cached_has_bits; + + if (from._internal_value() != 0) { + _internal_set_value(from._internal_value()); + } + _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_); +} + +void Int64Value::CopyFrom(const Int64Value& from) { +// @@protoc_insertion_point(class_specific_copy_from_start:google.protobuf.Int64Value) + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool Int64Value::IsInitialized() const { + return true; +} + +void Int64Value::InternalSwap(Int64Value* other) { + using std::swap; + _internal_metadata_.InternalSwap(&other->_internal_metadata_); + swap(value_, other->value_); +} + +::PROTOBUF_NAMESPACE_ID::Metadata Int64Value::GetMetadata() const { + return ::PROTOBUF_NAMESPACE_ID::internal::AssignDescriptors( + &descriptor_table_google_2fprotobuf_2fwrappers_2eproto_getter, &descriptor_table_google_2fprotobuf_2fwrappers_2eproto_once, + file_level_metadata_google_2fprotobuf_2fwrappers_2eproto[2]); +} + +// =================================================================== + +class UInt64Value::_Internal { + public: +}; + +UInt64Value::UInt64Value(::PROTOBUF_NAMESPACE_ID::Arena* arena, + bool is_message_owned) + : ::PROTOBUF_NAMESPACE_ID::Message(arena, is_message_owned) { + SharedCtor(); + if (!is_message_owned) { + RegisterArenaDtor(arena); + } + // @@protoc_insertion_point(arena_constructor:google.protobuf.UInt64Value) +} +UInt64Value::UInt64Value(const UInt64Value& from) + : ::PROTOBUF_NAMESPACE_ID::Message() { + _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_); + value_ = from.value_; + // @@protoc_insertion_point(copy_constructor:google.protobuf.UInt64Value) +} + +inline void UInt64Value::SharedCtor() { +value_ = arc_ui64{0u}; +} + +UInt64Value::~UInt64Value() { + // @@protoc_insertion_point(destructor:google.protobuf.UInt64Value) + if (GetArenaForAllocation() != nullptr) return; + SharedDtor(); + _internal_metadata_.Delete<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(); +} + +inline void UInt64Value::SharedDtor() { + GOOGLE_DCHECK(GetArenaForAllocation() == nullptr); +} + +void UInt64Value::ArenaDtor(void* object) { + UInt64Value* _this = reinterpret_cast< UInt64Value* >(object); + (void)_this; +} +void UInt64Value::RegisterArenaDtor(::PROTOBUF_NAMESPACE_ID::Arena*) { +} +void UInt64Value::SetCachedSize(int size) const { + _cached_size_.Set(size); +} + +void UInt64Value::Clear() { +// @@protoc_insertion_point(message_clear_start:google.protobuf.UInt64Value) + arc_ui32 cached_has_bits = 0; + // Prevent compiler warnings about cached_has_bits being unused + (void) cached_has_bits; + + value_ = arc_ui64{0u}; + _internal_metadata_.Clear<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(); +} + +const char* UInt64Value::_InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) { +#define CHK_(x) if (PROTOBUF_PREDICT_FALSE(!(x))) goto failure + while (!ctx->Done(&ptr)) { + arc_ui32 tag; + ptr = ::PROTOBUF_NAMESPACE_ID::internal::ReadTag(ptr, &tag); + switch (tag >> 3) { + // uint64 value = 1; + case 1: + if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 8)) { + value_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint64(&ptr); + CHK_(ptr); + } else + goto handle_unusual; + continue; + default: + goto handle_unusual; + } // switch + handle_unusual: + if ((tag == 0) || ((tag & 7) == 4)) { + CHK_(ptr); + ctx->SetLastTag(tag); + goto message_done; + } + ptr = UnknownFieldParse( + tag, + _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(), + ptr, ctx); + CHK_(ptr != nullptr); + } // while +message_done: + return ptr; +failure: + ptr = nullptr; + goto message_done; +#undef CHK_ +} + +uint8_t* UInt64Value::_InternalSerialize( + uint8_t* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const { + // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.UInt64Value) + arc_ui32 cached_has_bits = 0; + (void) cached_has_bits; + + // uint64 value = 1; + if (this->_internal_value() != 0) { + target = stream->EnsureSpace(target); + target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteUInt64ToArray(1, this->_internal_value(), target); + } + + if (PROTOBUF_PREDICT_FALSE(_internal_metadata_.have_unknown_fields())) { + target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::InternalSerializeUnknownFieldsToArray( + _internal_metadata_.unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(::PROTOBUF_NAMESPACE_ID::UnknownFieldSet::default_instance), target, stream); + } + // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.UInt64Value) + return target; +} + +size_t UInt64Value::ByteSizeLong() const { +// @@protoc_insertion_point(message_byte_size_start:google.protobuf.UInt64Value) + size_t total_size = 0; + + arc_ui32 cached_has_bits = 0; + // Prevent compiler warnings about cached_has_bits being unused + (void) cached_has_bits; + + // uint64 value = 1; + if (this->_internal_value() != 0) { + total_size += ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::UInt64SizePlusOne(this->_internal_value()); + } + + return MaybeComputeUnknownFieldsSize(total_size, &_cached_size_); +} + +const ::PROTOBUF_NAMESPACE_ID::Message::ClassData UInt64Value::_class_data_ = { + ::PROTOBUF_NAMESPACE_ID::Message::CopyWithSizeCheck, + UInt64Value::MergeImpl +}; +const ::PROTOBUF_NAMESPACE_ID::Message::ClassData*UInt64Value::GetClassData() const { return &_class_data_; } + +void UInt64Value::MergeImpl(::PROTOBUF_NAMESPACE_ID::Message* to, + const ::PROTOBUF_NAMESPACE_ID::Message& from) { + static_cast<UInt64Value *>(to)->MergeFrom( + static_cast<const UInt64Value &>(from)); +} + + +void UInt64Value::MergeFrom(const UInt64Value& from) { +// @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.UInt64Value) + GOOGLE_DCHECK_NE(&from, this); + arc_ui32 cached_has_bits = 0; + (void) cached_has_bits; + + if (from._internal_value() != 0) { + _internal_set_value(from._internal_value()); + } + _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_); +} + +void UInt64Value::CopyFrom(const UInt64Value& from) { +// @@protoc_insertion_point(class_specific_copy_from_start:google.protobuf.UInt64Value) + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool UInt64Value::IsInitialized() const { + return true; +} + +void UInt64Value::InternalSwap(UInt64Value* other) { + using std::swap; + _internal_metadata_.InternalSwap(&other->_internal_metadata_); + swap(value_, other->value_); +} + +::PROTOBUF_NAMESPACE_ID::Metadata UInt64Value::GetMetadata() const { + return ::PROTOBUF_NAMESPACE_ID::internal::AssignDescriptors( + &descriptor_table_google_2fprotobuf_2fwrappers_2eproto_getter, &descriptor_table_google_2fprotobuf_2fwrappers_2eproto_once, + file_level_metadata_google_2fprotobuf_2fwrappers_2eproto[3]); +} + +// =================================================================== + +class Int32Value::_Internal { + public: +}; + +Int32Value::Int32Value(::PROTOBUF_NAMESPACE_ID::Arena* arena, + bool is_message_owned) + : ::PROTOBUF_NAMESPACE_ID::Message(arena, is_message_owned) { + SharedCtor(); + if (!is_message_owned) { + RegisterArenaDtor(arena); + } + // @@protoc_insertion_point(arena_constructor:google.protobuf.Int32Value) +} +Int32Value::Int32Value(const Int32Value& from) + : ::PROTOBUF_NAMESPACE_ID::Message() { + _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_); + value_ = from.value_; + // @@protoc_insertion_point(copy_constructor:google.protobuf.Int32Value) +} + +inline void Int32Value::SharedCtor() { +value_ = 0; +} + +Int32Value::~Int32Value() { + // @@protoc_insertion_point(destructor:google.protobuf.Int32Value) + if (GetArenaForAllocation() != nullptr) return; + SharedDtor(); + _internal_metadata_.Delete<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(); +} + +inline void Int32Value::SharedDtor() { + GOOGLE_DCHECK(GetArenaForAllocation() == nullptr); +} + +void Int32Value::ArenaDtor(void* object) { + Int32Value* _this = reinterpret_cast< Int32Value* >(object); + (void)_this; +} +void Int32Value::RegisterArenaDtor(::PROTOBUF_NAMESPACE_ID::Arena*) { +} +void Int32Value::SetCachedSize(int size) const { + _cached_size_.Set(size); +} + +void Int32Value::Clear() { +// @@protoc_insertion_point(message_clear_start:google.protobuf.Int32Value) + arc_ui32 cached_has_bits = 0; + // Prevent compiler warnings about cached_has_bits being unused + (void) cached_has_bits; + + value_ = 0; + _internal_metadata_.Clear<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(); +} + +const char* Int32Value::_InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) { +#define CHK_(x) if (PROTOBUF_PREDICT_FALSE(!(x))) goto failure + while (!ctx->Done(&ptr)) { + arc_ui32 tag; + ptr = ::PROTOBUF_NAMESPACE_ID::internal::ReadTag(ptr, &tag); + switch (tag >> 3) { + // int32 value = 1; + case 1: + if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 8)) { + value_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint32(&ptr); + CHK_(ptr); + } else + goto handle_unusual; + continue; + default: + goto handle_unusual; + } // switch + handle_unusual: + if ((tag == 0) || ((tag & 7) == 4)) { + CHK_(ptr); + ctx->SetLastTag(tag); + goto message_done; + } + ptr = UnknownFieldParse( + tag, + _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(), + ptr, ctx); + CHK_(ptr != nullptr); + } // while +message_done: + return ptr; +failure: + ptr = nullptr; + goto message_done; +#undef CHK_ +} + +uint8_t* Int32Value::_InternalSerialize( + uint8_t* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const { + // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.Int32Value) + arc_ui32 cached_has_bits = 0; + (void) cached_has_bits; + + // int32 value = 1; + if (this->_internal_value() != 0) { + target = stream->EnsureSpace(target); + target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteInt32ToArray(1, this->_internal_value(), target); + } + + if (PROTOBUF_PREDICT_FALSE(_internal_metadata_.have_unknown_fields())) { + target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::InternalSerializeUnknownFieldsToArray( + _internal_metadata_.unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(::PROTOBUF_NAMESPACE_ID::UnknownFieldSet::default_instance), target, stream); + } + // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.Int32Value) + return target; +} + +size_t Int32Value::ByteSizeLong() const { +// @@protoc_insertion_point(message_byte_size_start:google.protobuf.Int32Value) + size_t total_size = 0; + + arc_ui32 cached_has_bits = 0; + // Prevent compiler warnings about cached_has_bits being unused + (void) cached_has_bits; + + // int32 value = 1; + if (this->_internal_value() != 0) { + total_size += ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::Int32SizePlusOne(this->_internal_value()); + } + + return MaybeComputeUnknownFieldsSize(total_size, &_cached_size_); +} + +const ::PROTOBUF_NAMESPACE_ID::Message::ClassData Int32Value::_class_data_ = { + ::PROTOBUF_NAMESPACE_ID::Message::CopyWithSizeCheck, + Int32Value::MergeImpl +}; +const ::PROTOBUF_NAMESPACE_ID::Message::ClassData*Int32Value::GetClassData() const { return &_class_data_; } + +void Int32Value::MergeImpl(::PROTOBUF_NAMESPACE_ID::Message* to, + const ::PROTOBUF_NAMESPACE_ID::Message& from) { + static_cast<Int32Value *>(to)->MergeFrom( + static_cast<const Int32Value &>(from)); +} + + +void Int32Value::MergeFrom(const Int32Value& from) { +// @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.Int32Value) + GOOGLE_DCHECK_NE(&from, this); + arc_ui32 cached_has_bits = 0; + (void) cached_has_bits; + + if (from._internal_value() != 0) { + _internal_set_value(from._internal_value()); + } + _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_); +} + +void Int32Value::CopyFrom(const Int32Value& from) { +// @@protoc_insertion_point(class_specific_copy_from_start:google.protobuf.Int32Value) + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool Int32Value::IsInitialized() const { + return true; +} + +void Int32Value::InternalSwap(Int32Value* other) { + using std::swap; + _internal_metadata_.InternalSwap(&other->_internal_metadata_); + swap(value_, other->value_); +} + +::PROTOBUF_NAMESPACE_ID::Metadata Int32Value::GetMetadata() const { + return ::PROTOBUF_NAMESPACE_ID::internal::AssignDescriptors( + &descriptor_table_google_2fprotobuf_2fwrappers_2eproto_getter, &descriptor_table_google_2fprotobuf_2fwrappers_2eproto_once, + file_level_metadata_google_2fprotobuf_2fwrappers_2eproto[4]); +} + +// =================================================================== + +class UInt32Value::_Internal { + public: +}; + +UInt32Value::UInt32Value(::PROTOBUF_NAMESPACE_ID::Arena* arena, + bool is_message_owned) + : ::PROTOBUF_NAMESPACE_ID::Message(arena, is_message_owned) { + SharedCtor(); + if (!is_message_owned) { + RegisterArenaDtor(arena); + } + // @@protoc_insertion_point(arena_constructor:google.protobuf.UInt32Value) +} +UInt32Value::UInt32Value(const UInt32Value& from) + : ::PROTOBUF_NAMESPACE_ID::Message() { + _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_); + value_ = from.value_; + // @@protoc_insertion_point(copy_constructor:google.protobuf.UInt32Value) +} + +inline void UInt32Value::SharedCtor() { +value_ = 0u; +} + +UInt32Value::~UInt32Value() { + // @@protoc_insertion_point(destructor:google.protobuf.UInt32Value) + if (GetArenaForAllocation() != nullptr) return; + SharedDtor(); + _internal_metadata_.Delete<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(); +} + +inline void UInt32Value::SharedDtor() { + GOOGLE_DCHECK(GetArenaForAllocation() == nullptr); +} + +void UInt32Value::ArenaDtor(void* object) { + UInt32Value* _this = reinterpret_cast< UInt32Value* >(object); + (void)_this; +} +void UInt32Value::RegisterArenaDtor(::PROTOBUF_NAMESPACE_ID::Arena*) { +} +void UInt32Value::SetCachedSize(int size) const { + _cached_size_.Set(size); +} + +void UInt32Value::Clear() { +// @@protoc_insertion_point(message_clear_start:google.protobuf.UInt32Value) + arc_ui32 cached_has_bits = 0; + // Prevent compiler warnings about cached_has_bits being unused + (void) cached_has_bits; + + value_ = 0u; + _internal_metadata_.Clear<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(); +} + +const char* UInt32Value::_InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) { +#define CHK_(x) if (PROTOBUF_PREDICT_FALSE(!(x))) goto failure + while (!ctx->Done(&ptr)) { + arc_ui32 tag; + ptr = ::PROTOBUF_NAMESPACE_ID::internal::ReadTag(ptr, &tag); + switch (tag >> 3) { + // uint32 value = 1; + case 1: + if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 8)) { + value_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint32(&ptr); + CHK_(ptr); + } else + goto handle_unusual; + continue; + default: + goto handle_unusual; + } // switch + handle_unusual: + if ((tag == 0) || ((tag & 7) == 4)) { + CHK_(ptr); + ctx->SetLastTag(tag); + goto message_done; + } + ptr = UnknownFieldParse( + tag, + _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(), + ptr, ctx); + CHK_(ptr != nullptr); + } // while +message_done: + return ptr; +failure: + ptr = nullptr; + goto message_done; +#undef CHK_ +} + +uint8_t* UInt32Value::_InternalSerialize( + uint8_t* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const { + // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.UInt32Value) + arc_ui32 cached_has_bits = 0; + (void) cached_has_bits; + + // uint32 value = 1; + if (this->_internal_value() != 0) { + target = stream->EnsureSpace(target); + target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteUInt32ToArray(1, this->_internal_value(), target); + } + + if (PROTOBUF_PREDICT_FALSE(_internal_metadata_.have_unknown_fields())) { + target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::InternalSerializeUnknownFieldsToArray( + _internal_metadata_.unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(::PROTOBUF_NAMESPACE_ID::UnknownFieldSet::default_instance), target, stream); + } + // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.UInt32Value) + return target; +} + +size_t UInt32Value::ByteSizeLong() const { +// @@protoc_insertion_point(message_byte_size_start:google.protobuf.UInt32Value) + size_t total_size = 0; + + arc_ui32 cached_has_bits = 0; + // Prevent compiler warnings about cached_has_bits being unused + (void) cached_has_bits; + + // uint32 value = 1; + if (this->_internal_value() != 0) { + total_size += ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::UInt32SizePlusOne(this->_internal_value()); + } + + return MaybeComputeUnknownFieldsSize(total_size, &_cached_size_); +} + +const ::PROTOBUF_NAMESPACE_ID::Message::ClassData UInt32Value::_class_data_ = { + ::PROTOBUF_NAMESPACE_ID::Message::CopyWithSizeCheck, + UInt32Value::MergeImpl +}; +const ::PROTOBUF_NAMESPACE_ID::Message::ClassData*UInt32Value::GetClassData() const { return &_class_data_; } + +void UInt32Value::MergeImpl(::PROTOBUF_NAMESPACE_ID::Message* to, + const ::PROTOBUF_NAMESPACE_ID::Message& from) { + static_cast<UInt32Value *>(to)->MergeFrom( + static_cast<const UInt32Value &>(from)); +} + + +void UInt32Value::MergeFrom(const UInt32Value& from) { +// @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.UInt32Value) + GOOGLE_DCHECK_NE(&from, this); + arc_ui32 cached_has_bits = 0; + (void) cached_has_bits; + + if (from._internal_value() != 0) { + _internal_set_value(from._internal_value()); + } + _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_); +} + +void UInt32Value::CopyFrom(const UInt32Value& from) { +// @@protoc_insertion_point(class_specific_copy_from_start:google.protobuf.UInt32Value) + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool UInt32Value::IsInitialized() const { + return true; +} + +void UInt32Value::InternalSwap(UInt32Value* other) { + using std::swap; + _internal_metadata_.InternalSwap(&other->_internal_metadata_); + swap(value_, other->value_); +} + +::PROTOBUF_NAMESPACE_ID::Metadata UInt32Value::GetMetadata() const { + return ::PROTOBUF_NAMESPACE_ID::internal::AssignDescriptors( + &descriptor_table_google_2fprotobuf_2fwrappers_2eproto_getter, &descriptor_table_google_2fprotobuf_2fwrappers_2eproto_once, + file_level_metadata_google_2fprotobuf_2fwrappers_2eproto[5]); +} + +// =================================================================== + +class BoolValue::_Internal { + public: +}; + +BoolValue::BoolValue(::PROTOBUF_NAMESPACE_ID::Arena* arena, + bool is_message_owned) + : ::PROTOBUF_NAMESPACE_ID::Message(arena, is_message_owned) { + SharedCtor(); + if (!is_message_owned) { + RegisterArenaDtor(arena); + } + // @@protoc_insertion_point(arena_constructor:google.protobuf.BoolValue) +} +BoolValue::BoolValue(const BoolValue& from) + : ::PROTOBUF_NAMESPACE_ID::Message() { + _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_); + value_ = from.value_; + // @@protoc_insertion_point(copy_constructor:google.protobuf.BoolValue) +} + +inline void BoolValue::SharedCtor() { +value_ = false; +} + +BoolValue::~BoolValue() { + // @@protoc_insertion_point(destructor:google.protobuf.BoolValue) + if (GetArenaForAllocation() != nullptr) return; + SharedDtor(); + _internal_metadata_.Delete<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(); +} + +inline void BoolValue::SharedDtor() { + GOOGLE_DCHECK(GetArenaForAllocation() == nullptr); +} + +void BoolValue::ArenaDtor(void* object) { + BoolValue* _this = reinterpret_cast< BoolValue* >(object); + (void)_this; +} +void BoolValue::RegisterArenaDtor(::PROTOBUF_NAMESPACE_ID::Arena*) { +} +void BoolValue::SetCachedSize(int size) const { + _cached_size_.Set(size); +} + +void BoolValue::Clear() { +// @@protoc_insertion_point(message_clear_start:google.protobuf.BoolValue) + arc_ui32 cached_has_bits = 0; + // Prevent compiler warnings about cached_has_bits being unused + (void) cached_has_bits; + + value_ = false; + _internal_metadata_.Clear<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(); +} + +const char* BoolValue::_InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) { +#define CHK_(x) if (PROTOBUF_PREDICT_FALSE(!(x))) goto failure + while (!ctx->Done(&ptr)) { + arc_ui32 tag; + ptr = ::PROTOBUF_NAMESPACE_ID::internal::ReadTag(ptr, &tag); + switch (tag >> 3) { + // bool value = 1; + case 1: + if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 8)) { + value_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint64(&ptr); + CHK_(ptr); + } else + goto handle_unusual; + continue; + default: + goto handle_unusual; + } // switch + handle_unusual: + if ((tag == 0) || ((tag & 7) == 4)) { + CHK_(ptr); + ctx->SetLastTag(tag); + goto message_done; + } + ptr = UnknownFieldParse( + tag, + _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(), + ptr, ctx); + CHK_(ptr != nullptr); + } // while +message_done: + return ptr; +failure: + ptr = nullptr; + goto message_done; +#undef CHK_ +} + +uint8_t* BoolValue::_InternalSerialize( + uint8_t* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const { + // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.BoolValue) + arc_ui32 cached_has_bits = 0; + (void) cached_has_bits; + + // bool value = 1; + if (this->_internal_value() != 0) { + target = stream->EnsureSpace(target); + target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteBoolToArray(1, this->_internal_value(), target); + } + + if (PROTOBUF_PREDICT_FALSE(_internal_metadata_.have_unknown_fields())) { + target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::InternalSerializeUnknownFieldsToArray( + _internal_metadata_.unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(::PROTOBUF_NAMESPACE_ID::UnknownFieldSet::default_instance), target, stream); + } + // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.BoolValue) + return target; +} + +size_t BoolValue::ByteSizeLong() const { +// @@protoc_insertion_point(message_byte_size_start:google.protobuf.BoolValue) + size_t total_size = 0; + + arc_ui32 cached_has_bits = 0; + // Prevent compiler warnings about cached_has_bits being unused + (void) cached_has_bits; + + // bool value = 1; + if (this->_internal_value() != 0) { + total_size += 1 + 1; + } + + return MaybeComputeUnknownFieldsSize(total_size, &_cached_size_); +} + +const ::PROTOBUF_NAMESPACE_ID::Message::ClassData BoolValue::_class_data_ = { + ::PROTOBUF_NAMESPACE_ID::Message::CopyWithSizeCheck, + BoolValue::MergeImpl +}; +const ::PROTOBUF_NAMESPACE_ID::Message::ClassData*BoolValue::GetClassData() const { return &_class_data_; } + +void BoolValue::MergeImpl(::PROTOBUF_NAMESPACE_ID::Message* to, + const ::PROTOBUF_NAMESPACE_ID::Message& from) { + static_cast<BoolValue *>(to)->MergeFrom( + static_cast<const BoolValue &>(from)); +} + + +void BoolValue::MergeFrom(const BoolValue& from) { +// @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.BoolValue) + GOOGLE_DCHECK_NE(&from, this); + arc_ui32 cached_has_bits = 0; + (void) cached_has_bits; + + if (from._internal_value() != 0) { + _internal_set_value(from._internal_value()); + } + _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_); +} + +void BoolValue::CopyFrom(const BoolValue& from) { +// @@protoc_insertion_point(class_specific_copy_from_start:google.protobuf.BoolValue) + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool BoolValue::IsInitialized() const { + return true; +} + +void BoolValue::InternalSwap(BoolValue* other) { + using std::swap; + _internal_metadata_.InternalSwap(&other->_internal_metadata_); + swap(value_, other->value_); +} + +::PROTOBUF_NAMESPACE_ID::Metadata BoolValue::GetMetadata() const { + return ::PROTOBUF_NAMESPACE_ID::internal::AssignDescriptors( + &descriptor_table_google_2fprotobuf_2fwrappers_2eproto_getter, &descriptor_table_google_2fprotobuf_2fwrappers_2eproto_once, + file_level_metadata_google_2fprotobuf_2fwrappers_2eproto[6]); +} + +// =================================================================== + +class StringValue::_Internal { + public: +}; + +StringValue::StringValue(::PROTOBUF_NAMESPACE_ID::Arena* arena, + bool is_message_owned) + : ::PROTOBUF_NAMESPACE_ID::Message(arena, is_message_owned) { + SharedCtor(); + if (!is_message_owned) { + RegisterArenaDtor(arena); + } + // @@protoc_insertion_point(arena_constructor:google.protobuf.StringValue) +} +StringValue::StringValue(const StringValue& from) + : ::PROTOBUF_NAMESPACE_ID::Message() { + _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_); + value_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); + #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING + value_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation()); + #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING + if (!from._internal_value().empty()) { + value_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, from._internal_value(), + GetArenaForAllocation()); + } + // @@protoc_insertion_point(copy_constructor:google.protobuf.StringValue) +} + +inline void StringValue::SharedCtor() { +value_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); +#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING + value_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation()); +#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING +} + +StringValue::~StringValue() { + // @@protoc_insertion_point(destructor:google.protobuf.StringValue) + if (GetArenaForAllocation() != nullptr) return; + SharedDtor(); + _internal_metadata_.Delete<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(); +} + +inline void StringValue::SharedDtor() { + GOOGLE_DCHECK(GetArenaForAllocation() == nullptr); + value_.DestroyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); +} + +void StringValue::ArenaDtor(void* object) { + StringValue* _this = reinterpret_cast< StringValue* >(object); + (void)_this; +} +void StringValue::RegisterArenaDtor(::PROTOBUF_NAMESPACE_ID::Arena*) { +} +void StringValue::SetCachedSize(int size) const { + _cached_size_.Set(size); +} + +void StringValue::Clear() { +// @@protoc_insertion_point(message_clear_start:google.protobuf.StringValue) + arc_ui32 cached_has_bits = 0; + // Prevent compiler warnings about cached_has_bits being unused + (void) cached_has_bits; + + value_.ClearToEmpty(); + _internal_metadata_.Clear<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(); +} + +const char* StringValue::_InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) { +#define CHK_(x) if (PROTOBUF_PREDICT_FALSE(!(x))) goto failure + while (!ctx->Done(&ptr)) { + arc_ui32 tag; + ptr = ::PROTOBUF_NAMESPACE_ID::internal::ReadTag(ptr, &tag); + switch (tag >> 3) { + // string value = 1; + case 1: + if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 10)) { + auto str = _internal_mutable_value(); + ptr = ::PROTOBUF_NAMESPACE_ID::internal::InlineGreedyStringParser(str, ptr, ctx); + CHK_(::PROTOBUF_NAMESPACE_ID::internal::VerifyUTF8(str, "google.protobuf.StringValue.value")); + CHK_(ptr); + } else + goto handle_unusual; + continue; + default: + goto handle_unusual; + } // switch + handle_unusual: + if ((tag == 0) || ((tag & 7) == 4)) { + CHK_(ptr); + ctx->SetLastTag(tag); + goto message_done; + } + ptr = UnknownFieldParse( + tag, + _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(), + ptr, ctx); + CHK_(ptr != nullptr); + } // while +message_done: + return ptr; +failure: + ptr = nullptr; + goto message_done; +#undef CHK_ +} + +uint8_t* StringValue::_InternalSerialize( + uint8_t* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const { + // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.StringValue) + arc_ui32 cached_has_bits = 0; + (void) cached_has_bits; + + // string value = 1; + if (!this->_internal_value().empty()) { + ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::VerifyUtf8String( + this->_internal_value().data(), static_cast<int>(this->_internal_value().length()), + ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::SERIALIZE, + "google.protobuf.StringValue.value"); + target = stream->WriteStringMaybeAliased( + 1, this->_internal_value(), target); + } + + if (PROTOBUF_PREDICT_FALSE(_internal_metadata_.have_unknown_fields())) { + target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::InternalSerializeUnknownFieldsToArray( + _internal_metadata_.unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(::PROTOBUF_NAMESPACE_ID::UnknownFieldSet::default_instance), target, stream); + } + // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.StringValue) + return target; +} + +size_t StringValue::ByteSizeLong() const { +// @@protoc_insertion_point(message_byte_size_start:google.protobuf.StringValue) + size_t total_size = 0; + + arc_ui32 cached_has_bits = 0; + // Prevent compiler warnings about cached_has_bits being unused + (void) cached_has_bits; + + // string value = 1; + if (!this->_internal_value().empty()) { + total_size += 1 + + ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::StringSize( + this->_internal_value()); + } + + return MaybeComputeUnknownFieldsSize(total_size, &_cached_size_); +} + +const ::PROTOBUF_NAMESPACE_ID::Message::ClassData StringValue::_class_data_ = { + ::PROTOBUF_NAMESPACE_ID::Message::CopyWithSizeCheck, + StringValue::MergeImpl +}; +const ::PROTOBUF_NAMESPACE_ID::Message::ClassData*StringValue::GetClassData() const { return &_class_data_; } + +void StringValue::MergeImpl(::PROTOBUF_NAMESPACE_ID::Message* to, + const ::PROTOBUF_NAMESPACE_ID::Message& from) { + static_cast<StringValue *>(to)->MergeFrom( + static_cast<const StringValue &>(from)); +} + + +void StringValue::MergeFrom(const StringValue& from) { +// @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.StringValue) + GOOGLE_DCHECK_NE(&from, this); + arc_ui32 cached_has_bits = 0; + (void) cached_has_bits; + + if (!from._internal_value().empty()) { + _internal_set_value(from._internal_value()); + } + _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_); +} + +void StringValue::CopyFrom(const StringValue& from) { +// @@protoc_insertion_point(class_specific_copy_from_start:google.protobuf.StringValue) + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool StringValue::IsInitialized() const { + return true; +} + +void StringValue::InternalSwap(StringValue* other) { + using std::swap; + auto* lhs_arena = GetArenaForAllocation(); + auto* rhs_arena = other->GetArenaForAllocation(); + _internal_metadata_.InternalSwap(&other->_internal_metadata_); + ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::InternalSwap( + &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), + &value_, lhs_arena, + &other->value_, rhs_arena + ); +} + +::PROTOBUF_NAMESPACE_ID::Metadata StringValue::GetMetadata() const { + return ::PROTOBUF_NAMESPACE_ID::internal::AssignDescriptors( + &descriptor_table_google_2fprotobuf_2fwrappers_2eproto_getter, &descriptor_table_google_2fprotobuf_2fwrappers_2eproto_once, + file_level_metadata_google_2fprotobuf_2fwrappers_2eproto[7]); +} + +// =================================================================== + +class BytesValue::_Internal { + public: +}; + +BytesValue::BytesValue(::PROTOBUF_NAMESPACE_ID::Arena* arena, + bool is_message_owned) + : ::PROTOBUF_NAMESPACE_ID::Message(arena, is_message_owned) { + SharedCtor(); + if (!is_message_owned) { + RegisterArenaDtor(arena); + } + // @@protoc_insertion_point(arena_constructor:google.protobuf.BytesValue) +} +BytesValue::BytesValue(const BytesValue& from) + : ::PROTOBUF_NAMESPACE_ID::Message() { + _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_); + value_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); + #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING + value_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation()); + #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING + if (!from._internal_value().empty()) { + value_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, from._internal_value(), + GetArenaForAllocation()); + } + // @@protoc_insertion_point(copy_constructor:google.protobuf.BytesValue) +} + +inline void BytesValue::SharedCtor() { +value_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); +#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING + value_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation()); +#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING +} + +BytesValue::~BytesValue() { + // @@protoc_insertion_point(destructor:google.protobuf.BytesValue) + if (GetArenaForAllocation() != nullptr) return; + SharedDtor(); + _internal_metadata_.Delete<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(); +} + +inline void BytesValue::SharedDtor() { + GOOGLE_DCHECK(GetArenaForAllocation() == nullptr); + value_.DestroyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); +} + +void BytesValue::ArenaDtor(void* object) { + BytesValue* _this = reinterpret_cast< BytesValue* >(object); + (void)_this; +} +void BytesValue::RegisterArenaDtor(::PROTOBUF_NAMESPACE_ID::Arena*) { +} +void BytesValue::SetCachedSize(int size) const { + _cached_size_.Set(size); +} + +void BytesValue::Clear() { +// @@protoc_insertion_point(message_clear_start:google.protobuf.BytesValue) + arc_ui32 cached_has_bits = 0; + // Prevent compiler warnings about cached_has_bits being unused + (void) cached_has_bits; + + value_.ClearToEmpty(); + _internal_metadata_.Clear<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(); +} + +const char* BytesValue::_InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) { +#define CHK_(x) if (PROTOBUF_PREDICT_FALSE(!(x))) goto failure + while (!ctx->Done(&ptr)) { + arc_ui32 tag; + ptr = ::PROTOBUF_NAMESPACE_ID::internal::ReadTag(ptr, &tag); + switch (tag >> 3) { + // bytes value = 1; + case 1: + if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 10)) { + auto str = _internal_mutable_value(); + ptr = ::PROTOBUF_NAMESPACE_ID::internal::InlineGreedyStringParser(str, ptr, ctx); + CHK_(ptr); + } else + goto handle_unusual; + continue; + default: + goto handle_unusual; + } // switch + handle_unusual: + if ((tag == 0) || ((tag & 7) == 4)) { + CHK_(ptr); + ctx->SetLastTag(tag); + goto message_done; + } + ptr = UnknownFieldParse( + tag, + _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(), + ptr, ctx); + CHK_(ptr != nullptr); + } // while +message_done: + return ptr; +failure: + ptr = nullptr; + goto message_done; +#undef CHK_ +} + +uint8_t* BytesValue::_InternalSerialize( + uint8_t* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const { + // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.BytesValue) + arc_ui32 cached_has_bits = 0; + (void) cached_has_bits; + + // bytes value = 1; + if (!this->_internal_value().empty()) { + target = stream->WriteBytesMaybeAliased( + 1, this->_internal_value(), target); + } + + if (PROTOBUF_PREDICT_FALSE(_internal_metadata_.have_unknown_fields())) { + target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::InternalSerializeUnknownFieldsToArray( + _internal_metadata_.unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(::PROTOBUF_NAMESPACE_ID::UnknownFieldSet::default_instance), target, stream); + } + // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.BytesValue) + return target; +} + +size_t BytesValue::ByteSizeLong() const { +// @@protoc_insertion_point(message_byte_size_start:google.protobuf.BytesValue) + size_t total_size = 0; + + arc_ui32 cached_has_bits = 0; + // Prevent compiler warnings about cached_has_bits being unused + (void) cached_has_bits; + + // bytes value = 1; + if (!this->_internal_value().empty()) { + total_size += 1 + + ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::BytesSize( + this->_internal_value()); + } + + return MaybeComputeUnknownFieldsSize(total_size, &_cached_size_); +} + +const ::PROTOBUF_NAMESPACE_ID::Message::ClassData BytesValue::_class_data_ = { + ::PROTOBUF_NAMESPACE_ID::Message::CopyWithSizeCheck, + BytesValue::MergeImpl +}; +const ::PROTOBUF_NAMESPACE_ID::Message::ClassData*BytesValue::GetClassData() const { return &_class_data_; } + +void BytesValue::MergeImpl(::PROTOBUF_NAMESPACE_ID::Message* to, + const ::PROTOBUF_NAMESPACE_ID::Message& from) { + static_cast<BytesValue *>(to)->MergeFrom( + static_cast<const BytesValue &>(from)); +} + + +void BytesValue::MergeFrom(const BytesValue& from) { +// @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.BytesValue) + GOOGLE_DCHECK_NE(&from, this); + arc_ui32 cached_has_bits = 0; + (void) cached_has_bits; + + if (!from._internal_value().empty()) { + _internal_set_value(from._internal_value()); + } + _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_); +} + +void BytesValue::CopyFrom(const BytesValue& from) { +// @@protoc_insertion_point(class_specific_copy_from_start:google.protobuf.BytesValue) + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool BytesValue::IsInitialized() const { + return true; +} + +void BytesValue::InternalSwap(BytesValue* other) { + using std::swap; + auto* lhs_arena = GetArenaForAllocation(); + auto* rhs_arena = other->GetArenaForAllocation(); + _internal_metadata_.InternalSwap(&other->_internal_metadata_); + ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::InternalSwap( + &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), + &value_, lhs_arena, + &other->value_, rhs_arena + ); +} + +::PROTOBUF_NAMESPACE_ID::Metadata BytesValue::GetMetadata() const { + return ::PROTOBUF_NAMESPACE_ID::internal::AssignDescriptors( + &descriptor_table_google_2fprotobuf_2fwrappers_2eproto_getter, &descriptor_table_google_2fprotobuf_2fwrappers_2eproto_once, + file_level_metadata_google_2fprotobuf_2fwrappers_2eproto[8]); +} + +// @@protoc_insertion_point(namespace_scope) +PROTOBUF_NAMESPACE_CLOSE +PROTOBUF_NAMESPACE_OPEN +template<> PROTOBUF_NOINLINE ::PROTOBUF_NAMESPACE_ID::DoubleValue* Arena::CreateMaybeMessage< ::PROTOBUF_NAMESPACE_ID::DoubleValue >(Arena* arena) { + return Arena::CreateMessageInternal< ::PROTOBUF_NAMESPACE_ID::DoubleValue >(arena); +} +template<> PROTOBUF_NOINLINE ::PROTOBUF_NAMESPACE_ID::FloatValue* Arena::CreateMaybeMessage< ::PROTOBUF_NAMESPACE_ID::FloatValue >(Arena* arena) { + return Arena::CreateMessageInternal< ::PROTOBUF_NAMESPACE_ID::FloatValue >(arena); +} +template<> PROTOBUF_NOINLINE ::PROTOBUF_NAMESPACE_ID::Int64Value* Arena::CreateMaybeMessage< ::PROTOBUF_NAMESPACE_ID::Int64Value >(Arena* arena) { + return Arena::CreateMessageInternal< ::PROTOBUF_NAMESPACE_ID::Int64Value >(arena); +} +template<> PROTOBUF_NOINLINE ::PROTOBUF_NAMESPACE_ID::UInt64Value* Arena::CreateMaybeMessage< ::PROTOBUF_NAMESPACE_ID::UInt64Value >(Arena* arena) { + return Arena::CreateMessageInternal< ::PROTOBUF_NAMESPACE_ID::UInt64Value >(arena); +} +template<> PROTOBUF_NOINLINE ::PROTOBUF_NAMESPACE_ID::Int32Value* Arena::CreateMaybeMessage< ::PROTOBUF_NAMESPACE_ID::Int32Value >(Arena* arena) { + return Arena::CreateMessageInternal< ::PROTOBUF_NAMESPACE_ID::Int32Value >(arena); +} +template<> PROTOBUF_NOINLINE ::PROTOBUF_NAMESPACE_ID::UInt32Value* Arena::CreateMaybeMessage< ::PROTOBUF_NAMESPACE_ID::UInt32Value >(Arena* arena) { + return Arena::CreateMessageInternal< ::PROTOBUF_NAMESPACE_ID::UInt32Value >(arena); +} +template<> PROTOBUF_NOINLINE ::PROTOBUF_NAMESPACE_ID::BoolValue* Arena::CreateMaybeMessage< ::PROTOBUF_NAMESPACE_ID::BoolValue >(Arena* arena) { + return Arena::CreateMessageInternal< ::PROTOBUF_NAMESPACE_ID::BoolValue >(arena); +} +template<> PROTOBUF_NOINLINE ::PROTOBUF_NAMESPACE_ID::StringValue* Arena::CreateMaybeMessage< ::PROTOBUF_NAMESPACE_ID::StringValue >(Arena* arena) { + return Arena::CreateMessageInternal< ::PROTOBUF_NAMESPACE_ID::StringValue >(arena); +} +template<> PROTOBUF_NOINLINE ::PROTOBUF_NAMESPACE_ID::BytesValue* Arena::CreateMaybeMessage< ::PROTOBUF_NAMESPACE_ID::BytesValue >(Arena* arena) { + return Arena::CreateMessageInternal< ::PROTOBUF_NAMESPACE_ID::BytesValue >(arena); +} +PROTOBUF_NAMESPACE_CLOSE + +// @@protoc_insertion_point(global_scope) +#include <google/protobuf/port_undef.inc> diff --git a/contrib/libs/protobuf_old/src/google/protobuf/wrappers.pb.h b/contrib/libs/protobuf_old/src/google/protobuf/wrappers.pb.h new file mode 100644 index 0000000000..a827390303 --- /dev/null +++ b/contrib/libs/protobuf_old/src/google/protobuf/wrappers.pb.h @@ -0,0 +1,1734 @@ +// Generated by the protocol buffer compiler. DO NOT EDIT! +// source: google/protobuf/wrappers.proto + +#ifndef GOOGLE_PROTOBUF_INCLUDED_google_2fprotobuf_2fwrappers_2eproto +#define GOOGLE_PROTOBUF_INCLUDED_google_2fprotobuf_2fwrappers_2eproto + +#include <limits> +#include <string> + +#include <google/protobuf/port_def.inc> +#if PROTOBUF_VERSION < 3019000 +#error This file was generated by a newer version of protoc which is +#error incompatible with your Protocol Buffer headers. Please update +#error your headers. +#endif +#if 3019000 < PROTOBUF_MIN_PROTOC_VERSION +#error This file was generated by an older version of protoc which is +#error incompatible with your Protocol Buffer headers. Please +#error regenerate this file with a newer version of protoc. +#endif + +#include <google/protobuf/port_undef.inc> +#include <google/protobuf/io/coded_stream.h> +#include <google/protobuf/arena.h> +#include <google/protobuf/arenastring.h> +#include <google/protobuf/generated_message_table_driven.h> +#include <google/protobuf/generated_message_util.h> +#include <google/protobuf/metadata_lite.h> +#include <google/protobuf/generated_message_reflection.h> +#include <google/protobuf/message.h> +#include <google/protobuf/repeated_field.h> // IWYU pragma: export +#include <google/protobuf/extension_set.h> // IWYU pragma: export +#include <google/protobuf/unknown_field_set.h> +// @@protoc_insertion_point(includes) +#include <google/protobuf/port_def.inc> +#define PROTOBUF_INTERNAL_EXPORT_google_2fprotobuf_2fwrappers_2eproto PROTOBUF_EXPORT +PROTOBUF_NAMESPACE_OPEN +namespace internal { +class AnyMetadata; +} // namespace internal +PROTOBUF_NAMESPACE_CLOSE + +// Internal implementation detail -- do not use these members. +struct PROTOBUF_EXPORT TableStruct_google_2fprotobuf_2fwrappers_2eproto { + static const ::PROTOBUF_NAMESPACE_ID::internal::ParseTableField entries[] + PROTOBUF_SECTION_VARIABLE(protodesc_cold); + static const ::PROTOBUF_NAMESPACE_ID::internal::AuxiliaryParseTableField aux[] + PROTOBUF_SECTION_VARIABLE(protodesc_cold); + static const ::PROTOBUF_NAMESPACE_ID::internal::ParseTable schema[9] + PROTOBUF_SECTION_VARIABLE(protodesc_cold); + static const ::PROTOBUF_NAMESPACE_ID::internal::FieldMetadata field_metadata[]; + static const ::PROTOBUF_NAMESPACE_ID::internal::SerializationTable serialization_table[]; + static const arc_ui32 offsets[]; +}; +PROTOBUF_EXPORT extern const ::PROTOBUF_NAMESPACE_ID::internal::DescriptorTable descriptor_table_google_2fprotobuf_2fwrappers_2eproto; +PROTOBUF_NAMESPACE_OPEN +class BoolValue; +struct BoolValueDefaultTypeInternal; +PROTOBUF_EXPORT extern BoolValueDefaultTypeInternal _BoolValue_default_instance_; +class BytesValue; +struct BytesValueDefaultTypeInternal; +PROTOBUF_EXPORT extern BytesValueDefaultTypeInternal _BytesValue_default_instance_; +class DoubleValue; +struct DoubleValueDefaultTypeInternal; +PROTOBUF_EXPORT extern DoubleValueDefaultTypeInternal _DoubleValue_default_instance_; +class FloatValue; +struct FloatValueDefaultTypeInternal; +PROTOBUF_EXPORT extern FloatValueDefaultTypeInternal _FloatValue_default_instance_; +class Int32Value; +struct Int32ValueDefaultTypeInternal; +PROTOBUF_EXPORT extern Int32ValueDefaultTypeInternal _Int32Value_default_instance_; +class Int64Value; +struct Int64ValueDefaultTypeInternal; +PROTOBUF_EXPORT extern Int64ValueDefaultTypeInternal _Int64Value_default_instance_; +class StringValue; +struct StringValueDefaultTypeInternal; +PROTOBUF_EXPORT extern StringValueDefaultTypeInternal _StringValue_default_instance_; +class UInt32Value; +struct UInt32ValueDefaultTypeInternal; +PROTOBUF_EXPORT extern UInt32ValueDefaultTypeInternal _UInt32Value_default_instance_; +class UInt64Value; +struct UInt64ValueDefaultTypeInternal; +PROTOBUF_EXPORT extern UInt64ValueDefaultTypeInternal _UInt64Value_default_instance_; +PROTOBUF_NAMESPACE_CLOSE +PROTOBUF_NAMESPACE_OPEN +template<> PROTOBUF_EXPORT ::PROTOBUF_NAMESPACE_ID::BoolValue* Arena::CreateMaybeMessage<::PROTOBUF_NAMESPACE_ID::BoolValue>(Arena*); +template<> PROTOBUF_EXPORT ::PROTOBUF_NAMESPACE_ID::BytesValue* Arena::CreateMaybeMessage<::PROTOBUF_NAMESPACE_ID::BytesValue>(Arena*); +template<> PROTOBUF_EXPORT ::PROTOBUF_NAMESPACE_ID::DoubleValue* Arena::CreateMaybeMessage<::PROTOBUF_NAMESPACE_ID::DoubleValue>(Arena*); +template<> PROTOBUF_EXPORT ::PROTOBUF_NAMESPACE_ID::FloatValue* Arena::CreateMaybeMessage<::PROTOBUF_NAMESPACE_ID::FloatValue>(Arena*); +template<> PROTOBUF_EXPORT ::PROTOBUF_NAMESPACE_ID::Int32Value* Arena::CreateMaybeMessage<::PROTOBUF_NAMESPACE_ID::Int32Value>(Arena*); +template<> PROTOBUF_EXPORT ::PROTOBUF_NAMESPACE_ID::Int64Value* Arena::CreateMaybeMessage<::PROTOBUF_NAMESPACE_ID::Int64Value>(Arena*); +template<> PROTOBUF_EXPORT ::PROTOBUF_NAMESPACE_ID::StringValue* Arena::CreateMaybeMessage<::PROTOBUF_NAMESPACE_ID::StringValue>(Arena*); +template<> PROTOBUF_EXPORT ::PROTOBUF_NAMESPACE_ID::UInt32Value* Arena::CreateMaybeMessage<::PROTOBUF_NAMESPACE_ID::UInt32Value>(Arena*); +template<> PROTOBUF_EXPORT ::PROTOBUF_NAMESPACE_ID::UInt64Value* Arena::CreateMaybeMessage<::PROTOBUF_NAMESPACE_ID::UInt64Value>(Arena*); +PROTOBUF_NAMESPACE_CLOSE +PROTOBUF_NAMESPACE_OPEN + +// =================================================================== + +class PROTOBUF_EXPORT DoubleValue final : + public ::PROTOBUF_NAMESPACE_ID::Message /* @@protoc_insertion_point(class_definition:google.protobuf.DoubleValue) */ { + public: + inline DoubleValue() : DoubleValue(nullptr) {} + ~DoubleValue() override; + explicit constexpr DoubleValue(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized); + + DoubleValue(const DoubleValue& from); + DoubleValue(DoubleValue&& from) noexcept + : DoubleValue() { + *this = ::std::move(from); + } + + inline DoubleValue& operator=(const DoubleValue& from) { + CopyFrom(from); + return *this; + } + inline DoubleValue& operator=(DoubleValue&& from) noexcept { + if (this == &from) return *this; + if (GetOwningArena() == from.GetOwningArena() + #ifdef PROTOBUF_FORCE_COPY_IN_MOVE + && GetOwningArena() != nullptr + #endif // !PROTOBUF_FORCE_COPY_IN_MOVE + ) { + InternalSwap(&from); + } else { + CopyFrom(from); + } + return *this; + } + + static const ::PROTOBUF_NAMESPACE_ID::Descriptor* descriptor() { + return GetDescriptor(); + } + static const ::PROTOBUF_NAMESPACE_ID::Descriptor* GetDescriptor() { + return default_instance().GetMetadata().descriptor; + } + static const ::PROTOBUF_NAMESPACE_ID::Reflection* GetReflection() { + return default_instance().GetMetadata().reflection; + } + static const DoubleValue& default_instance() { + return *internal_default_instance(); + } + static inline const DoubleValue* internal_default_instance() { + return reinterpret_cast<const DoubleValue*>( + &_DoubleValue_default_instance_); + } + static constexpr int kIndexInFileMessages = + 0; + + friend void swap(DoubleValue& a, DoubleValue& b) { + a.Swap(&b); + } + inline void Swap(DoubleValue* other) { + if (other == this) return; + #ifdef PROTOBUF_FORCE_COPY_IN_SWAP + if (GetOwningArena() != nullptr && + GetOwningArena() == other->GetOwningArena()) { + #else // PROTOBUF_FORCE_COPY_IN_SWAP + if (GetOwningArena() == other->GetOwningArena()) { + #endif // !PROTOBUF_FORCE_COPY_IN_SWAP + InternalSwap(other); + } else { + ::PROTOBUF_NAMESPACE_ID::internal::GenericSwap(this, other); + } + } + void UnsafeArenaSwap(DoubleValue* other) { + if (other == this) return; + GOOGLE_DCHECK(GetOwningArena() == other->GetOwningArena()); + InternalSwap(other); + } + + // implements Message ---------------------------------------------- + + DoubleValue* New(::PROTOBUF_NAMESPACE_ID::Arena* arena = nullptr) const final { + return CreateMaybeMessage<DoubleValue>(arena); + } + using ::PROTOBUF_NAMESPACE_ID::Message::CopyFrom; + void CopyFrom(const DoubleValue& from); + using ::PROTOBUF_NAMESPACE_ID::Message::MergeFrom; + void MergeFrom(const DoubleValue& 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; + + size_t ByteSizeLong() const final; + const char* _InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) final; + uint8_t* _InternalSerialize( + uint8_t* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const final; + int GetCachedSize() const final { return _cached_size_.Get(); } + + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const final; + void InternalSwap(DoubleValue* other); + + private: + friend class ::PROTOBUF_NAMESPACE_ID::internal::AnyMetadata; + static ::PROTOBUF_NAMESPACE_ID::StringPiece FullMessageName() { + return "google.protobuf.DoubleValue"; + } + protected: + explicit DoubleValue(::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 ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + enum : int { + kValueFieldNumber = 1, + }; + // double value = 1; + void clear_value(); + double value() const; + void set_value(double value); + private: + double _internal_value() const; + void _internal_set_value(double value); + public: + + // @@protoc_insertion_point(class_scope:google.protobuf.DoubleValue) + private: + class _Internal; + + template <typename T> friend class ::PROTOBUF_NAMESPACE_ID::Arena::InternalHelper; + typedef void InternalArenaConstructable_; + typedef void DestructorSkippable_; + double value_; + mutable ::PROTOBUF_NAMESPACE_ID::internal::CachedSize _cached_size_; + friend struct ::TableStruct_google_2fprotobuf_2fwrappers_2eproto; +}; +// ------------------------------------------------------------------- + +class PROTOBUF_EXPORT FloatValue final : + public ::PROTOBUF_NAMESPACE_ID::Message /* @@protoc_insertion_point(class_definition:google.protobuf.FloatValue) */ { + public: + inline FloatValue() : FloatValue(nullptr) {} + ~FloatValue() override; + explicit constexpr FloatValue(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized); + + FloatValue(const FloatValue& from); + FloatValue(FloatValue&& from) noexcept + : FloatValue() { + *this = ::std::move(from); + } + + inline FloatValue& operator=(const FloatValue& from) { + CopyFrom(from); + return *this; + } + inline FloatValue& operator=(FloatValue&& from) noexcept { + if (this == &from) return *this; + if (GetOwningArena() == from.GetOwningArena() + #ifdef PROTOBUF_FORCE_COPY_IN_MOVE + && GetOwningArena() != nullptr + #endif // !PROTOBUF_FORCE_COPY_IN_MOVE + ) { + InternalSwap(&from); + } else { + CopyFrom(from); + } + return *this; + } + + static const ::PROTOBUF_NAMESPACE_ID::Descriptor* descriptor() { + return GetDescriptor(); + } + static const ::PROTOBUF_NAMESPACE_ID::Descriptor* GetDescriptor() { + return default_instance().GetMetadata().descriptor; + } + static const ::PROTOBUF_NAMESPACE_ID::Reflection* GetReflection() { + return default_instance().GetMetadata().reflection; + } + static const FloatValue& default_instance() { + return *internal_default_instance(); + } + static inline const FloatValue* internal_default_instance() { + return reinterpret_cast<const FloatValue*>( + &_FloatValue_default_instance_); + } + static constexpr int kIndexInFileMessages = + 1; + + friend void swap(FloatValue& a, FloatValue& b) { + a.Swap(&b); + } + inline void Swap(FloatValue* other) { + if (other == this) return; + #ifdef PROTOBUF_FORCE_COPY_IN_SWAP + if (GetOwningArena() != nullptr && + GetOwningArena() == other->GetOwningArena()) { + #else // PROTOBUF_FORCE_COPY_IN_SWAP + if (GetOwningArena() == other->GetOwningArena()) { + #endif // !PROTOBUF_FORCE_COPY_IN_SWAP + InternalSwap(other); + } else { + ::PROTOBUF_NAMESPACE_ID::internal::GenericSwap(this, other); + } + } + void UnsafeArenaSwap(FloatValue* other) { + if (other == this) return; + GOOGLE_DCHECK(GetOwningArena() == other->GetOwningArena()); + InternalSwap(other); + } + + // implements Message ---------------------------------------------- + + FloatValue* New(::PROTOBUF_NAMESPACE_ID::Arena* arena = nullptr) const final { + return CreateMaybeMessage<FloatValue>(arena); + } + using ::PROTOBUF_NAMESPACE_ID::Message::CopyFrom; + void CopyFrom(const FloatValue& from); + using ::PROTOBUF_NAMESPACE_ID::Message::MergeFrom; + void MergeFrom(const FloatValue& 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; + + size_t ByteSizeLong() const final; + const char* _InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) final; + uint8_t* _InternalSerialize( + uint8_t* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const final; + int GetCachedSize() const final { return _cached_size_.Get(); } + + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const final; + void InternalSwap(FloatValue* other); + + private: + friend class ::PROTOBUF_NAMESPACE_ID::internal::AnyMetadata; + static ::PROTOBUF_NAMESPACE_ID::StringPiece FullMessageName() { + return "google.protobuf.FloatValue"; + } + protected: + explicit FloatValue(::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 ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + enum : int { + kValueFieldNumber = 1, + }; + // float value = 1; + void clear_value(); + float value() const; + void set_value(float value); + private: + float _internal_value() const; + void _internal_set_value(float value); + public: + + // @@protoc_insertion_point(class_scope:google.protobuf.FloatValue) + private: + class _Internal; + + template <typename T> friend class ::PROTOBUF_NAMESPACE_ID::Arena::InternalHelper; + typedef void InternalArenaConstructable_; + typedef void DestructorSkippable_; + float value_; + mutable ::PROTOBUF_NAMESPACE_ID::internal::CachedSize _cached_size_; + friend struct ::TableStruct_google_2fprotobuf_2fwrappers_2eproto; +}; +// ------------------------------------------------------------------- + +class PROTOBUF_EXPORT Int64Value final : + public ::PROTOBUF_NAMESPACE_ID::Message /* @@protoc_insertion_point(class_definition:google.protobuf.Int64Value) */ { + public: + inline Int64Value() : Int64Value(nullptr) {} + ~Int64Value() override; + explicit constexpr Int64Value(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized); + + Int64Value(const Int64Value& from); + Int64Value(Int64Value&& from) noexcept + : Int64Value() { + *this = ::std::move(from); + } + + inline Int64Value& operator=(const Int64Value& from) { + CopyFrom(from); + return *this; + } + inline Int64Value& operator=(Int64Value&& from) noexcept { + if (this == &from) return *this; + if (GetOwningArena() == from.GetOwningArena() + #ifdef PROTOBUF_FORCE_COPY_IN_MOVE + && GetOwningArena() != nullptr + #endif // !PROTOBUF_FORCE_COPY_IN_MOVE + ) { + InternalSwap(&from); + } else { + CopyFrom(from); + } + return *this; + } + + static const ::PROTOBUF_NAMESPACE_ID::Descriptor* descriptor() { + return GetDescriptor(); + } + static const ::PROTOBUF_NAMESPACE_ID::Descriptor* GetDescriptor() { + return default_instance().GetMetadata().descriptor; + } + static const ::PROTOBUF_NAMESPACE_ID::Reflection* GetReflection() { + return default_instance().GetMetadata().reflection; + } + static const Int64Value& default_instance() { + return *internal_default_instance(); + } + static inline const Int64Value* internal_default_instance() { + return reinterpret_cast<const Int64Value*>( + &_Int64Value_default_instance_); + } + static constexpr int kIndexInFileMessages = + 2; + + friend void swap(Int64Value& a, Int64Value& b) { + a.Swap(&b); + } + inline void Swap(Int64Value* other) { + if (other == this) return; + #ifdef PROTOBUF_FORCE_COPY_IN_SWAP + if (GetOwningArena() != nullptr && + GetOwningArena() == other->GetOwningArena()) { + #else // PROTOBUF_FORCE_COPY_IN_SWAP + if (GetOwningArena() == other->GetOwningArena()) { + #endif // !PROTOBUF_FORCE_COPY_IN_SWAP + InternalSwap(other); + } else { + ::PROTOBUF_NAMESPACE_ID::internal::GenericSwap(this, other); + } + } + void UnsafeArenaSwap(Int64Value* other) { + if (other == this) return; + GOOGLE_DCHECK(GetOwningArena() == other->GetOwningArena()); + InternalSwap(other); + } + + // implements Message ---------------------------------------------- + + Int64Value* New(::PROTOBUF_NAMESPACE_ID::Arena* arena = nullptr) const final { + return CreateMaybeMessage<Int64Value>(arena); + } + using ::PROTOBUF_NAMESPACE_ID::Message::CopyFrom; + void CopyFrom(const Int64Value& from); + using ::PROTOBUF_NAMESPACE_ID::Message::MergeFrom; + void MergeFrom(const Int64Value& 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; + + size_t ByteSizeLong() const final; + const char* _InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) final; + uint8_t* _InternalSerialize( + uint8_t* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const final; + int GetCachedSize() const final { return _cached_size_.Get(); } + + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const final; + void InternalSwap(Int64Value* other); + + private: + friend class ::PROTOBUF_NAMESPACE_ID::internal::AnyMetadata; + static ::PROTOBUF_NAMESPACE_ID::StringPiece FullMessageName() { + return "google.protobuf.Int64Value"; + } + protected: + explicit Int64Value(::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 ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + enum : int { + kValueFieldNumber = 1, + }; + // int64 value = 1; + void clear_value(); + arc_i64 value() const; + void set_value(arc_i64 value); + private: + arc_i64 _internal_value() const; + void _internal_set_value(arc_i64 value); + public: + + // @@protoc_insertion_point(class_scope:google.protobuf.Int64Value) + private: + class _Internal; + + template <typename T> friend class ::PROTOBUF_NAMESPACE_ID::Arena::InternalHelper; + typedef void InternalArenaConstructable_; + typedef void DestructorSkippable_; + arc_i64 value_; + mutable ::PROTOBUF_NAMESPACE_ID::internal::CachedSize _cached_size_; + friend struct ::TableStruct_google_2fprotobuf_2fwrappers_2eproto; +}; +// ------------------------------------------------------------------- + +class PROTOBUF_EXPORT UInt64Value final : + public ::PROTOBUF_NAMESPACE_ID::Message /* @@protoc_insertion_point(class_definition:google.protobuf.UInt64Value) */ { + public: + inline UInt64Value() : UInt64Value(nullptr) {} + ~UInt64Value() override; + explicit constexpr UInt64Value(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized); + + UInt64Value(const UInt64Value& from); + UInt64Value(UInt64Value&& from) noexcept + : UInt64Value() { + *this = ::std::move(from); + } + + inline UInt64Value& operator=(const UInt64Value& from) { + CopyFrom(from); + return *this; + } + inline UInt64Value& operator=(UInt64Value&& from) noexcept { + if (this == &from) return *this; + if (GetOwningArena() == from.GetOwningArena() + #ifdef PROTOBUF_FORCE_COPY_IN_MOVE + && GetOwningArena() != nullptr + #endif // !PROTOBUF_FORCE_COPY_IN_MOVE + ) { + InternalSwap(&from); + } else { + CopyFrom(from); + } + return *this; + } + + static const ::PROTOBUF_NAMESPACE_ID::Descriptor* descriptor() { + return GetDescriptor(); + } + static const ::PROTOBUF_NAMESPACE_ID::Descriptor* GetDescriptor() { + return default_instance().GetMetadata().descriptor; + } + static const ::PROTOBUF_NAMESPACE_ID::Reflection* GetReflection() { + return default_instance().GetMetadata().reflection; + } + static const UInt64Value& default_instance() { + return *internal_default_instance(); + } + static inline const UInt64Value* internal_default_instance() { + return reinterpret_cast<const UInt64Value*>( + &_UInt64Value_default_instance_); + } + static constexpr int kIndexInFileMessages = + 3; + + friend void swap(UInt64Value& a, UInt64Value& b) { + a.Swap(&b); + } + inline void Swap(UInt64Value* other) { + if (other == this) return; + #ifdef PROTOBUF_FORCE_COPY_IN_SWAP + if (GetOwningArena() != nullptr && + GetOwningArena() == other->GetOwningArena()) { + #else // PROTOBUF_FORCE_COPY_IN_SWAP + if (GetOwningArena() == other->GetOwningArena()) { + #endif // !PROTOBUF_FORCE_COPY_IN_SWAP + InternalSwap(other); + } else { + ::PROTOBUF_NAMESPACE_ID::internal::GenericSwap(this, other); + } + } + void UnsafeArenaSwap(UInt64Value* other) { + if (other == this) return; + GOOGLE_DCHECK(GetOwningArena() == other->GetOwningArena()); + InternalSwap(other); + } + + // implements Message ---------------------------------------------- + + UInt64Value* New(::PROTOBUF_NAMESPACE_ID::Arena* arena = nullptr) const final { + return CreateMaybeMessage<UInt64Value>(arena); + } + using ::PROTOBUF_NAMESPACE_ID::Message::CopyFrom; + void CopyFrom(const UInt64Value& from); + using ::PROTOBUF_NAMESPACE_ID::Message::MergeFrom; + void MergeFrom(const UInt64Value& 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; + + size_t ByteSizeLong() const final; + const char* _InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) final; + uint8_t* _InternalSerialize( + uint8_t* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const final; + int GetCachedSize() const final { return _cached_size_.Get(); } + + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const final; + void InternalSwap(UInt64Value* other); + + private: + friend class ::PROTOBUF_NAMESPACE_ID::internal::AnyMetadata; + static ::PROTOBUF_NAMESPACE_ID::StringPiece FullMessageName() { + return "google.protobuf.UInt64Value"; + } + protected: + explicit UInt64Value(::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 ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + enum : int { + kValueFieldNumber = 1, + }; + // uint64 value = 1; + void clear_value(); + arc_ui64 value() const; + void set_value(arc_ui64 value); + private: + arc_ui64 _internal_value() const; + void _internal_set_value(arc_ui64 value); + public: + + // @@protoc_insertion_point(class_scope:google.protobuf.UInt64Value) + private: + class _Internal; + + template <typename T> friend class ::PROTOBUF_NAMESPACE_ID::Arena::InternalHelper; + typedef void InternalArenaConstructable_; + typedef void DestructorSkippable_; + arc_ui64 value_; + mutable ::PROTOBUF_NAMESPACE_ID::internal::CachedSize _cached_size_; + friend struct ::TableStruct_google_2fprotobuf_2fwrappers_2eproto; +}; +// ------------------------------------------------------------------- + +class PROTOBUF_EXPORT Int32Value final : + public ::PROTOBUF_NAMESPACE_ID::Message /* @@protoc_insertion_point(class_definition:google.protobuf.Int32Value) */ { + public: + inline Int32Value() : Int32Value(nullptr) {} + ~Int32Value() override; + explicit constexpr Int32Value(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized); + + Int32Value(const Int32Value& from); + Int32Value(Int32Value&& from) noexcept + : Int32Value() { + *this = ::std::move(from); + } + + inline Int32Value& operator=(const Int32Value& from) { + CopyFrom(from); + return *this; + } + inline Int32Value& operator=(Int32Value&& from) noexcept { + if (this == &from) return *this; + if (GetOwningArena() == from.GetOwningArena() + #ifdef PROTOBUF_FORCE_COPY_IN_MOVE + && GetOwningArena() != nullptr + #endif // !PROTOBUF_FORCE_COPY_IN_MOVE + ) { + InternalSwap(&from); + } else { + CopyFrom(from); + } + return *this; + } + + static const ::PROTOBUF_NAMESPACE_ID::Descriptor* descriptor() { + return GetDescriptor(); + } + static const ::PROTOBUF_NAMESPACE_ID::Descriptor* GetDescriptor() { + return default_instance().GetMetadata().descriptor; + } + static const ::PROTOBUF_NAMESPACE_ID::Reflection* GetReflection() { + return default_instance().GetMetadata().reflection; + } + static const Int32Value& default_instance() { + return *internal_default_instance(); + } + static inline const Int32Value* internal_default_instance() { + return reinterpret_cast<const Int32Value*>( + &_Int32Value_default_instance_); + } + static constexpr int kIndexInFileMessages = + 4; + + friend void swap(Int32Value& a, Int32Value& b) { + a.Swap(&b); + } + inline void Swap(Int32Value* other) { + if (other == this) return; + #ifdef PROTOBUF_FORCE_COPY_IN_SWAP + if (GetOwningArena() != nullptr && + GetOwningArena() == other->GetOwningArena()) { + #else // PROTOBUF_FORCE_COPY_IN_SWAP + if (GetOwningArena() == other->GetOwningArena()) { + #endif // !PROTOBUF_FORCE_COPY_IN_SWAP + InternalSwap(other); + } else { + ::PROTOBUF_NAMESPACE_ID::internal::GenericSwap(this, other); + } + } + void UnsafeArenaSwap(Int32Value* other) { + if (other == this) return; + GOOGLE_DCHECK(GetOwningArena() == other->GetOwningArena()); + InternalSwap(other); + } + + // implements Message ---------------------------------------------- + + Int32Value* New(::PROTOBUF_NAMESPACE_ID::Arena* arena = nullptr) const final { + return CreateMaybeMessage<Int32Value>(arena); + } + using ::PROTOBUF_NAMESPACE_ID::Message::CopyFrom; + void CopyFrom(const Int32Value& from); + using ::PROTOBUF_NAMESPACE_ID::Message::MergeFrom; + void MergeFrom(const Int32Value& 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; + + size_t ByteSizeLong() const final; + const char* _InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) final; + uint8_t* _InternalSerialize( + uint8_t* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const final; + int GetCachedSize() const final { return _cached_size_.Get(); } + + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const final; + void InternalSwap(Int32Value* other); + + private: + friend class ::PROTOBUF_NAMESPACE_ID::internal::AnyMetadata; + static ::PROTOBUF_NAMESPACE_ID::StringPiece FullMessageName() { + return "google.protobuf.Int32Value"; + } + protected: + explicit Int32Value(::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 ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + enum : int { + kValueFieldNumber = 1, + }; + // int32 value = 1; + void clear_value(); + arc_i32 value() const; + void set_value(arc_i32 value); + private: + arc_i32 _internal_value() const; + void _internal_set_value(arc_i32 value); + public: + + // @@protoc_insertion_point(class_scope:google.protobuf.Int32Value) + private: + class _Internal; + + template <typename T> friend class ::PROTOBUF_NAMESPACE_ID::Arena::InternalHelper; + typedef void InternalArenaConstructable_; + typedef void DestructorSkippable_; + arc_i32 value_; + mutable ::PROTOBUF_NAMESPACE_ID::internal::CachedSize _cached_size_; + friend struct ::TableStruct_google_2fprotobuf_2fwrappers_2eproto; +}; +// ------------------------------------------------------------------- + +class PROTOBUF_EXPORT UInt32Value final : + public ::PROTOBUF_NAMESPACE_ID::Message /* @@protoc_insertion_point(class_definition:google.protobuf.UInt32Value) */ { + public: + inline UInt32Value() : UInt32Value(nullptr) {} + ~UInt32Value() override; + explicit constexpr UInt32Value(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized); + + UInt32Value(const UInt32Value& from); + UInt32Value(UInt32Value&& from) noexcept + : UInt32Value() { + *this = ::std::move(from); + } + + inline UInt32Value& operator=(const UInt32Value& from) { + CopyFrom(from); + return *this; + } + inline UInt32Value& operator=(UInt32Value&& from) noexcept { + if (this == &from) return *this; + if (GetOwningArena() == from.GetOwningArena() + #ifdef PROTOBUF_FORCE_COPY_IN_MOVE + && GetOwningArena() != nullptr + #endif // !PROTOBUF_FORCE_COPY_IN_MOVE + ) { + InternalSwap(&from); + } else { + CopyFrom(from); + } + return *this; + } + + static const ::PROTOBUF_NAMESPACE_ID::Descriptor* descriptor() { + return GetDescriptor(); + } + static const ::PROTOBUF_NAMESPACE_ID::Descriptor* GetDescriptor() { + return default_instance().GetMetadata().descriptor; + } + static const ::PROTOBUF_NAMESPACE_ID::Reflection* GetReflection() { + return default_instance().GetMetadata().reflection; + } + static const UInt32Value& default_instance() { + return *internal_default_instance(); + } + static inline const UInt32Value* internal_default_instance() { + return reinterpret_cast<const UInt32Value*>( + &_UInt32Value_default_instance_); + } + static constexpr int kIndexInFileMessages = + 5; + + friend void swap(UInt32Value& a, UInt32Value& b) { + a.Swap(&b); + } + inline void Swap(UInt32Value* other) { + if (other == this) return; + #ifdef PROTOBUF_FORCE_COPY_IN_SWAP + if (GetOwningArena() != nullptr && + GetOwningArena() == other->GetOwningArena()) { + #else // PROTOBUF_FORCE_COPY_IN_SWAP + if (GetOwningArena() == other->GetOwningArena()) { + #endif // !PROTOBUF_FORCE_COPY_IN_SWAP + InternalSwap(other); + } else { + ::PROTOBUF_NAMESPACE_ID::internal::GenericSwap(this, other); + } + } + void UnsafeArenaSwap(UInt32Value* other) { + if (other == this) return; + GOOGLE_DCHECK(GetOwningArena() == other->GetOwningArena()); + InternalSwap(other); + } + + // implements Message ---------------------------------------------- + + UInt32Value* New(::PROTOBUF_NAMESPACE_ID::Arena* arena = nullptr) const final { + return CreateMaybeMessage<UInt32Value>(arena); + } + using ::PROTOBUF_NAMESPACE_ID::Message::CopyFrom; + void CopyFrom(const UInt32Value& from); + using ::PROTOBUF_NAMESPACE_ID::Message::MergeFrom; + void MergeFrom(const UInt32Value& 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; + + size_t ByteSizeLong() const final; + const char* _InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) final; + uint8_t* _InternalSerialize( + uint8_t* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const final; + int GetCachedSize() const final { return _cached_size_.Get(); } + + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const final; + void InternalSwap(UInt32Value* other); + + private: + friend class ::PROTOBUF_NAMESPACE_ID::internal::AnyMetadata; + static ::PROTOBUF_NAMESPACE_ID::StringPiece FullMessageName() { + return "google.protobuf.UInt32Value"; + } + protected: + explicit UInt32Value(::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 ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + enum : int { + kValueFieldNumber = 1, + }; + // uint32 value = 1; + void clear_value(); + arc_ui32 value() const; + void set_value(arc_ui32 value); + private: + arc_ui32 _internal_value() const; + void _internal_set_value(arc_ui32 value); + public: + + // @@protoc_insertion_point(class_scope:google.protobuf.UInt32Value) + private: + class _Internal; + + template <typename T> friend class ::PROTOBUF_NAMESPACE_ID::Arena::InternalHelper; + typedef void InternalArenaConstructable_; + typedef void DestructorSkippable_; + arc_ui32 value_; + mutable ::PROTOBUF_NAMESPACE_ID::internal::CachedSize _cached_size_; + friend struct ::TableStruct_google_2fprotobuf_2fwrappers_2eproto; +}; +// ------------------------------------------------------------------- + +class PROTOBUF_EXPORT BoolValue final : + public ::PROTOBUF_NAMESPACE_ID::Message /* @@protoc_insertion_point(class_definition:google.protobuf.BoolValue) */ { + public: + inline BoolValue() : BoolValue(nullptr) {} + ~BoolValue() override; + explicit constexpr BoolValue(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized); + + BoolValue(const BoolValue& from); + BoolValue(BoolValue&& from) noexcept + : BoolValue() { + *this = ::std::move(from); + } + + inline BoolValue& operator=(const BoolValue& from) { + CopyFrom(from); + return *this; + } + inline BoolValue& operator=(BoolValue&& from) noexcept { + if (this == &from) return *this; + if (GetOwningArena() == from.GetOwningArena() + #ifdef PROTOBUF_FORCE_COPY_IN_MOVE + && GetOwningArena() != nullptr + #endif // !PROTOBUF_FORCE_COPY_IN_MOVE + ) { + InternalSwap(&from); + } else { + CopyFrom(from); + } + return *this; + } + + static const ::PROTOBUF_NAMESPACE_ID::Descriptor* descriptor() { + return GetDescriptor(); + } + static const ::PROTOBUF_NAMESPACE_ID::Descriptor* GetDescriptor() { + return default_instance().GetMetadata().descriptor; + } + static const ::PROTOBUF_NAMESPACE_ID::Reflection* GetReflection() { + return default_instance().GetMetadata().reflection; + } + static const BoolValue& default_instance() { + return *internal_default_instance(); + } + static inline const BoolValue* internal_default_instance() { + return reinterpret_cast<const BoolValue*>( + &_BoolValue_default_instance_); + } + static constexpr int kIndexInFileMessages = + 6; + + friend void swap(BoolValue& a, BoolValue& b) { + a.Swap(&b); + } + inline void Swap(BoolValue* other) { + if (other == this) return; + #ifdef PROTOBUF_FORCE_COPY_IN_SWAP + if (GetOwningArena() != nullptr && + GetOwningArena() == other->GetOwningArena()) { + #else // PROTOBUF_FORCE_COPY_IN_SWAP + if (GetOwningArena() == other->GetOwningArena()) { + #endif // !PROTOBUF_FORCE_COPY_IN_SWAP + InternalSwap(other); + } else { + ::PROTOBUF_NAMESPACE_ID::internal::GenericSwap(this, other); + } + } + void UnsafeArenaSwap(BoolValue* other) { + if (other == this) return; + GOOGLE_DCHECK(GetOwningArena() == other->GetOwningArena()); + InternalSwap(other); + } + + // implements Message ---------------------------------------------- + + BoolValue* New(::PROTOBUF_NAMESPACE_ID::Arena* arena = nullptr) const final { + return CreateMaybeMessage<BoolValue>(arena); + } + using ::PROTOBUF_NAMESPACE_ID::Message::CopyFrom; + void CopyFrom(const BoolValue& from); + using ::PROTOBUF_NAMESPACE_ID::Message::MergeFrom; + void MergeFrom(const BoolValue& 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; + + size_t ByteSizeLong() const final; + const char* _InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) final; + uint8_t* _InternalSerialize( + uint8_t* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const final; + int GetCachedSize() const final { return _cached_size_.Get(); } + + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const final; + void InternalSwap(BoolValue* other); + + private: + friend class ::PROTOBUF_NAMESPACE_ID::internal::AnyMetadata; + static ::PROTOBUF_NAMESPACE_ID::StringPiece FullMessageName() { + return "google.protobuf.BoolValue"; + } + protected: + explicit BoolValue(::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 ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + enum : int { + kValueFieldNumber = 1, + }; + // bool value = 1; + void clear_value(); + bool value() const; + void set_value(bool value); + private: + bool _internal_value() const; + void _internal_set_value(bool value); + public: + + // @@protoc_insertion_point(class_scope:google.protobuf.BoolValue) + private: + class _Internal; + + template <typename T> friend class ::PROTOBUF_NAMESPACE_ID::Arena::InternalHelper; + typedef void InternalArenaConstructable_; + typedef void DestructorSkippable_; + bool value_; + mutable ::PROTOBUF_NAMESPACE_ID::internal::CachedSize _cached_size_; + friend struct ::TableStruct_google_2fprotobuf_2fwrappers_2eproto; +}; +// ------------------------------------------------------------------- + +class PROTOBUF_EXPORT StringValue final : + public ::PROTOBUF_NAMESPACE_ID::Message /* @@protoc_insertion_point(class_definition:google.protobuf.StringValue) */ { + public: + inline StringValue() : StringValue(nullptr) {} + ~StringValue() override; + explicit constexpr StringValue(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized); + + StringValue(const StringValue& from); + StringValue(StringValue&& from) noexcept + : StringValue() { + *this = ::std::move(from); + } + + inline StringValue& operator=(const StringValue& from) { + CopyFrom(from); + return *this; + } + inline StringValue& operator=(StringValue&& from) noexcept { + if (this == &from) return *this; + if (GetOwningArena() == from.GetOwningArena() + #ifdef PROTOBUF_FORCE_COPY_IN_MOVE + && GetOwningArena() != nullptr + #endif // !PROTOBUF_FORCE_COPY_IN_MOVE + ) { + InternalSwap(&from); + } else { + CopyFrom(from); + } + return *this; + } + + static const ::PROTOBUF_NAMESPACE_ID::Descriptor* descriptor() { + return GetDescriptor(); + } + static const ::PROTOBUF_NAMESPACE_ID::Descriptor* GetDescriptor() { + return default_instance().GetMetadata().descriptor; + } + static const ::PROTOBUF_NAMESPACE_ID::Reflection* GetReflection() { + return default_instance().GetMetadata().reflection; + } + static const StringValue& default_instance() { + return *internal_default_instance(); + } + static inline const StringValue* internal_default_instance() { + return reinterpret_cast<const StringValue*>( + &_StringValue_default_instance_); + } + static constexpr int kIndexInFileMessages = + 7; + + friend void swap(StringValue& a, StringValue& b) { + a.Swap(&b); + } + inline void Swap(StringValue* other) { + if (other == this) return; + #ifdef PROTOBUF_FORCE_COPY_IN_SWAP + if (GetOwningArena() != nullptr && + GetOwningArena() == other->GetOwningArena()) { + #else // PROTOBUF_FORCE_COPY_IN_SWAP + if (GetOwningArena() == other->GetOwningArena()) { + #endif // !PROTOBUF_FORCE_COPY_IN_SWAP + InternalSwap(other); + } else { + ::PROTOBUF_NAMESPACE_ID::internal::GenericSwap(this, other); + } + } + void UnsafeArenaSwap(StringValue* other) { + if (other == this) return; + GOOGLE_DCHECK(GetOwningArena() == other->GetOwningArena()); + InternalSwap(other); + } + + // implements Message ---------------------------------------------- + + StringValue* New(::PROTOBUF_NAMESPACE_ID::Arena* arena = nullptr) const final { + return CreateMaybeMessage<StringValue>(arena); + } + using ::PROTOBUF_NAMESPACE_ID::Message::CopyFrom; + void CopyFrom(const StringValue& from); + using ::PROTOBUF_NAMESPACE_ID::Message::MergeFrom; + void MergeFrom(const StringValue& 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; + + size_t ByteSizeLong() const final; + const char* _InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) final; + uint8_t* _InternalSerialize( + uint8_t* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const final; + int GetCachedSize() const final { return _cached_size_.Get(); } + + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const final; + void InternalSwap(StringValue* other); + + private: + friend class ::PROTOBUF_NAMESPACE_ID::internal::AnyMetadata; + static ::PROTOBUF_NAMESPACE_ID::StringPiece FullMessageName() { + return "google.protobuf.StringValue"; + } + protected: + explicit StringValue(::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 ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + enum : int { + kValueFieldNumber = 1, + }; + // string value = 1; + void clear_value(); + const TProtoStringType& value() const; + template <typename ArgT0 = const TProtoStringType&, typename... ArgT> + void set_value(ArgT0&& arg0, ArgT... args); + TProtoStringType* mutable_value(); + PROTOBUF_NODISCARD TProtoStringType* release_value(); + void set_allocated_value(TProtoStringType* value); + private: + const TProtoStringType& _internal_value() const; + inline PROTOBUF_ALWAYS_INLINE void _internal_set_value(const TProtoStringType& value); + TProtoStringType* _internal_mutable_value(); + public: + + // @@protoc_insertion_point(class_scope:google.protobuf.StringValue) + private: + class _Internal; + + template <typename T> friend class ::PROTOBUF_NAMESPACE_ID::Arena::InternalHelper; + typedef void InternalArenaConstructable_; + typedef void DestructorSkippable_; + ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr value_; + mutable ::PROTOBUF_NAMESPACE_ID::internal::CachedSize _cached_size_; + friend struct ::TableStruct_google_2fprotobuf_2fwrappers_2eproto; +}; +// ------------------------------------------------------------------- + +class PROTOBUF_EXPORT BytesValue final : + public ::PROTOBUF_NAMESPACE_ID::Message /* @@protoc_insertion_point(class_definition:google.protobuf.BytesValue) */ { + public: + inline BytesValue() : BytesValue(nullptr) {} + ~BytesValue() override; + explicit constexpr BytesValue(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized); + + BytesValue(const BytesValue& from); + BytesValue(BytesValue&& from) noexcept + : BytesValue() { + *this = ::std::move(from); + } + + inline BytesValue& operator=(const BytesValue& from) { + CopyFrom(from); + return *this; + } + inline BytesValue& operator=(BytesValue&& from) noexcept { + if (this == &from) return *this; + if (GetOwningArena() == from.GetOwningArena() + #ifdef PROTOBUF_FORCE_COPY_IN_MOVE + && GetOwningArena() != nullptr + #endif // !PROTOBUF_FORCE_COPY_IN_MOVE + ) { + InternalSwap(&from); + } else { + CopyFrom(from); + } + return *this; + } + + static const ::PROTOBUF_NAMESPACE_ID::Descriptor* descriptor() { + return GetDescriptor(); + } + static const ::PROTOBUF_NAMESPACE_ID::Descriptor* GetDescriptor() { + return default_instance().GetMetadata().descriptor; + } + static const ::PROTOBUF_NAMESPACE_ID::Reflection* GetReflection() { + return default_instance().GetMetadata().reflection; + } + static const BytesValue& default_instance() { + return *internal_default_instance(); + } + static inline const BytesValue* internal_default_instance() { + return reinterpret_cast<const BytesValue*>( + &_BytesValue_default_instance_); + } + static constexpr int kIndexInFileMessages = + 8; + + friend void swap(BytesValue& a, BytesValue& b) { + a.Swap(&b); + } + inline void Swap(BytesValue* other) { + if (other == this) return; + #ifdef PROTOBUF_FORCE_COPY_IN_SWAP + if (GetOwningArena() != nullptr && + GetOwningArena() == other->GetOwningArena()) { + #else // PROTOBUF_FORCE_COPY_IN_SWAP + if (GetOwningArena() == other->GetOwningArena()) { + #endif // !PROTOBUF_FORCE_COPY_IN_SWAP + InternalSwap(other); + } else { + ::PROTOBUF_NAMESPACE_ID::internal::GenericSwap(this, other); + } + } + void UnsafeArenaSwap(BytesValue* other) { + if (other == this) return; + GOOGLE_DCHECK(GetOwningArena() == other->GetOwningArena()); + InternalSwap(other); + } + + // implements Message ---------------------------------------------- + + BytesValue* New(::PROTOBUF_NAMESPACE_ID::Arena* arena = nullptr) const final { + return CreateMaybeMessage<BytesValue>(arena); + } + using ::PROTOBUF_NAMESPACE_ID::Message::CopyFrom; + void CopyFrom(const BytesValue& from); + using ::PROTOBUF_NAMESPACE_ID::Message::MergeFrom; + void MergeFrom(const BytesValue& 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; + + size_t ByteSizeLong() const final; + const char* _InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) final; + uint8_t* _InternalSerialize( + uint8_t* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const final; + int GetCachedSize() const final { return _cached_size_.Get(); } + + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const final; + void InternalSwap(BytesValue* other); + + private: + friend class ::PROTOBUF_NAMESPACE_ID::internal::AnyMetadata; + static ::PROTOBUF_NAMESPACE_ID::StringPiece FullMessageName() { + return "google.protobuf.BytesValue"; + } + protected: + explicit BytesValue(::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 ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + enum : int { + kValueFieldNumber = 1, + }; + // bytes value = 1; + void clear_value(); + const TProtoStringType& value() const; + template <typename ArgT0 = const TProtoStringType&, typename... ArgT> + void set_value(ArgT0&& arg0, ArgT... args); + TProtoStringType* mutable_value(); + PROTOBUF_NODISCARD TProtoStringType* release_value(); + void set_allocated_value(TProtoStringType* value); + private: + const TProtoStringType& _internal_value() const; + inline PROTOBUF_ALWAYS_INLINE void _internal_set_value(const TProtoStringType& value); + TProtoStringType* _internal_mutable_value(); + public: + + // @@protoc_insertion_point(class_scope:google.protobuf.BytesValue) + private: + class _Internal; + + template <typename T> friend class ::PROTOBUF_NAMESPACE_ID::Arena::InternalHelper; + typedef void InternalArenaConstructable_; + typedef void DestructorSkippable_; + ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr value_; + mutable ::PROTOBUF_NAMESPACE_ID::internal::CachedSize _cached_size_; + friend struct ::TableStruct_google_2fprotobuf_2fwrappers_2eproto; +}; +// =================================================================== + + +// =================================================================== + +#ifdef __GNUC__ + #pragma GCC diagnostic push + #pragma GCC diagnostic ignored "-Wstrict-aliasing" +#endif // __GNUC__ +// DoubleValue + +// double value = 1; +inline void DoubleValue::clear_value() { + value_ = 0; +} +inline double DoubleValue::_internal_value() const { + return value_; +} +inline double DoubleValue::value() const { + // @@protoc_insertion_point(field_get:google.protobuf.DoubleValue.value) + return _internal_value(); +} +inline void DoubleValue::_internal_set_value(double value) { + + value_ = value; +} +inline void DoubleValue::set_value(double value) { + _internal_set_value(value); + // @@protoc_insertion_point(field_set:google.protobuf.DoubleValue.value) +} + +// ------------------------------------------------------------------- + +// FloatValue + +// float value = 1; +inline void FloatValue::clear_value() { + value_ = 0; +} +inline float FloatValue::_internal_value() const { + return value_; +} +inline float FloatValue::value() const { + // @@protoc_insertion_point(field_get:google.protobuf.FloatValue.value) + return _internal_value(); +} +inline void FloatValue::_internal_set_value(float value) { + + value_ = value; +} +inline void FloatValue::set_value(float value) { + _internal_set_value(value); + // @@protoc_insertion_point(field_set:google.protobuf.FloatValue.value) +} + +// ------------------------------------------------------------------- + +// Int64Value + +// int64 value = 1; +inline void Int64Value::clear_value() { + value_ = arc_i64{0}; +} +inline arc_i64 Int64Value::_internal_value() const { + return value_; +} +inline arc_i64 Int64Value::value() const { + // @@protoc_insertion_point(field_get:google.protobuf.Int64Value.value) + return _internal_value(); +} +inline void Int64Value::_internal_set_value(arc_i64 value) { + + value_ = value; +} +inline void Int64Value::set_value(arc_i64 value) { + _internal_set_value(value); + // @@protoc_insertion_point(field_set:google.protobuf.Int64Value.value) +} + +// ------------------------------------------------------------------- + +// UInt64Value + +// uint64 value = 1; +inline void UInt64Value::clear_value() { + value_ = arc_ui64{0u}; +} +inline arc_ui64 UInt64Value::_internal_value() const { + return value_; +} +inline arc_ui64 UInt64Value::value() const { + // @@protoc_insertion_point(field_get:google.protobuf.UInt64Value.value) + return _internal_value(); +} +inline void UInt64Value::_internal_set_value(arc_ui64 value) { + + value_ = value; +} +inline void UInt64Value::set_value(arc_ui64 value) { + _internal_set_value(value); + // @@protoc_insertion_point(field_set:google.protobuf.UInt64Value.value) +} + +// ------------------------------------------------------------------- + +// Int32Value + +// int32 value = 1; +inline void Int32Value::clear_value() { + value_ = 0; +} +inline arc_i32 Int32Value::_internal_value() const { + return value_; +} +inline arc_i32 Int32Value::value() const { + // @@protoc_insertion_point(field_get:google.protobuf.Int32Value.value) + return _internal_value(); +} +inline void Int32Value::_internal_set_value(arc_i32 value) { + + value_ = value; +} +inline void Int32Value::set_value(arc_i32 value) { + _internal_set_value(value); + // @@protoc_insertion_point(field_set:google.protobuf.Int32Value.value) +} + +// ------------------------------------------------------------------- + +// UInt32Value + +// uint32 value = 1; +inline void UInt32Value::clear_value() { + value_ = 0u; +} +inline arc_ui32 UInt32Value::_internal_value() const { + return value_; +} +inline arc_ui32 UInt32Value::value() const { + // @@protoc_insertion_point(field_get:google.protobuf.UInt32Value.value) + return _internal_value(); +} +inline void UInt32Value::_internal_set_value(arc_ui32 value) { + + value_ = value; +} +inline void UInt32Value::set_value(arc_ui32 value) { + _internal_set_value(value); + // @@protoc_insertion_point(field_set:google.protobuf.UInt32Value.value) +} + +// ------------------------------------------------------------------- + +// BoolValue + +// bool value = 1; +inline void BoolValue::clear_value() { + value_ = false; +} +inline bool BoolValue::_internal_value() const { + return value_; +} +inline bool BoolValue::value() const { + // @@protoc_insertion_point(field_get:google.protobuf.BoolValue.value) + return _internal_value(); +} +inline void BoolValue::_internal_set_value(bool value) { + + value_ = value; +} +inline void BoolValue::set_value(bool value) { + _internal_set_value(value); + // @@protoc_insertion_point(field_set:google.protobuf.BoolValue.value) +} + +// ------------------------------------------------------------------- + +// StringValue + +// string value = 1; +inline void StringValue::clear_value() { + value_.ClearToEmpty(); +} +inline const TProtoStringType& StringValue::value() const { + // @@protoc_insertion_point(field_get:google.protobuf.StringValue.value) + return _internal_value(); +} +template <typename ArgT0, typename... ArgT> +inline PROTOBUF_ALWAYS_INLINE +void StringValue::set_value(ArgT0&& arg0, ArgT... args) { + + value_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, static_cast<ArgT0 &&>(arg0), args..., GetArenaForAllocation()); + // @@protoc_insertion_point(field_set:google.protobuf.StringValue.value) +} +inline TProtoStringType* StringValue::mutable_value() { + TProtoStringType* _s = _internal_mutable_value(); + // @@protoc_insertion_point(field_mutable:google.protobuf.StringValue.value) + return _s; +} +inline const TProtoStringType& StringValue::_internal_value() const { + return value_.Get(); +} +inline void StringValue::_internal_set_value(const TProtoStringType& value) { + + value_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, value, GetArenaForAllocation()); +} +inline TProtoStringType* StringValue::_internal_mutable_value() { + + return value_.Mutable(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, GetArenaForAllocation()); +} +inline TProtoStringType* StringValue::release_value() { + // @@protoc_insertion_point(field_release:google.protobuf.StringValue.value) + return value_.Release(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArenaForAllocation()); +} +inline void StringValue::set_allocated_value(TProtoStringType* value) { + if (value != nullptr) { + + } else { + + } + value_.SetAllocated(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), value, + GetArenaForAllocation()); +#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING + if (value_.IsDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited())) { + value_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation()); + } +#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING + // @@protoc_insertion_point(field_set_allocated:google.protobuf.StringValue.value) +} + +// ------------------------------------------------------------------- + +// BytesValue + +// bytes value = 1; +inline void BytesValue::clear_value() { + value_.ClearToEmpty(); +} +inline const TProtoStringType& BytesValue::value() const { + // @@protoc_insertion_point(field_get:google.protobuf.BytesValue.value) + return _internal_value(); +} +template <typename ArgT0, typename... ArgT> +inline PROTOBUF_ALWAYS_INLINE +void BytesValue::set_value(ArgT0&& arg0, ArgT... args) { + + value_.SetBytes(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, static_cast<ArgT0 &&>(arg0), args..., GetArenaForAllocation()); + // @@protoc_insertion_point(field_set:google.protobuf.BytesValue.value) +} +inline TProtoStringType* BytesValue::mutable_value() { + TProtoStringType* _s = _internal_mutable_value(); + // @@protoc_insertion_point(field_mutable:google.protobuf.BytesValue.value) + return _s; +} +inline const TProtoStringType& BytesValue::_internal_value() const { + return value_.Get(); +} +inline void BytesValue::_internal_set_value(const TProtoStringType& value) { + + value_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, value, GetArenaForAllocation()); +} +inline TProtoStringType* BytesValue::_internal_mutable_value() { + + return value_.Mutable(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, GetArenaForAllocation()); +} +inline TProtoStringType* BytesValue::release_value() { + // @@protoc_insertion_point(field_release:google.protobuf.BytesValue.value) + return value_.Release(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArenaForAllocation()); +} +inline void BytesValue::set_allocated_value(TProtoStringType* value) { + if (value != nullptr) { + + } else { + + } + value_.SetAllocated(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), value, + GetArenaForAllocation()); +#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING + if (value_.IsDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited())) { + value_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation()); + } +#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING + // @@protoc_insertion_point(field_set_allocated:google.protobuf.BytesValue.value) +} + +#ifdef __GNUC__ + #pragma GCC diagnostic pop +#endif // __GNUC__ +// ------------------------------------------------------------------- + +// ------------------------------------------------------------------- + +// ------------------------------------------------------------------- + +// ------------------------------------------------------------------- + +// ------------------------------------------------------------------- + +// ------------------------------------------------------------------- + +// ------------------------------------------------------------------- + +// ------------------------------------------------------------------- + + +// @@protoc_insertion_point(namespace_scope) + +PROTOBUF_NAMESPACE_CLOSE + +// @@protoc_insertion_point(global_scope) + +#include <google/protobuf/port_undef.inc> +#endif // GOOGLE_PROTOBUF_INCLUDED_GOOGLE_PROTOBUF_INCLUDED_google_2fprotobuf_2fwrappers_2eproto diff --git a/contrib/libs/protobuf_old/src/google/protobuf/wrappers.proto b/contrib/libs/protobuf_old/src/google/protobuf/wrappers.proto new file mode 100644 index 0000000000..d49dd53c8d --- /dev/null +++ b/contrib/libs/protobuf_old/src/google/protobuf/wrappers.proto @@ -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. + +// Wrappers for primitive (non-message) types. These types are useful +// for embedding primitives in the `google.protobuf.Any` type and for places +// where we need to distinguish between the absence of a primitive +// typed field and its default value. +// +// These wrappers have no meaningful use within repeated fields as they lack +// the ability to detect presence on individual elements. +// These wrappers have no meaningful use within a map or a oneof since +// individual entries of a map or fields of a oneof can already detect presence. + +syntax = "proto3"; + +package google.protobuf; + +option csharp_namespace = "Google.Protobuf.WellKnownTypes"; +option cc_enable_arenas = true; +option go_package = "google.golang.org/protobuf/types/known/wrapperspb"; +option java_package = "com.google.protobuf"; +option java_outer_classname = "WrappersProto"; +option java_multiple_files = true; +option objc_class_prefix = "GPB"; + +// Wrapper message for `double`. +// +// The JSON representation for `DoubleValue` is JSON number. +message DoubleValue { + // The double value. + double value = 1; +} + +// Wrapper message for `float`. +// +// The JSON representation for `FloatValue` is JSON number. +message FloatValue { + // The float value. + float value = 1; +} + +// Wrapper message for `int64`. +// +// The JSON representation for `Int64Value` is JSON string. +message Int64Value { + // The int64 value. + int64 value = 1; +} + +// Wrapper message for `uint64`. +// +// The JSON representation for `UInt64Value` is JSON string. +message UInt64Value { + // The uint64 value. + uint64 value = 1; +} + +// Wrapper message for `int32`. +// +// The JSON representation for `Int32Value` is JSON number. +message Int32Value { + // The int32 value. + int32 value = 1; +} + +// Wrapper message for `uint32`. +// +// The JSON representation for `UInt32Value` is JSON number. +message UInt32Value { + // The uint32 value. + uint32 value = 1; +} + +// Wrapper message for `bool`. +// +// The JSON representation for `BoolValue` is JSON `true` and `false`. +message BoolValue { + // The bool value. + bool value = 1; +} + +// Wrapper message for `string`. +// +// The JSON representation for `StringValue` is JSON string. +message StringValue { + // The string value. + string value = 1; +} + +// Wrapper message for `bytes`. +// +// The JSON representation for `BytesValue` is JSON string. +message BytesValue { + // The bytes value. + bytes value = 1; +} diff --git a/contrib/libs/protobuf_old/ya.make b/contrib/libs/protobuf_old/ya.make new file mode 100644 index 0000000000..50a3d8cd79 --- /dev/null +++ b/contrib/libs/protobuf_old/ya.make @@ -0,0 +1,143 @@ +# Generated by devtools/yamaker from nixpkgs 22.05. + +LIBRARY() + +LICENSE( + BSD-3-Clause AND + Protobuf-License +) + +LICENSE_TEXTS(.yandex_meta/licenses.list.txt) + +#PROVIDES(protobuf) + +VERSION(3.19.0) + +ORIGINAL_SOURCE(https://github.com/protocolbuffers/protobuf/archive/v3.19.0.tar.gz) + +PEERDIR( + contrib/libs/zlib + library/cpp/sanitizer/include +) + +ADDINCL( + contrib/libs/protobuf_old/src +) + +NO_COMPILER_WARNINGS() + +CFLAGS( + -DHAVE_CONFIG_H + -DHAVE_PTHREAD=1 + -DHAVE_ZLIB=1 +) + +NO_LTO() + +IF (OS_ANDROID) + EXTRALIBS(log) +ENDIF() + +SRCS( + src/google/protobuf/generated_message_util.cc + src/google/protobuf/any.cc + src/google/protobuf/any.pb.cc + src/google/protobuf/any_lite.cc + src/google/protobuf/api.pb.cc + src/google/protobuf/arena.cc + src/google/protobuf/arenastring.cc + src/google/protobuf/descriptor.cc + src/google/protobuf/descriptor.pb.cc + src/google/protobuf/descriptor_database.cc + src/google/protobuf/duration.pb.cc + src/google/protobuf/dynamic_message.cc + src/google/protobuf/empty.pb.cc + src/google/protobuf/extension_set.cc + src/google/protobuf/extension_set_heavy.cc + src/google/protobuf/field_mask.pb.cc + src/google/protobuf/generated_enum_util.cc + src/google/protobuf/generated_message_bases.cc + src/google/protobuf/generated_message_reflection.cc + src/google/protobuf/generated_message_table_driven.cc + src/google/protobuf/generated_message_table_driven_lite.cc + src/google/protobuf/generated_message_tctable_full.cc + src/google/protobuf/generated_message_tctable_lite.cc + src/google/protobuf/implicit_weak_message.cc + src/google/protobuf/inlined_string_field.cc + src/google/protobuf/io/coded_stream.cc + src/google/protobuf/io/gzip_stream.cc + src/google/protobuf/io/io_win32.cc + src/google/protobuf/io/printer.cc + src/google/protobuf/io/strtod.cc + src/google/protobuf/io/tokenizer.cc + src/google/protobuf/io/zero_copy_stream.cc + src/google/protobuf/io/zero_copy_stream_impl.cc + src/google/protobuf/io/zero_copy_stream_impl_lite.cc + src/google/protobuf/json_util.cc + src/google/protobuf/map.cc + src/google/protobuf/map_field.cc + src/google/protobuf/message.cc + src/google/protobuf/message_lite.cc + src/google/protobuf/messagext.cc + src/google/protobuf/parse_context.cc + src/google/protobuf/reflection_ops.cc + src/google/protobuf/repeated_field.cc + src/google/protobuf/repeated_ptr_field.cc + src/google/protobuf/service.cc + src/google/protobuf/source_context.pb.cc + src/google/protobuf/struct.pb.cc + src/google/protobuf/stubs/bytestream.cc + src/google/protobuf/stubs/common.cc + src/google/protobuf/stubs/int128.cc + src/google/protobuf/stubs/status.cc + src/google/protobuf/stubs/statusor.cc + src/google/protobuf/stubs/stringpiece.cc + src/google/protobuf/stubs/stringprintf.cc + src/google/protobuf/stubs/structurally_valid.cc + src/google/protobuf/stubs/strutil.cc + src/google/protobuf/stubs/substitute.cc + src/google/protobuf/stubs/time.cc + src/google/protobuf/text_format.cc + src/google/protobuf/timestamp.pb.cc + src/google/protobuf/type.pb.cc + src/google/protobuf/unknown_field_set.cc + src/google/protobuf/util/delimited_message_util.cc + src/google/protobuf/util/field_comparator.cc + src/google/protobuf/util/field_mask_util.cc + src/google/protobuf/util/internal/datapiece.cc + src/google/protobuf/util/internal/default_value_objectwriter.cc + src/google/protobuf/util/internal/error_listener.cc + src/google/protobuf/util/internal/field_mask_utility.cc + src/google/protobuf/util/internal/json_escaping.cc + src/google/protobuf/util/internal/json_objectwriter.cc + src/google/protobuf/util/internal/json_stream_parser.cc + src/google/protobuf/util/internal/object_writer.cc + src/google/protobuf/util/internal/proto_writer.cc + src/google/protobuf/util/internal/protostream_objectsource.cc + src/google/protobuf/util/internal/protostream_objectwriter.cc + src/google/protobuf/util/internal/type_info.cc + src/google/protobuf/util/internal/utility.cc + src/google/protobuf/util/json_util.cc + src/google/protobuf/util/message_differencer.cc + src/google/protobuf/util/time_util.cc + src/google/protobuf/util/type_resolver_util.cc + src/google/protobuf/wire_format.cc + src/google/protobuf/wire_format_lite.cc + src/google/protobuf/wrappers.pb.cc +) + +FILES( + src/google/protobuf/any.proto + src/google/protobuf/api.proto + src/google/protobuf/descriptor.proto + src/google/protobuf/duration.proto + src/google/protobuf/empty.proto + src/google/protobuf/field_mask.proto + src/google/protobuf/source_context.proto + src/google/protobuf/struct.proto + src/google/protobuf/timestamp.proto + src/google/protobuf/type.proto + src/google/protobuf/wrappers.proto +) + +END() diff --git a/contrib/python/protobuf/py2/google/protobuf/pyext/descriptor_pool.cc b/contrib/python/protobuf/py2/google/protobuf/pyext/descriptor_pool.cc index a53411e797..3c08de1dc0 100644 --- a/contrib/python/protobuf/py2/google/protobuf/pyext/descriptor_pool.cc +++ b/contrib/python/protobuf/py2/google/protobuf/pyext/descriptor_pool.cc @@ -592,31 +592,40 @@ static PyObject* AddSerializedFile(PyObject* pself, PyObject* serialized_pb) { PyErr_SetString(PyExc_TypeError, "Couldn't parse file content!"); return NULL; } - + // DescriptorPool::InternalAddGeneratedFile(message_type, message_len); // If the file was already part of a C++ library, all its descriptors are in // the underlying pool. No need to do anything else. const FileDescriptor* generated_file = NULL; if (self->underlay) { generated_file = self->underlay->FindFileByName(file_proto.name()); } + if (generated_file != NULL) { - return PyFileDescriptor_FromDescriptorWithSerializedPb( - generated_file, serialized_pb); + return PyFileDescriptor_FromDescriptorWithSerializedPb(generated_file, serialized_pb); } BuildFileErrorCollector error_collector; - const FileDescriptor* descriptor = - self->pool->BuildFileCollectingErrors(file_proto, - &error_collector); - if (descriptor == NULL) { - PyErr_Format(PyExc_TypeError, - "Couldn't build proto file into descriptor pool!\n%s", - error_collector.error_message.c_str()); - return NULL; + + generated_file = self->pool->BuildFileCollectingErrors(file_proto, &error_collector); + + if (generated_file != NULL) { + return PyFileDescriptor_FromDescriptorWithSerializedPb(generated_file, serialized_pb); + } + + DescriptorPool::InternalAddGeneratedFile(message_type, message_len); + + if (self->underlay) { + generated_file = self->underlay->FindFileByName(file_proto.name()); + } + + if (generated_file != NULL) { + return PyFileDescriptor_FromDescriptorWithSerializedPb(generated_file, serialized_pb); } - return PyFileDescriptor_FromDescriptorWithSerializedPb( - descriptor, serialized_pb); + PyErr_Format(PyExc_TypeError, + "Couldn't build proto file into descriptor pool!\n%s", + error_collector.error_message.c_str()); + return NULL; } static PyObject* Add(PyObject* self, PyObject* file_descriptor_proto) { diff --git a/contrib/python/protobuf/py2/ya.make b/contrib/python/protobuf/py2/ya.make index c66515d586..b369e9bf4b 100644 --- a/contrib/python/protobuf/py2/ya.make +++ b/contrib/python/protobuf/py2/ya.make @@ -9,41 +9,22 @@ VERSION(3.17.3) ORIGINAL_SOURCE(https://github.com/protocolbuffers/protobuf/archive/v3.17.3.tar.gz) PEERDIR( - contrib/libs/protobuf - contrib/libs/protobuf/builtin_proto/protos_from_protobuf - contrib/libs/protobuf/builtin_proto/protos_from_protoc + contrib/libs/protobuf_old + contrib/libs/protobuf_old/builtin_proto/protos_from_protobuf + #contrib/libs/protobuf_old/builtin_proto/protos_from_protoc contrib/python/six ) ADDINCL( contrib/python/protobuf/py2 + contrib/libs/protobuf_old + contrib/libs/protobuf_old/src ) NO_COMPILER_WARNINGS() NO_LINT() -CFLAGS( - -DPYTHON_PROTO2_CPP_IMPL_V2 -) - -SRCS( - google/protobuf/internal/api_implementation.cc - google/protobuf/pyext/descriptor.cc - google/protobuf/pyext/descriptor_containers.cc - google/protobuf/pyext/descriptor_database.cc - google/protobuf/pyext/descriptor_pool.cc - google/protobuf/pyext/extension_dict.cc - google/protobuf/pyext/field.cc - google/protobuf/pyext/map_container.cc - google/protobuf/pyext/message.cc - google/protobuf/pyext/message_factory.cc - google/protobuf/pyext/message_module.cc - google/protobuf/pyext/repeated_composite_container.cc - google/protobuf/pyext/repeated_scalar_container.cc - google/protobuf/pyext/unknown_fields.cc -) - PY_REGISTER( google.protobuf.internal._api_implementation google.protobuf.pyext._message @@ -85,4 +66,27 @@ PY_SRCS( google/protobuf/util/__init__.py ) +NO_LTO() + +CFLAGS( + -DPYTHON_PROTO2_CPP_IMPL_V2 +) + +SRCS( + google/protobuf/internal/api_implementation.cc + google/protobuf/pyext/descriptor.cc + google/protobuf/pyext/descriptor_containers.cc + google/protobuf/pyext/descriptor_database.cc + google/protobuf/pyext/descriptor_pool.cc + google/protobuf/pyext/extension_dict.cc + google/protobuf/pyext/field.cc + google/protobuf/pyext/map_container.cc + google/protobuf/pyext/message.cc + google/protobuf/pyext/message_factory.cc + google/protobuf/pyext/message_module.cc + google/protobuf/pyext/repeated_composite_container.cc + google/protobuf/pyext/repeated_scalar_container.cc + google/protobuf/pyext/unknown_fields.cc +) + END() |